From 813e954f4e0d482222d975fa29d83715ec04ecf9 Mon Sep 17 00:00:00 2001 From: yangxiao Date: Fri, 8 Aug 2014 00:00:58 +0800 Subject: [PATCH 1/4] aabb, obb --- build/cocos2d_libs.xcodeproj/project.pbxproj | 24 + cocos/3d/CCAABB.cpp | 186 ++++++++ cocos/3d/CCAABB.h | 114 +++++ cocos/3d/CCOBB.cpp | 439 +++++++++++++++++++ cocos/3d/CCOBB.h | 117 +++++ cocos/3d/CMakeLists.txt | 2 + cocos/Android.mk | 2 + templates/cocos2dx_files.json | 4 + 8 files changed, 888 insertions(+) create mode 100755 cocos/3d/CCAABB.cpp create mode 100755 cocos/3d/CCAABB.h create mode 100755 cocos/3d/CCOBB.cpp create mode 100755 cocos/3d/CCOBB.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index f6336e4b6a..c9cb06ded3 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -584,6 +584,14 @@ 3E6176771960F89B00DE83F5 /* CCEventListenerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176641960F89B00DE83F5 /* CCEventListenerController.h */; }; 3E6176781960F89B00DE83F5 /* CCGameController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E6176651960F89B00DE83F5 /* CCGameController.h */; }; 3E61781D1966A5A300DE83F5 /* CCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E61781C1966A5A300DE83F5 /* CCController.cpp */; }; + 3E9E75E41993D8E4005B7047 /* CCAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E75E01993D8E4005B7047 /* CCAABB.cpp */; }; + 3E9E75E51993D8E4005B7047 /* CCAABB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E75E01993D8E4005B7047 /* CCAABB.cpp */; }; + 3E9E75E61993D8E4005B7047 /* CCAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E75E11993D8E4005B7047 /* CCAABB.h */; }; + 3E9E75E71993D8E4005B7047 /* CCAABB.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E75E11993D8E4005B7047 /* CCAABB.h */; }; + 3E9E75E81993D8E4005B7047 /* CCOBB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E75E21993D8E4005B7047 /* CCOBB.cpp */; }; + 3E9E75E91993D8E4005B7047 /* CCOBB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E75E21993D8E4005B7047 /* CCOBB.cpp */; }; + 3E9E75EA1993D8E4005B7047 /* CCOBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E75E31993D8E4005B7047 /* CCOBB.h */; }; + 3E9E75EB1993D8E4005B7047 /* CCOBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E75E31993D8E4005B7047 /* CCOBB.h */; }; 3E9E80E9198639EF00FA95D0 /* CCAttachNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E3198639EF00FA95D0 /* CCAttachNode.cpp */; }; 3E9E80EA198639EF00FA95D0 /* CCAttachNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E3198639EF00FA95D0 /* CCAttachNode.cpp */; }; 3E9E80EB198639EF00FA95D0 /* CCAttachNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E4198639EF00FA95D0 /* CCAttachNode.h */; }; @@ -2477,6 +2485,10 @@ 3E6176641960F89B00DE83F5 /* CCEventListenerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCEventListenerController.h; path = ../base/CCEventListenerController.h; sourceTree = ""; }; 3E6176651960F89B00DE83F5 /* CCGameController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCGameController.h; path = ../base/CCGameController.h; sourceTree = ""; }; 3E61781C1966A5A300DE83F5 /* CCController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCController.cpp; path = ../base/CCController.cpp; sourceTree = ""; }; + 3E9E75E01993D8E4005B7047 /* CCAABB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAABB.cpp; sourceTree = ""; }; + 3E9E75E11993D8E4005B7047 /* CCAABB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAABB.h; sourceTree = ""; }; + 3E9E75E21993D8E4005B7047 /* CCOBB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCOBB.cpp; sourceTree = ""; }; + 3E9E75E31993D8E4005B7047 /* CCOBB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCOBB.h; sourceTree = ""; }; 3E9E80E3198639EF00FA95D0 /* CCAttachNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAttachNode.cpp; sourceTree = ""; }; 3E9E80E4198639EF00FA95D0 /* CCAttachNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAttachNode.h; sourceTree = ""; }; 3E9E80E5198639EF00FA95D0 /* CCSubMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSubMesh.cpp; sourceTree = ""; }; @@ -5202,6 +5214,10 @@ B29594B81926D61F003EEF37 /* 3d */ = { isa = PBXGroup; children = ( + 3E9E75E01993D8E4005B7047 /* CCAABB.cpp */, + 3E9E75E11993D8E4005B7047 /* CCAABB.h */, + 3E9E75E21993D8E4005B7047 /* CCOBB.cpp */, + 3E9E75E31993D8E4005B7047 /* CCOBB.h */, 3EA3EDCA199234B500645534 /* CCDrawNode3D.cpp */, 3EA3EDCB199234B500645534 /* CCDrawNode3D.h */, 3EA2A83E1987A6810077B3D4 /* CCSkeleton3D.cpp */, @@ -5339,6 +5355,7 @@ 1A570216180BCBF40088DEC7 /* CCRenderTexture.h in Headers */, 1A01C69618F57BE800EFE3A6 /* CCInteger.h in Headers */, 3EA3EDCE199234B500645534 /* CCDrawNode3D.h in Headers */, + 3E9E75EA1993D8E4005B7047 /* CCOBB.h in Headers */, 1A570223180BCC1A0088DEC7 /* CCParticleBatchNode.h in Headers */, 50ABBD891925AB4100A911A9 /* CCCustomCommand.h in Headers */, 5034CA43191D591100CE6051 /* ccShader_Label.vert in Headers */, @@ -5387,6 +5404,7 @@ 50ABBDBB1925AB4100A911A9 /* CCTextureAtlas.h in Headers */, 1A570302180BCE890088DEC7 /* CCParallaxNode.h in Headers */, 50ABBE4B1925AB6F00A911A9 /* CCEventAcceleration.h in Headers */, + 3E9E75E61993D8E4005B7047 /* CCAABB.h in Headers */, 1A57030E180BCF190088DEC7 /* CCComponent.h in Headers */, 3E9E80EF198639EF00FA95D0 /* CCSubMesh.h in Headers */, 1A570312180BCF190088DEC7 /* CCComponentContainer.h in Headers */, @@ -5621,6 +5639,7 @@ 503DD8EF1926736A00CD74DD /* CCPlatformDefine.h in Headers */, 46A171041807CECB005B8026 /* CCPhysicsShape.h in Headers */, 50ABBD3B1925AB0000A911A9 /* CCAffineTransform.h in Headers */, + 3E9E75EB1993D8E4005B7047 /* CCOBB.h in Headers */, 5034CA38191D591100CE6051 /* ccShader_PositionColorLengthTexture.vert in Headers */, 50ABBE7C1925AB6F00A911A9 /* CCEventMouse.h in Headers */, B29594D11926D61F003EEF37 /* CCSprite3DMaterial.h in Headers */, @@ -5851,6 +5870,7 @@ B6B2634019381FBF0088FE25 /* CCAnimationCurve.h in Headers */, B6B26346193884D60088FE25 /* CCAnimation3D.h in Headers */, B6ACD89A193D6693005E0B8A /* CCMeshSkin.h in Headers */, + 3E9E75E71993D8E4005B7047 /* CCAABB.h in Headers */, B6ACD8A1193DC0CC005E0B8A /* CCAnimate3D.h in Headers */, B6AAF84419404E0D0069DE01 /* CCBundle3D.h in Headers */, ); @@ -6885,6 +6905,7 @@ 50ABBD481925AB0000A911A9 /* Mat4.cpp in Sources */, 50ABBD8F1925AB4100A911A9 /* CCGLProgramCache.cpp in Sources */, 50ABBD441925AB0000A911A9 /* CCVertex.cpp in Sources */, + 3E9E75E81993D8E4005B7047 /* CCOBB.cpp in Sources */, 503DD8F71926B0DB00CD74DD /* CCIMEDispatcher.cpp in Sources */, 50ABBE751925AB6F00A911A9 /* CCEventListenerTouch.cpp in Sources */, 50ABBE511925AB6F00A911A9 /* CCEventDispatcher.cpp in Sources */, @@ -6904,6 +6925,7 @@ 50ABBECF1925AB6F00A911A9 /* TGAlib.cpp in Sources */, 50ABBE451925AB6F00A911A9 /* CCEvent.cpp in Sources */, 50ABBE611925AB6F00A911A9 /* CCEventListenerAcceleration.cpp in Sources */, + 3E9E75E41993D8E4005B7047 /* CCAABB.cpp in Sources */, 50ABBD9F1925AB4100A911A9 /* CCGroupCommand.cpp in Sources */, 50ABBD871925AB4100A911A9 /* CCCustomCommand.cpp in Sources */, 50ABBDBD1925AB4100A911A9 /* CCTextureCache.cpp in Sources */, @@ -7099,6 +7121,7 @@ 50ABBE6E1925AB6F00A911A9 /* CCEventListenerKeyboard.cpp in Sources */, 50ABBE461925AB6F00A911A9 /* CCEvent.cpp in Sources */, 50ABBEA01925AB6F00A911A9 /* CCScheduler.cpp in Sources */, + 3E9E75E91993D8E4005B7047 /* CCOBB.cpp in Sources */, 3E9E80EA198639EF00FA95D0 /* CCAttachNode.cpp in Sources */, 3EA3EDCD199234B500645534 /* CCDrawNode3D.cpp in Sources */, 50ABBE4E1925AB6F00A911A9 /* CCEventCustom.cpp in Sources */, @@ -7107,6 +7130,7 @@ 1A570076180BC5A10088DEC7 /* CCActionGrid3D.cpp in Sources */, B37510851823ACA100B3BA6A /* CCPhysicsWorldInfo_chipmunk.cpp in Sources */, 50ABBD551925AB0000A911A9 /* TransformUtils.cpp in Sources */, + 3E9E75E51993D8E4005B7047 /* CCAABB.cpp in Sources */, 1A57007A180BC5A10088DEC7 /* CCActionInstant.cpp in Sources */, 50ABBEC01925AB6F00A911A9 /* CCValue.cpp in Sources */, 50ABBD591925AB0000A911A9 /* Vec2.cpp in Sources */, diff --git a/cocos/3d/CCAABB.cpp b/cocos/3d/CCAABB.cpp new file mode 100755 index 0000000000..0cc13f2e46 --- /dev/null +++ b/cocos/3d/CCAABB.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#include "3d/CCAABB.h" + +NS_CC_BEGIN + +AABB::AABB() +{ + reset(); +} + +AABB::AABB(const Vec3& min, const Vec3& max) +{ + set(min, max); +} + +AABB::AABB(const AABB& box) +{ + set(box._min,box._max); +} + +Vec3 AABB::getCenter() +{ + Vec3 center; + center.x = 0.5f*(_min.x+_max.x); + center.y = 0.5f*(_min.y+_max.y); + center.z = 0.5f*(_min.z+_max.z); + + return center; +} + +void AABB::getCorners(Vec3 *dst) const +{ + assert(dst); + + // Near face, specified counter-clockwise looking towards the origin from the positive z-axis. + // Left-top-front. + dst[0].set(_min.x, _max.y, _max.z); + // Left-bottom-front. + dst[1].set(_min.x, _min.y, _max.z); + // Right-bottom-front. + dst[2].set(_max.x, _min.y, _max.z); + // Right-top-front. + dst[3].set(_max.x, _max.y, _max.z); + + // Far face, specified counter-clockwise looking towards the origin from the negative z-axis. + // Right-top-back. + dst[4].set(_max.x, _max.y, _min.z); + // Right-bottom-back. + dst[5].set(_max.x, _min.y, _min.z); + // Left-bottom-back. + dst[6].set(_min.x, _min.y, _min.z); + // Left-top-back. + dst[7].set(_min.x, _max.y, _min.z); +} + +bool AABB::intersects(const AABB& aabb) const +{ + return ((_min.x >= aabb._min.x && _min.x <= aabb._max.x) || (aabb._min.x >= _min.x && aabb._min.x <= _max.x)) && + ((_min.y >= aabb._min.y && _min.y <= aabb._max.y) || (aabb._min.y >= _min.y && aabb._min.y <= _max.y)) && + ((_min.z >= aabb._min.z && _min.z <= aabb._max.z) || (aabb._min.z >= _min.z && aabb._min.z <= _max.z)); +} + +bool AABB::containPoint(const Vec3& point) const +{ + if (point.x < _min.x) return false; + if (point.y < _min.y) return false; + if (point.z < _min.z) return false; + if (point.x > _max.x) return false; + if (point.y > _max.y) return false; + if (point.z > _max.z) return false; + return true; +} + +void AABB::merge(const AABB& box) +{ + // Calculate the new minimum point. + _min.x = std::min(_min.x, box._min.x); + _min.y = std::min(_min.y, box._min.y); + _min.z = std::min(_min.z, box._min.z); + + // Calculate the new maximum point. + _max.x = std::max(_max.x, box._max.x); + _max.y = std::max(_max.y, box._max.y); + _max.z = std::max(_max.z, box._max.z); +} + +void AABB::set(const Vec3& min, const Vec3& max) +{ + this->_min = min; + this->_max = max; +} + +void AABB::reset() +{ + _min.set(99999.0f, 99999.0f, 99999.0f); + _max.set(-99999.0f, -99999.0f, -99999.0f); +} + +void AABB::updateMinMax(const Vec3* point, ssize_t num) +{ + for (ssize_t i = 0; i < num; i++) + { + // Leftmost point. + if (point[i].x < _min.x) + _min.x = point[i].x; + + // Lowest point. + if (point[i].y < _min.y) + _min.y = point[i].y; + + // Farthest point. + if (point[i].z < _min.z) + _min.z = point[i].z; + + // Rightmost point. + if (point[i].x > _max.x) + _max.x = point[i].x; + + // Highest point. + if (point[i].y > _max.y) + _max.y = point[i].y; + + // Nearest point. + if (point[i].z > _max.z) + _max.z = point[i].z; + } +} + +void AABB::transform(const Mat4& matrix) +{ + Vec3 corners[8]; + // Near face, specified counter-clockwise + // Left-top-front. + corners[0].set(_min.x, _max.y, _max.z); + // Left-bottom-front. + corners[1].set(_min.x, _min.y, _max.z); + // Right-bottom-front. + corners[2].set(_max.x, _min.y, _max.z); + // Right-top-front. + corners[3].set(_max.x, _max.y, _max.z); + + // Far face, specified clockwise + // Right-top-back. + corners[4].set(_max.x, _max.y, _min.z); + // Right-bottom-back. + corners[5].set(_max.x, _min.y, _min.z); + // Left-bottom-back. + corners[6].set(_min.x, _min.y, _min.z); + // Left-top-back. + corners[7].set(_min.x, _max.y, _min.z); + + // Transform the corners, recalculating the min and max points along the way. + //matrix.transformPoint(&corners[0]); + + for (int i = 0; i < 8; i++) + matrix.transformPoint(&corners[i]); + + reset(); + + updateMinMax(corners, 8); +} + +NS_CC_END diff --git a/cocos/3d/CCAABB.h b/cocos/3d/CCAABB.h new file mode 100755 index 0000000000..97d25a09fe --- /dev/null +++ b/cocos/3d/CCAABB.h @@ -0,0 +1,114 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#ifndef __CC_AABB_H__ +#define __CC_AABB_H__ + +#include "base/ccMacros.h" +#include "math/CCMath.h" + +NS_CC_BEGIN + +class CC_DLL AABB +{ + +public: + /** + * Constructor. + */ + AABB(); + + /** + * Constructor. + */ + AABB(const Vec3& min, const Vec3& max); + + /** + * Constructor. + */ + AABB(const AABB& box); + + /** + * Gets the center point of the bounding box. + */ + Vec3 getCenter(); + + /* Near face, specified counter-clockwise looking towards the origin from the positive z-axis. + * verts[0] : left top front + * verts[1] : left bottom front + * verts[2] : right bottom front + * verts[3] : right top front + * + * Far face, specified counter-clockwise looking towards the origin from the negative z-axis. + * verts[4] : right top back + * verts[5] : right bottom back + * verts[6] : left bottom back + * verts[7] : left top back + */ + void getCorners(Vec3 *dst) const; + + /** + * Tests whether this bounding box intersects the specified bounding object. + */ + bool intersects(const AABB& aabb) const; + + /** + * check whether the point is in. + */ + bool containPoint(const Vec3& point) const; + + /** + * Sets this bounding box to the smallest bounding box + * that contains both this bounding object and the specified bounding box. + */ + void merge(const AABB& box); + + /** + * Sets this bounding box to the specified values. + */ + void set(const Vec3& min, const Vec3& max); + + /** + * reset min and max value. + */ + void reset(); + + /** + * update the _min and _max from the given point. + */ + void updateMinMax(const Vec3* point, ssize_t num); + + /** + * Transforms the bounding box by the given transformation matrix. + */ + void transform(const Mat4& matrix); + +public: + Vec3 _min; + Vec3 _max; +}; + +NS_CC_END + +#endif diff --git a/cocos/3d/CCOBB.cpp b/cocos/3d/CCOBB.cpp new file mode 100755 index 0000000000..65a7e2b733 --- /dev/null +++ b/cocos/3d/CCOBB.cpp @@ -0,0 +1,439 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#include "3d/CCOBB.h" + +NS_CC_BEGIN + +#define ROTATE(a,i,j,k,l) g=a.m[i + 4 * j]; h=a.m[k + 4 * l]; a.m[i + 4 * j]=(float)(g-s*(h+g*tau)); a.m[k + 4 * l]=(float)(h+s*(g-h*tau)); + +static Mat4 _convarianceMatrix(const Vec3* aVertPos, int nVertCount) +{ + int i; + Mat4 Cov; + + double S1[3]; + double S2[3][3]; + + S1[0] = S1[1] = S1[2] = 0.0; + S2[0][0] = S2[1][0] = S2[2][0] = 0.0; + S2[0][1] = S2[1][1] = S2[2][1] = 0.0; + S2[0][2] = S2[1][2] = S2[2][2] = 0.0; + + // get center of mass + for(i=0; i3 && fabs(dmip)+g==fabs(dmip) && fabs(dmiq)+g==fabs(dmiq) ) + a.m[ip + 4 * iq]=0.0; + else if (fabs(a.m[ip + 4 * iq])>tresh) + { + h = dmiq-dmip; + if (fabs(h)+g == fabs(h)) + t=(a.m[ip + 4 * iq])/h; + else + { + theta=0.5*h/(a.m[ip + 4 * iq]); + t=1.0/(fabs(theta)+sqrt(1.0+theta*theta)); + if (theta < 0.0) t = -t; + } + c=1.0/sqrt(1+t*t); + s=t*c; + tau=s/(1.0+c); + h=t*a.m[ip + 4 * iq]; + _getElement(z, ip) -= (float)h; + _getElement(z, iq) += (float)h; + _getElement(d, ip) -= (float)h; + _getElement(d, iq) += (float)h; + a.m[ip + 4 * iq]=0.0; + for(j=0;j vect.x ? vecMax.x : vect.x; + vecMax.y = vecMax.y > vect.y ? vecMax.y : vect.y; + vecMax.z = vecMax.z > vect.z ? vecMax.z : vect.z; + + vecMin.x = vecMin.x < vect.x ? vecMin.x : vect.x; + vecMin.y = vecMin.y < vect.y ? vecMin.y : vect.y; + vecMin.z = vecMin.z < vect.z ? vecMin.z : vect.z; + } + + matTransform.transpose(); + + _xAxis = Vec3(matTransform.m[0], matTransform.m[1], matTransform.m[2]); + _yAxis = Vec3(matTransform.m[4], matTransform.m[5], matTransform.m[6]); + _zAxis = Vec3(matTransform.m[8], matTransform.m[9], matTransform.m[10]); + + _center = 0.5f * (vecMax + vecMin); + _center *= matTransform; + + _xAxis.normalize(); + _yAxis.normalize(); + _zAxis.normalize(); + + _extents = 0.5f * (vecMax - vecMin); +} + +bool OBB::containPoint(const Vec3& point) const +{ + Vec3 vd = point - _center; + + float d = vd.dot(_xAxis); + if (d > _extents.x || d < -_extents.x) + return false; + + d = vd.dot(_yAxis); + if (d > _extents.y || d < -_extents.y) + return false; + + d = vd.dot(_zAxis); + if (d > _extents.z || d < -_extents.z) + return false; + + return true; +} + +void OBB::set(const Vec3& center, const Vec3& xAxis, const Vec3& yAxis, const Vec3& zAxis, const Vec3& extents) +{ + _center = center; + _xAxis = xAxis; + _yAxis = yAxis; + _zAxis = zAxis; + _extents = extents; +} + +void OBB::reset() +{ + memset(this, 0, sizeof(OBB)); +} + +void OBB::getCorners(Vec3* verts) const +{ + Vec3 extX = _xAxis * _extents.x; + Vec3 extY = _yAxis * _extents.y; + Vec3 extZ = _zAxis * _extents.z; + + verts[0] = _center - extX + extY + extZ; // left top front + verts[1] = _center - extX - extY + extZ; // left bottom front + verts[2] = _center + extX - extY + extZ; // right bottom front + verts[3] = _center + extX + extY + extZ; // right top front + + verts[4] = _center + extX + extY - extZ; // right top back + verts[5] = _center + extX - extY - extZ; // right bottom back + verts[6] = _center - extX - extY - extZ; // left bottom back + verts[7] = _center - extX + extY - extZ; // left top back +} + +float OBB::projectPoint(const Vec3& point, const Vec3& axis)const +{ + float dot = axis.dot(point); + float ret = dot * point.length(); + return ret; +} + +void OBB::getInterval(const OBB& box, const Vec3& axis, float &min, float &max)const +{ + Vec3 corners[8]; + box.getCorners(corners); + float value; + min = max = projectPoint(axis, corners[0]); + for(int i = 1; i < 8; i++) + { + value = projectPoint(axis, corners[i]); + min = MIN(min, value); + max = MAX(max, value); + } +} + +Vec3 OBB::getEdgeDir(int index)const +{ + Vec3 corners[8]; + getCorners(corners); + + Vec3 tmpLine; + switch(index) + { + case 0:// edge with x axis + tmpLine = corners[5] - corners[6]; + tmpLine.normalize(); + break; + case 1:// edge with y axis + tmpLine = corners[7] - corners[6]; + tmpLine.normalize(); + break; + case 2:// edge with z axis + tmpLine = corners[1] - corners[6]; + tmpLine.normalize(); + break; + } + return tmpLine; +} + +Vec3 OBB::getFaceDir(int index) const +{ + Vec3 corners[8]; + getCorners(corners); + + Vec3 faceDir, v0, v1; + switch(index) + { + case 0:// front and back + v0 = corners[2] - corners[1]; + v1 = corners[0] - corners[1]; + Vec3::cross(v0, v1, &faceDir); + faceDir.normalize(); + break; + case 1:// left and right + v0 = corners[5] - corners[2]; + v1 = corners[3] - corners[2]; + Vec3::cross(v0, v1, &faceDir); + faceDir.normalize(); + break; + case 2:// top and bottom + v0 = corners[1] - corners[2]; + v1 = corners[5] - corners[2]; + Vec3::cross(v0, v1, &faceDir); + faceDir.normalize(); + break; + } + return faceDir; +} + +bool OBB::intersects(const OBB& box) const +{ + float min1, max1, min2, max2; + for (int i = 0; i < 3; i++) + { + getInterval(*this, getFaceDir(i), min1, max1); + getInterval(box, getFaceDir(i), min2, max2); + if (max1 < min2 || max2 < min1) return false; + } + + for (int i = 0; i < 3; i++) + { + getInterval(*this, box.getFaceDir(i), min1, max1); + getInterval(box, box.getFaceDir(i), min2, max2); + if (max1 < min2 || max2 < min1) return false; + } + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + Vec3 axis; + Vec3::cross(getEdgeDir(i), box.getEdgeDir(j), &axis); + getInterval(*this, axis, min1, max1); + getInterval(box, axis, min2, max2); + if (max1 < min2 || max2 < min1) return false; + } + } + + return true; +} + + +void OBB::transform(const Mat4& mat) +{ + Vec4 newcenter = mat * Vec4(_center.x, _center.y, _center.z, 1.0f);// center; + _center.x = newcenter.x; + _center.y = newcenter.y; + _center.z = newcenter.z; + + _xAxis = mat * _xAxis; + _yAxis = mat * _yAxis; + _zAxis = mat * _zAxis; + + _xAxis.normalize(); + _yAxis.normalize(); + _zAxis.normalize(); + + Vec3 scale, trans; + Quaternion quat; + mat.decompose(&scale, &quat, &trans); + + _extents.x *= scale.x; + _extents.y *= scale.y; + _extents.z *= scale.z; +} + +NS_CC_END diff --git a/cocos/3d/CCOBB.h b/cocos/3d/CCOBB.h new file mode 100755 index 0000000000..ed691d9f79 --- /dev/null +++ b/cocos/3d/CCOBB.h @@ -0,0 +1,117 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#ifndef __CC_OBB_H__ +#define __CC_OBB_H__ + +#include "CCAABB.h" + +NS_CC_BEGIN + +class CC_DLL OBB +{ +public: + OBB(); + + /* + * Construct obb from oriented bounding box + */ + OBB(const AABB& aabb); + + /* + * Construct obb from points + */ + OBB(const Vec3* verts, int nVerts); + + /* + * Check point in + */ + bool containPoint(const Vec3& point) const; + + /* + * Specify obb values + */ + void set(const Vec3& center, const Vec3& _xAxis, const Vec3& _yAxis, const Vec3& _zAxis, const Vec3& _extents); + + /* + * Clear obb + */ + void reset(); + + /* face to the obb's -z direction + * verts[0] : left top front + * verts[1] : left bottom front + * verts[2] : right bottom front + * verts[3] : right top front + * + * face to the obb's z direction + * verts[4] : right top back + * verts[5] : right bottom back + * verts[6] : left bottom back + * verts[7] : left top back + */ + void getCorners(Vec3* verts) const; + + /* + * Check intersect with other + */ + bool intersects(const OBB& box) const; + + /** + * Transforms the obb by the given transformation matrix. + */ + void transform(const Mat4& mat); + +protected: + /* + * Project point to the target axis + */ + float projectPoint(const Vec3& point, const Vec3& axis) const; + + /* + * Calculate the min and max project value of through the box's corners + */ + void getInterval(const OBB& box, const Vec3& axis, float &min, float &max) const; + + /* + * Get the edege of x y z axis direction + */ + Vec3 getEdgeDir(int index) const; + + /* + * Get the face of x y z axis direction + */ + Vec3 getFaceDir(int index) const; + +public: + Vec3 _center; // obb center + Vec3 _xAxis; // x axis of obb, unit vector + Vec3 _yAxis; // y axis of obb, unit vecotr + Vec3 _zAxis; // z axis of obb, unit vector + Vec3 _extents; // obb length along each axis +}; + +NS_CC_END + +#endif diff --git a/cocos/3d/CMakeLists.txt b/cocos/3d/CMakeLists.txt index 19b90ab82e..bebc7af70b 100644 --- a/cocos/3d/CMakeLists.txt +++ b/cocos/3d/CMakeLists.txt @@ -1,4 +1,6 @@ set(COCOS_3D_SRC + 3d/CCAABB.cpp + 3d/CCOBB.cpp 3d/CCDrawNode3D.cpp 3d/CCSkeleton3D.cpp 3d/CCAttachNode.cpp diff --git a/cocos/Android.mk b/cocos/Android.mk index 479b3a3988..dd3ddc8a1e 100644 --- a/cocos/Android.mk +++ b/cocos/Android.mk @@ -74,6 +74,8 @@ cocos2d.cpp \ 2d/CCTransitionPageTurn.cpp \ 2d/CCTransitionProgress.cpp \ 2d/CCTweenFunction.cpp \ +3d/CCAABB.cpp \ +3d/CCOBB.cpp \ 3d/CCAnimate3D.cpp \ 3d/CCAnimation3D.cpp \ 3d/CCAttachNode.cpp \ diff --git a/templates/cocos2dx_files.json b/templates/cocos2dx_files.json index 799c5e127a..4fd30579a1 100644 --- a/templates/cocos2dx_files.json +++ b/templates/cocos2dx_files.json @@ -192,6 +192,10 @@ "cocos/2d/cocos2dx.props", "cocos/2d/libcocos2d.vcxproj", "cocos/2d/libcocos2d.vcxproj.filters", + "cocos/3d/CCAABB.cpp", + "cocos/3d/CCAABB.h”, + "cocos/3d/CCOBB.cpp", + "cocos/3d/CCOBB.h”, "cocos/3d/CCAnimate3D.cpp", "cocos/3d/CCAnimate3D.h", "cocos/3d/CCAnimation3D.cpp", From 9471b572f7683dc655e6b92ecea4c7ba87598866 Mon Sep 17 00:00:00 2001 From: yangxiao Date: Fri, 8 Aug 2014 00:05:02 +0800 Subject: [PATCH 2/4] add to cocos2d.h --- cocos/cocos2d.h | 2 ++ tools/tolua/cocos2dx.ini | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cocos/cocos2d.h b/cocos/cocos2d.h index afdb4cfa13..9ffea8f200 100644 --- a/cocos/cocos2d.h +++ b/cocos/cocos2d.h @@ -262,6 +262,8 @@ THE SOFTWARE. #include "2d/CCComponentContainer.h" //3d +#include "3d/CCAABB.h" +#include "3d/CCOBB.h" #include "3d/CCSprite3D.h" #include "3d/CCMesh.h" #include "3d/CCMeshSkin.h" diff --git a/tools/tolua/cocos2dx.ini b/tools/tolua/cocos2dx.ini index 525d31fc6b..6626ccf4c5 100644 --- a/tools/tolua/cocos2dx.ini +++ b/tools/tolua/cocos2dx.ini @@ -26,7 +26,7 @@ headers = %(cocosdir)s/cocos/cocos2d.h %(cocosdir)s/cocos/2d/CCProtectedNode.h % # what classes to produce code for. You can use regular expressions here. When testing the regular # expression, it will be enclosed in "^$", like this: "^Menu*$". -classes = New.* Sprite.* Scene Node.* Director Layer.* Menu.* Touch .*Action.* Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn Animat.* Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* PointArray ToggleVisibility.* RemoveSelf Hide Particle.* Label.* Atlas.* TextureCache.* Texture2D Cardinal.* CatmullRom.* ParallaxNode TileMap.* .*TMX.* CallFunc RenderTexture GridAction Grid3DAction GridBase$ .+Grid Shaky3D Waves3D FlipX3D FlipY3D Speed ActionManager Set Scheduler Timer Orbit.* Follow.* Bezier.* CardinalSpline.* Camera.* DrawNode .*3D$ Liquid$ Waves$ ShuffleTiles$ TurnOffTiles$ Split.* Twirl$ FileUtils$ GLProgram ShaderCache Application ClippingNode MotionStreak ^Ref$ UserDefault GLViewImpl GLView Image Event(?!.*(Physics).*).* Component ProtectedNode Console Mesh GLProgramCache GLProgramState SubMeshState AttachNode Camera DrawNode3D +classes = New.* Sprite.* Scene Node.* Director Layer.* Menu.* Touch .*Action.* Move.* Rotate.* Blink.* Tint.* Sequence Repeat.* Fade.* Ease.* Scale.* Transition.* Spawn Animat.* Flip.* Delay.* Skew.* Jump.* Place.* Show.* Progress.* PointArray ToggleVisibility.* RemoveSelf Hide Particle.* Label.* Atlas.* TextureCache.* Texture2D Cardinal.* CatmullRom.* ParallaxNode TileMap.* .*TMX.* CallFunc RenderTexture GridAction Grid3DAction GridBase$ .+Grid Shaky3D Waves3D FlipX3D FlipY3D Speed ActionManager Set Scheduler Timer Orbit.* Follow.* Bezier.* CardinalSpline.* Camera.* DrawNode .*3D$ Liquid$ Waves$ ShuffleTiles$ TurnOffTiles$ Split.* Twirl$ FileUtils$ GLProgram ShaderCache Application ClippingNode MotionStreak ^Ref$ UserDefault GLViewImpl GLView Image Event(?!.*(Physics).*).* Component ProtectedNode Console Mesh GLProgramCache GLProgramState SubMeshState AttachNode Camera DrawNode3D AABB OBB # what should we skip? in the format ClassName::[function function] # ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also From 28769c9b1512072400d95a06b7d16465d3be89ed Mon Sep 17 00:00:00 2001 From: lvlong Date: Fri, 8 Aug 2014 11:16:33 +0800 Subject: [PATCH 3/4] add obb sample --- build/cocos2d_libs.xcodeproj/project.pbxproj | 12 + cocos/3d/CCRay.cpp | 176 ++++++++++++ cocos/3d/CCRay.h | 97 +++++++ cocos/Android.mk | 1 + .../Classes/Sprite3DTest/Sprite3DTest.cpp | 261 +++++++++++++++++- .../Classes/Sprite3DTest/Sprite3DTest.h | 35 +++ 6 files changed, 581 insertions(+), 1 deletion(-) create mode 100755 cocos/3d/CCRay.cpp create mode 100755 cocos/3d/CCRay.h diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index c9cb06ded3..2b8e040b16 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -1264,6 +1264,10 @@ 50ABC0651926664800A911A9 /* CCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF531926664700A911A9 /* CCGL.h */; }; 50ABC0671926664800A911A9 /* CCPlatformDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF541926664700A911A9 /* CCPlatformDefine.h */; }; 50ABC0691926664800A911A9 /* CCStdC.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ABBF551926664700A911A9 /* CCStdC.h */; }; + 5E7EAC03199469D200CCFA35 /* CCRay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7EAC01199469D200CCFA35 /* CCRay.cpp */; }; + 5E7EAC04199469D200CCFA35 /* CCRay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E7EAC01199469D200CCFA35 /* CCRay.cpp */; }; + 5E7EAC05199469D200CCFA35 /* CCRay.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E7EAC02199469D200CCFA35 /* CCRay.h */; }; + 5E7EAC06199469D200CCFA35 /* CCRay.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E7EAC02199469D200CCFA35 /* CCRay.h */; }; A07A4CAF1783777C0073F6A7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1551A342158F2AB200E66CFE /* Foundation.framework */; }; B217703C1977ECB4009EE11B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B217703B1977ECB4009EE11B /* IOKit.framework */; }; B21770401977ECE6009EE11B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B217703F1977ECE6009EE11B /* OpenGL.framework */; }; @@ -2998,6 +3002,8 @@ 50FCEB9018C72017004AD434 /* WidgetReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WidgetReader.cpp; sourceTree = ""; }; 50FCEB9118C72017004AD434 /* WidgetReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WidgetReader.h; sourceTree = ""; }; 50FCEB9218C72017004AD434 /* WidgetReaderProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WidgetReaderProtocol.h; sourceTree = ""; }; + 5E7EAC01199469D200CCFA35 /* CCRay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCRay.cpp; sourceTree = ""; }; + 5E7EAC02199469D200CCFA35 /* CCRay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCRay.h; sourceTree = ""; }; A03F2CB81780BD04006731B9 /* libchipmunk Mac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libchipmunk Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A03F2D9B1780BDF7006731B9 /* libbox2d Mac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libbox2d Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A03F2ED617814268006731B9 /* libcocosdenshion Mac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libcocosdenshion Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -5214,6 +5220,8 @@ B29594B81926D61F003EEF37 /* 3d */ = { isa = PBXGroup; children = ( + 5E7EAC01199469D200CCFA35 /* CCRay.cpp */, + 5E7EAC02199469D200CCFA35 /* CCRay.h */, 3E9E75E01993D8E4005B7047 /* CCAABB.cpp */, 3E9E75E11993D8E4005B7047 /* CCAABB.h */, 3E9E75E21993D8E4005B7047 /* CCOBB.cpp */, @@ -5318,6 +5326,7 @@ 1A570114180BC8EE0088DEC7 /* CCDrawNode.h in Headers */, 1A57011D180BC90D0088DEC7 /* CCGrabber.h in Headers */, 1A570121180BC90D0088DEC7 /* CCGrid.h in Headers */, + 5E7EAC05199469D200CCFA35 /* CCRay.h in Headers */, 5034CA2D191D591100CE6051 /* ccShader_PositionTextureA8Color.frag in Headers */, 1AC0269C1914068200FA920D /* ConvertUTF.h in Headers */, 50ABBED11925AB6F00A911A9 /* TGAlib.h in Headers */, @@ -5637,6 +5646,7 @@ 46A170FF1807CECB005B8026 /* CCPhysicsContact.h in Headers */, 50ABBDA21925AB4100A911A9 /* CCGroupCommand.h in Headers */, 503DD8EF1926736A00CD74DD /* CCPlatformDefine.h in Headers */, + 5E7EAC06199469D200CCFA35 /* CCRay.h in Headers */, 46A171041807CECB005B8026 /* CCPhysicsShape.h in Headers */, 50ABBD3B1925AB0000A911A9 /* CCAffineTransform.h in Headers */, 3E9E75EB1993D8E4005B7047 /* CCOBB.h in Headers */, @@ -6855,6 +6865,7 @@ 1A570225180BCC1A0088DEC7 /* CCParticleExamples.cpp in Sources */, 1A570229180BCC1A0088DEC7 /* CCParticleSystem.cpp in Sources */, 1A57022D180BCC1A0088DEC7 /* CCParticleSystemQuad.cpp in Sources */, + 5E7EAC03199469D200CCFA35 /* CCRay.cpp in Sources */, 1A57027E180BCC900088DEC7 /* CCSprite.cpp in Sources */, 3EA3EDCC199234B500645534 /* CCDrawNode3D.cpp in Sources */, 1A570282180BCC900088DEC7 /* CCSpriteBatchNode.cpp in Sources */, @@ -7143,6 +7154,7 @@ 50ABBED81925AB6F00A911A9 /* ZipUtils.cpp in Sources */, 1A57008E180BC5A10088DEC7 /* CCActionTiledGrid.cpp in Sources */, 1A570092180BC5A10088DEC7 /* CCActionTween.cpp in Sources */, + 5E7EAC04199469D200CCFA35 /* CCRay.cpp in Sources */, 1A570099180BC5C10088DEC7 /* CCAtlasNode.cpp in Sources */, 50ABBD4D1925AB0000A911A9 /* MathUtil.cpp in Sources */, 50ABBE3E1925AB6F00A911A9 /* CCDataVisitor.cpp in Sources */, diff --git a/cocos/3d/CCRay.cpp b/cocos/3d/CCRay.cpp new file mode 100755 index 0000000000..8d8275af18 --- /dev/null +++ b/cocos/3d/CCRay.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +Copyright (c) Chukong Technologies Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +****************************************************************************/ + +#include "CCRay.h" +#include "CCAABB.h" +#include "CCOBB.h" + +NS_CC_BEGIN + +Ray::Ray() + : _direction(0, 0, 1) +{ +} + +Ray::Ray(const Vec3& origin, const Vec3& direction) +{ + set(origin, direction); +} + +Ray::~Ray() +{ +} + +bool Ray::intersects(const AABB& aabb) const +{ + Vec3 ptOnPlane; + Vec3 min = aabb._min; + Vec3 max = aabb._max; + + const Vec3& origin = _origin; + const Vec3& dir = _direction; + + float t; + + if (dir.x != 0.f) + { + if (dir.x > 0) + t = (min.x - origin.x) / dir.x; + else + t = (max.x - origin.x) / dir.x; + + if (t > 0.f) + { + ptOnPlane = origin + t * dir; + + if (min.y < ptOnPlane.y && ptOnPlane.y < max.y && min.z < ptOnPlane.z && ptOnPlane.z < max.z) + { + return true; + } + } + } + + if (dir.y != 0.f) + { + if (dir.y > 0) + t = (min.y - origin.y) / dir.y; + else + t = (max.y - origin.y) / dir.y; + + if (t > 0.f) + { + ptOnPlane = origin + t * dir; + + if (min.z < ptOnPlane.z && ptOnPlane.z < max.z && min.x < ptOnPlane.x && ptOnPlane.x < max.x) + { + return true; + } + } + } + + if (dir.z != 0.f) + { + if (dir.z > 0) + t = (min.z - origin.z) / dir.z; + else + t = (max.z - origin.z) / dir.z; + + if (t > 0.f) + { + ptOnPlane = origin + t * dir; + + if (min.x < ptOnPlane.x && ptOnPlane.x < max.x && min.y < ptOnPlane.y && ptOnPlane.y < max.y) + { + return true; + } + } + } + + return false; +} + +bool Ray::intersects(const OBB& obb) const +{ + AABB aabb; + aabb._min = - obb._extents; + aabb._max = obb._extents; + + Ray ray; + ray._direction = _direction; + ray._origin = _origin; + + Mat4 mat = Mat4::IDENTITY; + mat.m[0] = obb._xAxis.x; + mat.m[1] = obb._xAxis.y; + mat.m[2] = obb._xAxis.z; + + mat.m[4] = obb._yAxis.x; + mat.m[5] = obb._yAxis.y; + mat.m[6] = obb._yAxis.z; + + mat.m[8] = obb._zAxis.x; + mat.m[9] = obb._zAxis.y; + mat.m[10] = obb._zAxis.z; + + mat.m[12] = obb._center.x; + mat.m[13] = obb._center.y; + mat.m[14] = obb._center.z; + + mat = mat.getInversed(); + + ray.transform(mat); + + return ray.intersects(aabb); +} + +void Ray::set(const Vec3& origin, const Vec3& direction) +{ + _origin = origin; + _direction = direction; + normalize(); +} + +void Ray::transform(const Mat4& matrix) +{ + matrix.transformPoint(&_origin); + matrix.transformVector(&_direction); + _direction.normalize(); +} + +void Ray::normalize() +{ + if (_direction.isZero()) + { + return; + } + + // Normalize the ray's direction vector. + float normalizeFactor = 1.0f / sqrt(_direction.x * _direction.x + _direction.y * _direction.y + _direction.z * _direction.z); + if (normalizeFactor != 1.0f) + { + _direction.x *= normalizeFactor; + _direction.y *= normalizeFactor; + _direction.z *= normalizeFactor; + } +} + +NS_CC_END diff --git a/cocos/3d/CCRay.h b/cocos/3d/CCRay.h new file mode 100755 index 0000000000..7c60c35635 --- /dev/null +++ b/cocos/3d/CCRay.h @@ -0,0 +1,97 @@ +/**************************************************************************** + Copyright (c) 2014 Chukong Technologies Inc. + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +#ifndef __CC_RAY_H_ +#define __CC_RAY_H_ + +#include "base/ccMacros.h" +#include "math/CCMath.h" +#include "CCAABB.h" +#include "CCOBB.h" + +NS_CC_BEGIN + +class CC_DLL Ray +{ +public: + /** + * Constructor. + */ + Ray(); + + /** + * Constructor. + */ + Ray(const Ray& ray); + + /** + * Constructs a new ray initialized to the specified values. + * + * @param origin The ray's origin. + * @param direction The ray's direction. + */ + Ray(const Vec3& origin, const Vec3& direction); + + /** + * Destructor. + */ + ~Ray(); + + /** + * Check whether this ray intersects the specified bounding box. + */ + bool intersects(const AABB& aabb) const; + + /** + * Check whether this ray intersects the specified obb. + */ + bool intersects(const OBB& obb) const; + + /** + * Sets this ray to the specified values. + * + * @param origin The ray's origin. + * @param direction The ray's direction. + */ + void set(const Vec3& origin, const Vec3& direction); + + /** + * Transforms this ray by the given transformation matrix. + * + * @param matrix The transformation matrix to transform by. + */ + void transform(const Mat4& matrix); + + /** + * Normalizes the ray. + */ + void normalize(); + + Vec3 _origin; // The ray origin position. + Vec3 _direction; // The ray direction vector. +}; + +NS_CC_END + +#endif diff --git a/cocos/Android.mk b/cocos/Android.mk index dd3ddc8a1e..ece0054f1d 100644 --- a/cocos/Android.mk +++ b/cocos/Android.mk @@ -74,6 +74,7 @@ cocos2d.cpp \ 2d/CCTransitionPageTurn.cpp \ 2d/CCTransitionProgress.cpp \ 2d/CCTweenFunction.cpp \ +3d/CCRay.cpp\ 3d/CCAABB.cpp \ 3d/CCOBB.cpp \ 3d/CCAnimate3D.cpp \ diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp index 2c9c540c72..2ce7ce40e0 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.cpp @@ -28,6 +28,7 @@ #include "3d/CCAnimate3D.h" #include "3d/CCSubMesh.h" #include "3d/CCAttachNode.h" +#include "3d/CCRay.h" #include #include "../testResource.h" @@ -52,7 +53,8 @@ static std::function createFunctions[] = #endif CL(Sprite3DWithSkinTest), CL(Animate3DTest), - CL(AttachmentTest) + CL(AttachmentTest), + CL(Sprite3DWithOBBPerfromanceTest) }; #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) @@ -867,3 +869,260 @@ void AttachmentTest::onTouchesEnded(const std::vector& touches, Event* e } _hasWeapon = !_hasWeapon; } + +Sprite3DWithOBBPerfromanceTest::Sprite3DWithOBBPerfromanceTest() +{ + auto listener = EventListenerTouchAllAtOnce::create(); + listener->onTouchesBegan = CC_CALLBACK_2(Sprite3DWithOBBPerfromanceTest::onTouchesBegan, this); + listener->onTouchesEnded = CC_CALLBACK_2(Sprite3DWithOBBPerfromanceTest::onTouchesEnded, this); + listener->onTouchesMoved = CC_CALLBACK_2(Sprite3DWithOBBPerfromanceTest::onTouchesMoved, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); + auto s = Director::getInstance()->getWinSize(); + initDrawBox(); + + addNewSpriteWithCoords(Vec2(s.width/2, s.height/2)); + MenuItemFont::setFontName("fonts/arial.ttf"); + MenuItemFont::setFontSize(65); + auto decrease = MenuItemFont::create(" - ", CC_CALLBACK_1(Sprite3DWithOBBPerfromanceTest::delOBBCallback, this)); + decrease->setColor(Color3B(0,200,20)); + auto increase = MenuItemFont::create(" + ", CC_CALLBACK_1(Sprite3DWithOBBPerfromanceTest::addOBBCallback, this)); + increase->setColor(Color3B(0,200,20)); + + auto menu = Menu::create(decrease, increase, nullptr); + menu->alignItemsHorizontally(); + menu->setPosition(Vec2(s.width/2, s.height-65)); + addChild(menu, 1); + + TTFConfig ttfCount("fonts/Marker Felt.ttf", 30); + _labelCubeCount = Label::createWithTTF(ttfCount,"0 cubes"); + _labelCubeCount->setColor(Color3B(0,200,20)); + _labelCubeCount->setPosition(Vec2(s.width/2, s.height-90)); + addChild(_labelCubeCount); + _hasCollider = false; + scheduleUpdate(); +} +std::string Sprite3DWithOBBPerfromanceTest::title() const +{ + return "OBB Collison Perfromance Test"; +} +std::string Sprite3DWithOBBPerfromanceTest::subtitle() const +{ + return ""; +} +void Sprite3DWithOBBPerfromanceTest::addNewOBBWithCoords(Vec2 p) +{ + Vec3 extents = Vec3(10, 10, 10); + AABB aabb(-extents, extents); + auto obb = OBB(aabb); + obb._center = Vec3(p.x,p.y,0); + _obb.push_back(obb); +} + +void Sprite3DWithOBBPerfromanceTest::onTouchesBegan(const std::vector& touches, Event* event) +{ + for (auto touch: touches) + { + auto location = touch->getLocationInView(); + + if(_obb.size() > 0) + { + _intersetList.clear(); + Ray ray; + calculateRayByLocationInView(&ray,location); + for(int i = 0; i < _obb.size(); i++) + { + if(ray.intersects(_obb[i])) + { + _intersetList.insert(i); + return; + } + } + } + } +} + +void Sprite3DWithOBBPerfromanceTest::onTouchesEnded(const std::vector& touches, Event* event) +{ + +} + +void Sprite3DWithOBBPerfromanceTest::onTouchesMoved(const std::vector& touches, Event* event) +{ + for (auto touch: touches) + { + auto location = touch->getLocation(); + + for(int i = 0; i < _obb.size(); i++) + { + if(_intersetList.find(i) != _intersetList.end()) + _obb[i]._center = Vec3(location.x,location.y,0); + } + } +} + +void Sprite3DWithOBBPerfromanceTest::update(float dt) +{ + char szText[16]; + sprintf(szText,"%lu cubes",_obb.size()); + _labelCubeCount->setString(szText); + + if (_drawDebug) + { + _drawDebug->clear(); + + Mat4 mat = _sprite->getNodeToWorldTransform(); + mat.getRightVector(&_obbt._xAxis); + _obbt._xAxis.normalize(); + + mat.getUpVector(&_obbt._yAxis); + _obbt._yAxis.normalize(); + + mat.getForwardVector(&_obbt._zAxis); + _obbt._zAxis.normalize(); + + _obbt._center = _sprite->getPosition3D(); + + Vec3 corners[8] = {}; + _obbt.getCorners(corners); + _drawDebug->drawCube(corners, Color4F(0,0,1,1)); + } + if(_obb.size() > 0) + { + _drawOBB->clear(); + for(int i =0; i < _obb.size(); i++) + { + Vec3 corners[8] = {}; + _obb[i].getCorners(corners); + _drawOBB->drawCube(corners, _obbt.intersects(_obb[i])?Color4F(1,0,0,1):Color4F(0,1,0,1)); + } + } +} + +void Sprite3DWithOBBPerfromanceTest::initDrawBox() +{ + _drawOBB = DrawNode3D::create(); + addChild(_drawOBB); +} + +void Sprite3DWithOBBPerfromanceTest::addNewSpriteWithCoords(Vec2 p) +{ + std::string fileName = "Sprite3DTest/tortoise.c3b"; + auto sprite = Sprite3D::create(fileName); + sprite->setScale(0.1f); + auto s = Director::getInstance()->getWinSize(); + sprite->setPosition(Vec2(s.width * 4.f / 5.f, s.height / 2.f)); + addChild(sprite); + _sprite = sprite; + auto animation = Animation3D::create(fileName); + if (animation) + { + auto animate = Animate3D::create(animation, 0.f, 1.933f); + sprite->runAction(RepeatForever::create(animate)); + } + + _moveAction = MoveTo::create(4.f, Vec2(s.width / 5.f, s.height / 2.f)); + _moveAction->retain(); + auto seq = Sequence::create(_moveAction, CallFunc::create(CC_CALLBACK_0(Sprite3DWithOBBPerfromanceTest::reachEndCallBack, this)), nullptr); + seq->setTag(100); + sprite->runAction(seq); + + //Generate OBB by AABB + Vec3 extents = Vec3(50, 25, 25); + AABB aabb(-extents, extents); + _obbt = OBB(aabb); + + _drawDebug = DrawNode3D::create(); + addChild(_drawDebug); +} + +void Sprite3DWithOBBPerfromanceTest::reachEndCallBack() +{ + _sprite->stopActionByTag(100); + auto inverse = (MoveTo*)_moveAction->reverse(); + inverse->retain(); + _moveAction->release(); + _moveAction = inverse; + auto rot = RotateBy::create(1.0f, Vec3(0.f, 180.f, 0.f)); + auto seq = Sequence::create(rot, _moveAction, CallFunc::create(CC_CALLBACK_0(Sprite3DWithOBBPerfromanceTest::reachEndCallBack, this)), nullptr); + seq->setTag(100); + _sprite->runAction(seq); +} + +void Sprite3DWithOBBPerfromanceTest::addOBBCallback(Ref* sender) +{ + addOBBWithCount(10); +} + +void Sprite3DWithOBBPerfromanceTest::addOBBWithCount(float value) +{ + for(int i = 0; i < value; i++) + { + Vec2 randompos = Vec2(CCRANDOM_0_1() * Director::getInstance()->getWinSize().width,CCRANDOM_0_1() * Director::getInstance()->getWinSize().height); + Vec3 extents = Vec3(10, 10, 10); + AABB aabb(-extents, extents); + auto obb = OBB(aabb); + obb._center = Vec3(randompos.x,randompos.y,0); + _obb.push_back(obb); + } +} + +void Sprite3DWithOBBPerfromanceTest::delOBBCallback(Ref* sender) +{ + delOBBWithCount(10); +} + +void Sprite3DWithOBBPerfromanceTest::delOBBWithCount(float value) +{ + if(_obb.size() >= 10) + { + _obb.erase(_obb.begin(),_obb.begin() + value); + _drawOBB->clear(); + } + else + return; +} +void Sprite3DWithOBBPerfromanceTest::unproject(const Mat4& viewProjection, const Size* viewport, Vec3* src, Vec3* dst) +{ + assert(dst); + + assert(viewport->width != 0.0f && viewport->height != 0.0f); + Vec4 screen(src->x / viewport->width, ((viewport->height - src->y)) / viewport->height, src->z, 1.0f); + + screen.x = screen.x * 2.0f - 1.0f; + screen.y = screen.y * 2.0f - 1.0f; + screen.z = screen.z * 2.0f - 1.0f; + + viewProjection.getInversed().transformVector(screen, &screen); + + if (screen.w != 0.0f) + { + screen.x /= screen.w; + screen.y /= screen.w; + screen.z /= screen.w; + } + + dst->set(screen.x, screen.y, screen.z); +} + +void Sprite3DWithOBBPerfromanceTest::calculateRayByLocationInView(Ray* ray, const Vec2& location) +{ + auto dir = Director::getInstance(); + auto view = dir->getWinSize(); + Mat4 mat = dir->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); + mat = dir->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION); + + Vec3 src = Vec3(location.x, location.y, -1); + Vec3 nearPoint; + unproject(mat, &view, &src, &nearPoint); + + src = Vec3(location.x, location.y, 1); + Vec3 farPoint; + unproject(mat, &view, &src, &farPoint); + + Vec3 direction; + Vec3::subtract(farPoint, nearPoint, &direction); + direction.normalize(); + + ray->_origin = nearPoint; + ray->_direction = direction; +} diff --git a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h index a9f774d368..6b97aac4d6 100644 --- a/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h +++ b/tests/cpp-tests/Classes/Sprite3DTest/Sprite3DTest.h @@ -33,6 +33,7 @@ namespace cocos2d { class Animate3D; class Sprite3D; class Delay; + class Ray; } class Sprite3DTestDemo : public BaseTest @@ -224,6 +225,40 @@ protected: cocos2d::Sprite3D* _sprite; }; +class Sprite3DWithOBBPerfromanceTest : public Sprite3DTestDemo +{ +public: + CREATE_FUNC(Sprite3DWithOBBPerfromanceTest); + Sprite3DWithOBBPerfromanceTest(); + virtual std::string title() const override; + virtual std::string subtitle() const override; + virtual void update(float dt) override; + void addNewOBBWithCoords(Vec2 p); + void addNewSpriteWithCoords(Vec2 p); + void onTouchesBegan(const std::vector& touches, Event* event); + void onTouchesEnded(const std::vector& touches, Event* event); + void onTouchesMoved(const std::vector& touches, Event* event); + void addOBBCallback(Ref* sender); + void delOBBCallback(Ref* sender); + void addOBBWithCount(float value); + void delOBBWithCount(float value); +protected: + cocos2d::Sprite3D* _sprite; + std::vector _obb; + DrawNode3D* _drawOBB; + Label* _labelCubeCount; + MoveTo* _moveAction; + OBB _obbt; + DrawNode3D* _drawDebug; + bool _hasCollider; + std::set _intersetList; + void initDrawBox(); + void reachEndCallBack(); + + void unproject(const Mat4& viewProjection, const Size* viewport, Vec3* src, Vec3* dst); + void calculateRayByLocationInView(Ray* ray, const Vec2& location); +}; + class Sprite3DTestScene : public TestScene { public: From fe58c43b2d2c8605c0692029111a7dbe57932147 Mon Sep 17 00:00:00 2001 From: lvlong Date: Fri, 8 Aug 2014 14:06:54 +0800 Subject: [PATCH 4/4] add abb and obb to vc2012-project --- cocos/2d/libcocos2d.vcxproj | 6 ++++++ cocos/2d/libcocos2d.vcxproj.filters | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/cocos/2d/libcocos2d.vcxproj b/cocos/2d/libcocos2d.vcxproj index f935648fa7..c6396c878d 100644 --- a/cocos/2d/libcocos2d.vcxproj +++ b/cocos/2d/libcocos2d.vcxproj @@ -183,6 +183,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou + @@ -191,7 +192,9 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou + + @@ -370,6 +373,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou + @@ -380,7 +384,9 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou + + diff --git a/cocos/2d/libcocos2d.vcxproj.filters b/cocos/2d/libcocos2d.vcxproj.filters index b20b7f8bc3..dbbb942f17 100644 --- a/cocos/2d/libcocos2d.vcxproj.filters +++ b/cocos/2d/libcocos2d.vcxproj.filters @@ -616,6 +616,15 @@ base + + 3d + + + 3d + + + 3d + @@ -1252,6 +1261,15 @@ base + + 3d + + + 3d + + + 3d +