Merge pull request #9558 from super626/frustum

Frustum Culling
This commit is contained in:
minggo 2014-12-29 09:43:14 +08:00
commit b01b25e17e
23 changed files with 891 additions and 122 deletions

View File

@ -1749,6 +1749,14 @@
50ED2BE519BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDE19BEAF7900A0AB90 /* UIEditBoxImpl-win32.cpp */; };
50ED2BE619BEAF7900A0AB90 /* UIEditBoxImpl-wp8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDF19BEAF7900A0AB90 /* UIEditBoxImpl-wp8.cpp */; };
50ED2BE719BEAF7900A0AB90 /* UIEditBoxImpl-wp8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50ED2BDF19BEAF7900A0AB90 /* UIEditBoxImpl-wp8.cpp */; };
5E9F61261A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */; };
5E9F61271A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */; };
5E9F61281A3FFE3D0038DE01 /* CCFrustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */; };
5E9F61291A3FFE3D0038DE01 /* CCFrustum.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */; };
5E9F612A1A3FFE3D0038DE01 /* CCPlane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61241A3FFE3D0038DE01 /* CCPlane.cpp */; };
5E9F612B1A3FFE3D0038DE01 /* CCPlane.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5E9F61241A3FFE3D0038DE01 /* CCPlane.cpp */; };
5E9F612C1A3FFE3D0038DE01 /* CCPlane.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61251A3FFE3D0038DE01 /* CCPlane.h */; };
5E9F612D1A3FFE3D0038DE01 /* CCPlane.h in Headers */ = {isa = PBXBuildFile; fileRef = 5E9F61251A3FFE3D0038DE01 /* CCPlane.h */; };
A07A4CAF1783777C0073F6A7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1551A342158F2AB200E66CFE /* Foundation.framework */; };
B2165EEA19921124000BE3E6 /* CCPrimitiveCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B257B45E198A353E00D9A687 /* CCPrimitiveCommand.cpp */; };
B217703C1977ECB4009EE11B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B217703B1977ECB4009EE11B /* IOKit.framework */; };
@ -2921,6 +2929,10 @@
50FCEB9018C72017004AD434 /* WidgetReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WidgetReader.cpp; sourceTree = "<group>"; };
50FCEB9118C72017004AD434 /* WidgetReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WidgetReader.h; sourceTree = "<group>"; };
50FCEB9218C72017004AD434 /* WidgetReaderProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WidgetReaderProtocol.h; sourceTree = "<group>"; };
5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCFrustum.cpp; sourceTree = "<group>"; };
5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCFrustum.h; sourceTree = "<group>"; };
5E9F61241A3FFE3D0038DE01 /* CCPlane.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCPlane.cpp; sourceTree = "<group>"; };
5E9F61251A3FFE3D0038DE01 /* CCPlane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPlane.h; sourceTree = "<group>"; };
A07A4D641783777C0073F6A7 /* libcocos2d iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libcocos2d iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
B217703B1977ECB4009EE11B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
B217703D1977ECC1009EE11B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
@ -5160,6 +5172,10 @@
B29594B81926D61F003EEF37 /* 3d */ = {
isa = PBXGroup;
children = (
5E9F61221A3FFE3D0038DE01 /* CCFrustum.cpp */,
5E9F61231A3FFE3D0038DE01 /* CCFrustum.h */,
5E9F61241A3FFE3D0038DE01 /* CCPlane.cpp */,
5E9F61251A3FFE3D0038DE01 /* CCPlane.h */,
B60C5BD219AC68B10056FBDE /* CCBillBoard.cpp */,
B60C5BD319AC68B10056FBDE /* CCBillBoard.h */,
15AE17E419AAD2F700C27E9E /* CCAABB.cpp */,
@ -5392,6 +5408,7 @@
5034CA47191D591100CE6051 /* ccShader_Label_normal.frag in Headers */,
15AE182219AAD2F700C27E9E /* CCBundleReader.h in Headers */,
15AE18A519AAD33D00C27E9E /* CCScale9SpriteLoader.h in Headers */,
5E9F61281A3FFE3D0038DE01 /* CCFrustum.h in Headers */,
50ED2BE019BEAF7900A0AB90 /* UIEditBoxImpl-win32.h in Headers */,
15AE197119AAD35700C27E9E /* CCFrame.h in Headers */,
15AE1A6519AAD40300C27E9E /* b2TimeStep.h in Headers */,
@ -5676,6 +5693,7 @@
50ABBFFD1926664800A911A9 /* CCFileUtils-apple.h in Headers */,
15B3708219EE414C00ABE682 /* CCEventListenerAssetsManagerEx.h in Headers */,
15B3708619EE414C00ABE682 /* Downloader.h in Headers */,
5E9F612C1A3FFE3D0038DE01 /* CCPlane.h in Headers */,
5034CA41191D591100CE6051 /* ccShader_Position_uColor.frag in Headers */,
50ABBE7F1925AB6F00A911A9 /* CCEventTouch.h in Headers */,
50ABBE5B1925AB6F00A911A9 /* CCEventKeyboard.h in Headers */,
@ -5974,6 +5992,7 @@
15AE182F19AAD2F700C27E9E /* CCMeshVertexIndexData.h in Headers */,
15AE1BAA19AADFDF00C27E9E /* UIVBox.h in Headers */,
3EACC9A719F5014D00EB3C5E /* CCLight.h in Headers */,
5E9F61291A3FFE3D0038DE01 /* CCFrustum.h in Headers */,
15AE194E19AAD35100C27E9E /* CCDataReaderHelper.h in Headers */,
15AE1ADB19AAD41000C27E9E /* b2Rope.h in Headers */,
D0FD03561A3B51AA00825BB5 /* CCAllocatorMacros.h in Headers */,
@ -6258,6 +6277,7 @@
15AE19AD19AAD39700C27E9E /* LoadingBarReader.h in Headers */,
50ABBE5C1925AB6F00A911A9 /* CCEventKeyboard.h in Headers */,
B375107D1823ACA100B3BA6A /* CCPhysicsBodyInfo_chipmunk.h in Headers */,
5E9F612D1A3FFE3D0038DE01 /* CCPlane.h in Headers */,
50ABC01C1926664800A911A9 /* CCSAXParser.h in Headers */,
503DD8F11926736A00CD74DD /* OpenGL_Internal-ios.h in Headers */,
38ACD1FF1A27111900C3093D /* WidgetCallBackHandlerProtocol.h in Headers */,
@ -6396,6 +6416,7 @@
15AE189819AAD33D00C27E9E /* CCMenuItemLoader.cpp in Sources */,
15AE1A5719AAD40300C27E9E /* b2Settings.cpp in Sources */,
50ABBE271925AB6F00A911A9 /* CCAutoreleasePool.cpp in Sources */,
5E9F612A1A3FFE3D0038DE01 /* CCPlane.cpp in Sources */,
15AE197419AAD35700C27E9E /* CCTimeLine.cpp in Sources */,
15AE188E19AAD33D00C27E9E /* CCLabelTTFLoader.cpp in Sources */,
15AE1A3019AAD3D500C27E9E /* b2ChainShape.cpp in Sources */,
@ -6668,6 +6689,7 @@
15AE196E19AAD35700C27E9E /* CCActionTimelineCache.cpp in Sources */,
50ABBEB31925AB6F00A911A9 /* CCUserDefault-apple.mm in Sources */,
50ABBEB51925AB6F00A911A9 /* CCUserDefault-android.cpp in Sources */,
5E9F61261A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */,
29394CF619B01DBA00D2DE1A /* UIWebViewImpl-ios.mm in Sources */,
382383FC1A258FA7002C4610 /* idl_gen_text.cpp in Sources */,
50ABBE831925AB6F00A911A9 /* ccFPSImages.c in Sources */,
@ -6968,6 +6990,7 @@
B29A7E0019EE1B7700872B35 /* Json.c in Sources */,
1A570120180BC90D0088DEC7 /* CCGrid.cpp in Sources */,
15AE181119AAD2F700C27E9E /* CCAnimation3D.cpp in Sources */,
5E9F612B1A3FFE3D0038DE01 /* CCPlane.cpp in Sources */,
1A57019E180BCB590088DEC7 /* CCFont.cpp in Sources */,
15AE1ACC19AAD40300C27E9E /* b2PrismaticJoint.cpp in Sources */,
15AE195F19AAD35100C27E9E /* CCSpriteFrameCacheHelper.cpp in Sources */,
@ -7138,6 +7161,7 @@
1A57030D180BCF190088DEC7 /* CCComponent.cpp in Sources */,
15AE1B8F19AADA9A00C27E9E /* UIDeprecated.cpp in Sources */,
464AD6E6197EBB1400E502D8 /* pvr.cpp in Sources */,
5E9F61271A3FFE3D0038DE01 /* CCFrustum.cpp in Sources */,
15AE1B7619AADA9A00C27E9E /* UIPageView.cpp in Sources */,
1A570311180BCF190088DEC7 /* CCComponentContainer.cpp in Sources */,
50ABBE2C1925AB6F00A911A9 /* ccCArray.cpp in Sources */,

View File

@ -69,6 +69,8 @@ Camera::Camera()
: _scene(nullptr)
, _viewProjectionDirty(true)
, _cameraFlag(1)
, _frustumDirty(true)
, _enableFrustumCulling(true)
{
}
@ -96,6 +98,7 @@ const Mat4& Camera::getViewMatrix() const
if (memcmp(viewInv.m, _viewInv.m, count) != 0)
{
_viewProjectionDirty = true;
_frustumDirty = true;
_viewInv = viewInv;
_view = viewInv.getInversed();
}
@ -205,6 +208,7 @@ bool Camera::initPerspective(float fieldOfView, float aspectRatio, float nearPla
}
#endif
_viewProjectionDirty = true;
_frustumDirty = true;
return true;
}
@ -225,6 +229,7 @@ bool Camera::initOrthographic(float zoomX, float zoomY, float nearPlane, float f
}
#endif
_viewProjectionDirty = true;
_frustumDirty = true;
return true;
}
@ -248,6 +253,26 @@ void Camera::unproject(const Size& viewport, Vec3* src, Vec3* dst) const
dst->set(screen.x, screen.y, screen.z);
}
void Camera::enableFrustumCulling(bool enalbe, bool clipZ)
{
_enableFrustumCulling = enalbe;
_frustum.setClipZ(clipZ);
}
bool Camera::isVisibleInFrustum(const AABB* aabb) const
{
if (_enableFrustumCulling)
{
if (_frustumDirty)
{
_frustum.initFrustum(this);
_frustumDirty = false;
}
return !_frustum.isOutOfFrustum(*aabb);
}
return true;
}
void Camera::onEnter()
{
if (_scene == nullptr)

View File

@ -25,6 +25,7 @@ THE SOFTWARE.
#define _CCCAMERA_H__
#include "2d/CCNode.h"
#include "3d/CCFrustum.h"
NS_CC_BEGIN
@ -135,6 +136,16 @@ public:
*/
void unproject(const Size& viewport, Vec3* src, Vec3* dst) const;
/**
* Enable frustum culling
*/
void enableFrustumCulling(bool enalbe, bool clipZ);
/**
* Is this aabb visible in frustum
*/
bool isVisibleInFrustum(const AABB* aabb)const;
//override
virtual void onEnter() override;
virtual void onExit() override;
@ -171,7 +182,9 @@ protected:
float _farPlane;
mutable bool _viewProjectionDirty;
unsigned short _cameraFlag; // camera flag
mutable Frustum _frustum; // camera frustum
mutable bool _frustumDirty;
bool _enableFrustumCulling;
static Camera* _visitingCamera;
friend class Director;

View File

@ -228,11 +228,13 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
<ClCompile Include="..\3d\CCBillBoard.cpp" />
<ClCompile Include="..\3d\CCBundle3D.cpp" />
<ClCompile Include="..\3d\CCBundleReader.cpp" />
<ClCompile Include="..\3d\CCFrustum.cpp" />
<ClCompile Include="..\3d\CCMesh.cpp" />
<ClCompile Include="..\3d\CCMeshSkin.cpp" />
<ClCompile Include="..\3d\CCMeshVertexIndexData.cpp" />
<ClCompile Include="..\3d\CCOBB.cpp" />
<ClCompile Include="..\3d\CCObjLoader.cpp" />
<ClCompile Include="..\3d\CCPlane.cpp" />
<ClCompile Include="..\3d\CCRay.cpp" />
<ClCompile Include="..\3d\CCSkeleton3D.cpp" />
<ClCompile Include="..\3d\CCSprite3D.cpp" />
@ -600,11 +602,13 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
<ClInclude Include="..\3d\CCBundle3D.h" />
<ClInclude Include="..\3d\CCBundle3DData.h" />
<ClInclude Include="..\3d\CCBundleReader.h" />
<ClInclude Include="..\3d\CCFrustum.h" />
<ClInclude Include="..\3d\CCMesh.h" />
<ClInclude Include="..\3d\CCMeshSkin.h" />
<ClInclude Include="..\3d\CCMeshVertexIndexData.h" />
<ClInclude Include="..\3d\CCOBB.h" />
<ClInclude Include="..\3d\CCObjLoader.h" />
<ClInclude Include="..\3d\CCPlane.h" />
<ClInclude Include="..\3d\CCRay.h" />
<ClInclude Include="..\3d\CCSkeleton3D.h" />
<ClInclude Include="..\3d\CCSprite3D.h" />

View File

@ -62,6 +62,21 @@ Mat4 AttachNode::getWorldToNodeTransform() const
return mat;
}
Mat4 AttachNode::getNodeToWorldTransform() const
{
Mat4 mat;
auto parent = getParent();
if (parent)
{
mat = parent->getNodeToWorldTransform() * _attachBone->getWorldMat();
}
else
{
mat = _attachBone->getWorldMat();
}
return mat;
}
void AttachNode::visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags)
{
Node::visit(renderer, parentTransform * _attachBone->getWorldMat(), Node::FLAGS_DIRTY_MASK);

View File

@ -49,6 +49,7 @@ public:
static AttachNode* create(Bone3D* attachBone);
virtual Mat4 getWorldToNodeTransform() const override;
virtual Mat4 getNodeToWorldTransform() const override;
virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) override;
CC_CONSTRUCTOR_ACCESS:

View File

@ -260,7 +260,6 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeD
}
meshdatas.meshDatas.push_back(meshdata);
NMaterialData materialdata;
int i = 0;
char str[20];
std::string dir = "";
@ -270,6 +269,8 @@ bool Bundle3D::loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeD
for (const auto& it : shapes.shapes)
{
NMaterialData materialdata;
NTextureData tex;
tex.filename = it.material.diffuse_texname.empty() ? it.material.diffuse_texname : dir + it.material.diffuse_texname;
tex.type = NTextureData::Usage::Diffuse;

95
cocos/3d/CCFrustum.cpp Executable file
View File

@ -0,0 +1,95 @@
/****************************************************************************
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/CCFrustum.h"
#include "2d/CCCamera.h"
NS_CC_BEGIN
bool Frustum::initFrustum(const Camera* camera)
{
_initialized = true;
createPlane(camera);
return true;
}
bool Frustum::isOutOfFrustum(const AABB& aabb) const
{
if (_initialized)
{
Vec3 point;
int plane = _clipZ ? 6 : 4;
for (int i = 0; i < plane; i++)
{
const Vec3& normal = _plane[i].getNormal();
point.x = normal.x < 0 ? aabb._max.x : aabb._min.x;
point.y = normal.y < 0 ? aabb._max.y : aabb._min.y;
point.z = normal.z < 0 ? aabb._max.z : aabb._min.z;
if (_plane[i].getSide(point) == PointSide::FRONT_PLANE )
return true;
}
}
return false;
}
bool Frustum::isOutOfFrustum(const OBB& obb) const
{
if (_initialized)
{
Vec3 point;
int plane = _clipZ ? 6 : 4;
Vec3 obbExtentX = obb._xAxis * obb._extents.x;
Vec3 obbExtentY = obb._yAxis * obb._extents.y;
Vec3 obbExtentZ = obb._zAxis * obb._extents.z;
for (int i = 0; i < plane; i++)
{
const Vec3& normal = _plane[i].getNormal();
point = obb._center;
point = normal.dot(obb._xAxis) > 0 ? point - obbExtentX : point + obbExtentX;
point = normal.dot(obb._yAxis) > 0 ? point - obbExtentY : point + obbExtentY;
point = normal.dot(obb._zAxis) > 0 ? point - obbExtentZ : point + obbExtentZ;
if (_plane[i].getSide(point) == PointSide::FRONT_PLANE)
return true;
}
}
return false;
}
void Frustum::createPlane(const Camera* camera)
{
const Mat4& mat = camera->getViewProjectionMatrix();
//ref http://www.lighthouse3d.com/tutorials/view-frustum-culling/clip-space-approach-extracting-the-planes/
//extract frustum plane
_plane[0].initPlane(-Vec3(mat.m[3] + mat.m[0], mat.m[7] + mat.m[4], mat.m[11] + mat.m[8]), (mat.m[15] + mat.m[12]));//left
_plane[1].initPlane(-Vec3(mat.m[3] - mat.m[0], mat.m[7] - mat.m[4], mat.m[11] - mat.m[8]), (mat.m[15] - mat.m[12]));//right
_plane[2].initPlane(-Vec3(mat.m[3] + mat.m[1], mat.m[7] + mat.m[5], mat.m[11] + mat.m[9]), (mat.m[15] + mat.m[13]));//bottom
_plane[3].initPlane(-Vec3(mat.m[3] - mat.m[1], mat.m[7] - mat.m[5], mat.m[11] - mat.m[9]), (mat.m[15] - mat.m[13]));//top
_plane[4].initPlane(-Vec3(mat.m[3] + mat.m[2], mat.m[7] + mat.m[6], mat.m[11] + mat.m[10]), (mat.m[15] + mat.m[14]));//near
_plane[5].initPlane(-Vec3(mat.m[3] - mat.m[2], mat.m[7] - mat.m[6], mat.m[11] - mat.m[10]), (mat.m[15] - mat.m[14]));//far
}
NS_CC_END

80
cocos/3d/CCFrustum.h Executable file
View File

@ -0,0 +1,80 @@
/****************************************************************************
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_FRUSTUM_H_
#define __CC_FRUSTUM_H_
#include "base/ccMacros.h"
#include "math/CCMath.h"
#include "3d/CCAABB.h"
#include "3d/CCOBB.h"
#include "3d/CCPlane.h"
NS_CC_BEGIN
class Camera;
class CC_DLL Frustum
{
friend class Camera;
public:
/**
* Constructor & Destructor.
*/
Frustum(): _initialized(false), _clipZ(true){}
~Frustum(){}
/**
* init frustum from camera.
*/
bool initFrustum(const Camera* camera);
/**
* is aabb out of frustum.
*/
bool isOutOfFrustum(const AABB& aabb) const;
/**
* is obb out of frustum
*/
bool isOutOfFrustum(const OBB& obb) const;
/**
* get & set z clip. if bclipZ == true use near and far plane
*/
void setClipZ(bool clipZ) { _clipZ = clipZ; }
bool isClipZ() { return _clipZ; }
protected:
/**
* create clip plane
*/
void createPlane(const Camera* camera);
Plane _plane[6]; // clip plane, left, right, top, bottom, near, far
bool _clipZ; // use near and far clip plane
bool _initialized;
};
NS_CC_END
#endif//__CC_FRUSTUM_H_

View File

@ -215,6 +215,8 @@ OBB::OBB(const AABB& aabb)
_extents = aabb._max - aabb._min;
_extents.scale(0.5f);
computeExtAxis();
}
OBB::OBB(const Vec3* verts, int num)
@ -259,6 +261,8 @@ OBB::OBB(const Vec3* verts, int num)
_zAxis.normalize();
_extents = 0.5f * (vecMax - vecMin);
computeExtAxis();
}
bool OBB::containPoint(const Vec3& point) const
@ -296,19 +300,15 @@ void OBB::reset()
void OBB::getCorners(Vec3* verts) const
{
Vec3 extX = _xAxis * _extents.x;
Vec3 extY = _yAxis * _extents.y;
Vec3 extZ = _zAxis * _extents.z;
verts[0] = _center - _extentX + _extentY + _extentZ; // left top front
verts[1] = _center - _extentX - _extentY + _extentZ; // left bottom front
verts[2] = _center + _extentX - _extentY + _extentZ; // right bottom front
verts[3] = _center + _extentX + _extentY + _extentZ; // right top front
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
verts[4] = _center + _extentX + _extentY - _extentZ; // right top back
verts[5] = _center + _extentX - _extentY - _extentZ; // right bottom back
verts[6] = _center - _extentX - _extentY - _extentZ; // left bottom back
verts[7] = _center - _extentX + _extentY - _extentZ; // left top back
}
float OBB::projectPoint(const Vec3& point, const Vec3& axis)const
@ -447,6 +447,8 @@ void OBB::transform(const Mat4& mat)
_extents.x *= scale.x;
_extents.y *= scale.y;
_extents.z *= scale.z;
computeExtAxis();
}
NS_CC_END

View File

@ -84,6 +84,16 @@ public:
void transform(const Mat4& mat);
protected:
/*
* compute extX, extY, extZ
*/
void computeExtAxis()
{
_extentX = _xAxis * _extents.x;
_extentY = _yAxis * _extents.y;
_extentZ = _zAxis * _extents.z;
}
/*
* Project point to the target axis
*/
@ -109,6 +119,9 @@ public:
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 _extentX; // _xAxis * _extents.x
Vec3 _extentY; // _yAxis * _extents.y
Vec3 _extentZ; // _zAxis * _extents.z
Vec3 _extents; // obb length along each axis
};

95
cocos/3d/CCPlane.cpp Executable file
View File

@ -0,0 +1,95 @@
/****************************************************************************
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 "CCPlane.h"
NS_CC_BEGIN
Plane::Plane()
:
_normal(0.f, 0.f, 1.f),
_dist(0.f)
{
}
// create plane from tree point
Plane::Plane(const Vec3& p1, const Vec3& p2, const Vec3& p3)
{
initPlane(p1, p2, p3);
}
// create plane from normal and dist
Plane::Plane(const Vec3& normal, float dist)
{
initPlane(normal, dist);
}
// create plane from normal and a point on plane
Plane::Plane(const Vec3& normal, const Vec3& point)
{
initPlane(normal, point);
}
void Plane::initPlane(const Vec3& p1, const Vec3& p2, const Vec3& p3)
{
Vec3 p21 = p2 - p1;
Vec3 p32 = p3 - p2;
Vec3::cross(p21, p32, &_normal);
_normal.normalize();
_dist = _normal.dot(p1);
}
void Plane::initPlane(const Vec3& normal, float dist)
{
float oneOverLength = 1 / normal.length();
_normal = normal * oneOverLength;
_dist = dist * oneOverLength;
}
void Plane::initPlane(const Vec3& normal, const Vec3& point)
{
_normal = normal;
_normal.normalize();
_dist = _normal.dot(point);
}
float Plane::dist2Plane(const Vec3& p) const
{
return _normal.dot(p) - _dist;
}
PointSide Plane::getSide(const Vec3& point) const
{
float dist = dist2Plane(point);
if (dist > 0)
return PointSide::FRONT_PLANE;
else if (dist < 0)
return PointSide::BEHIND_PLANE;
else
return PointSide::IN_PLANE;
}
NS_CC_END

101
cocos/3d/CCPlane.h Executable file
View File

@ -0,0 +1,101 @@
/****************************************************************************
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_PLANE_H_
#define __CC_PLANE_H_
#include "base/ccMacros.h"
#include "math/CCMath.h"
NS_CC_BEGIN
enum class PointSide
{
IN_PLANE,
FRONT_PLANE,
BEHIND_PLANE,
};
class CC_DLL Plane
{
public:
/**
* create plane from tree point.
*/
Plane(const Vec3& p1, const Vec3& p2, const Vec3& p3);
/**
* create plane from normal and dist.
*/
Plane(const Vec3& normal, float dist);
/**
* create plane from normal and a point on plane.
*/
Plane(const Vec3& normal, const Vec3& point);
Plane();
/**
* init plane from tree point.
*/
void initPlane(const Vec3& p1, const Vec3& p2, const Vec3& p3);
/**
* init plane from normal and dist.
*/
void initPlane(const Vec3& normal, float dist);
/**
* init plane from normal and a point on plane.
*/
void initPlane(const Vec3& normal, const Vec3& point);
/**
* dist to plane, > 0 normal direction
*/
float dist2Plane(const Vec3& p) const;
/**
* Gets the plane's normal.
*/
const Vec3& getNormal() const { return _normal; }
/**
* Gets the plane's distance to the origin along its normal.
*/
float getDist() const { return _dist; }
/**
* Return the side where the point is.
*/
PointSide getSide(const Vec3& point) const;
protected:
Vec3 _normal;
float _dist;
};
NS_CC_END
#endif

View File

@ -140,10 +140,26 @@ bool Ray::intersects(const OBB& obb) const
return ray.intersects(aabb);
}
float Ray::dist(const Plane& plane) const
{
float ndd = Vec3::dot(plane.getNormal(), _direction);
if(ndd == 0)
return 0.0f;
float ndo = Vec3::dot(plane.getNormal(), _origin);
return (plane.getDist() - ndo) / ndd;
}
Vec3 Ray::intersects(const Plane& plane) const
{
float dis = this->dist(plane);
return _origin + dis * _direction;
}
void Ray::set(const Vec3& origin, const Vec3& direction)
{
_origin = origin;
_direction = direction;
_direction.normalize();
}
void Ray::transform(const Mat4& matrix)

View File

@ -28,6 +28,7 @@
#include "math/CCMath.h"
#include "3d/CCAABB.h"
#include "3d/CCOBB.h"
#include "3d/CCPlane.h"
NS_CC_BEGIN
@ -67,6 +68,9 @@ public:
*/
bool intersects(const OBB& obb) const;
float dist(const Plane& plane) const;
Vec3 intersects(const Plane& plane) const;
/**
* Sets this ray to the specified values.
*

View File

@ -601,6 +601,10 @@ static Texture2D * getDummyTexture()
void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
// camera clipping
if(!Camera::getVisitingCamera()->isVisibleInFrustum(&this->getAABB()))
return;
if (_skeleton)
_skeleton->updateBoneMatrix();

View File

@ -11,11 +11,13 @@ set(COCOS_3D_SRC
3d/CCAttachNode.cpp
3d/CCBundle3D.cpp
3d/CCBundleReader.cpp
3d/CCFrustum.cpp
3d/CCMesh.cpp
3d/CCMeshSkin.cpp
3d/CCMeshVertexIndexData.cpp
3d/CCOBB.cpp
3d/CCObjLoader.cpp
3d/CCPlane.cpp
3d/CCRay.cpp
3d/CCSkeleton3D.cpp
3d/CCSprite3D.cpp

View File

@ -77,6 +77,8 @@ cocos2d.cpp \
2d/CCTransitionPageTurn.cpp \
2d/CCTransitionProgress.cpp \
2d/CCTweenFunction.cpp \
3d/CCFrustum.cpp \
3d/CCPlane.cpp \
platform/CCGLView.cpp \
platform/CCFileUtils.cpp \
platform/CCSAXParser.cpp \

View File

@ -283,6 +283,8 @@ THE SOFTWARE.
#include "3d/CCMeshVertexIndexData.h"
#include "3d/CCSkeleton3D.h"
#include "3d/CCBillBoard.h"
#include "3d/CCFrustum.h"
#include "3d/CCPlane.h"
// Deprecated include
#include "deprecated/CCDictionary.h"

View File

@ -12,12 +12,6 @@
-- @param #cc.Bone3D attachBone
-- @return AttachNode#AttachNode ret (return value: cc.AttachNode)
--------------------------------
--
-- @function [parent=#AttachNode] getWorldToNodeTransform
-- @param self
-- @return mat4_table#mat4_table ret (return value: mat4_table)
--------------------------------
--
-- @function [parent=#AttachNode] visit
@ -26,4 +20,16 @@
-- @param #mat4_table parentTransform
-- @param #unsigned int parentFlags
--------------------------------
--
-- @function [parent=#AttachNode] getWorldToNodeTransform
-- @param self
-- @return mat4_table#mat4_table ret (return value: mat4_table)
--------------------------------
--
-- @function [parent=#AttachNode] getNodeToWorldTransform
-- @param self
-- @return mat4_table#mat4_table ret (return value: mat4_table)
return nil

View File

@ -37,6 +37,13 @@
-- @param self
-- @return int#int ret (return value: int)
--------------------------------
-- Enable frustum culling
-- @function [parent=#Camera] enableFrustumCulling
-- @param self
-- @param #bool enalbe
-- @param #bool clipZ
--------------------------------
-- Creates a view matrix based on the specified input parameters.<br>
-- param eyePosition The eye position.<br>
@ -48,6 +55,13 @@
-- @param #vec3_table target
-- @param #vec3_table up
--------------------------------
-- Is this aabb visible in frustum
-- @function [parent=#Camera] isVisibleInFrustum
-- @param self
-- @param #cc.AABB aabb
-- @return bool#bool ret (return value: bool)
--------------------------------
--
-- @function [parent=#Camera] setCameraFlag

View File

@ -27,107 +27,6 @@ THE SOFTWARE.
#include <algorithm>
#include "../testResource.h"
////////////DrawLine/////////////////////
class DrawLine3D: public Node
{
public:
/** creates and initialize a node */
static DrawLine3D* create();
/**
* Draw 3D Line
*/
void drawLine(const Vec3 &from, const Vec3 &to, const Color4F &color);
/** Clear the geometry in the node's buffer. */
void clear()
{
_buffer.clear();
}
void onDraw(const Mat4 &transform, uint32_t flags);
// Overrides
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
CC_CONSTRUCTOR_ACCESS:
DrawLine3D()
{
}
virtual ~DrawLine3D()
{
}
virtual bool init();
protected:
struct V3F_C4B
{
Vec3 vertices;
Color4B colors;
};
std::vector<V3F_C4B> _buffer;
CustomCommand _customCommand;
private:
CC_DISALLOW_COPY_AND_ASSIGN(DrawLine3D);
};
DrawLine3D* DrawLine3D::create()
{
auto ret = new (std::nothrow) DrawLine3D();
if (ret && ret->init())
return ret;
CC_SAFE_DELETE(ret);
return nullptr;
}
bool DrawLine3D::init()
{
setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_COLOR));
return true;
}
void DrawLine3D::drawLine(const Vec3 &from, const Vec3 &to, const Color4F &color)
{
Color4B col = Color4B(color);
DrawLine3D::V3F_C4B vertex;
vertex.vertices = from;
vertex.colors = col;
_buffer.push_back(vertex);
vertex.vertices = to;
_buffer.push_back(vertex);
}
void DrawLine3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(DrawLine3D::onDraw, this, transform, flags);
renderer->addCommand(&_customCommand);
}
void DrawLine3D::onDraw(const Mat4 &transform, uint32_t flags)
{
auto glProgram = getGLProgram();
glProgram->use();
glProgram->setUniformsForBuiltins(transform);
glEnable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B), &(_buffer[0].vertices));
glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B), &(_buffer[0].colors));
glDrawArrays(GL_LINES, 0, static_cast<int>(_buffer.size()));
glDisable(GL_DEPTH_TEST);
}
////////////////////////////////////////////////////////////////////////////////
enum
{
IDC_NEXT = 100,
@ -140,6 +39,7 @@ static int sceneIdx = -1;
static std::function<Layer*()> createFunctions[] =
{
CL(Camera3DTestDemo),
CL(CameraClippingDemo)
};
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
@ -354,7 +254,7 @@ void Camera3DTestDemo::onEnter()
_layer3D->addChild(_camera);
}
SwitchViewCallback(this,CameraType::ThirdCamera);
DrawLine3D* line =DrawLine3D::create();
DrawNode3D* line =DrawNode3D::create();
//draw x
for( int j =-20; j<=20 ;j++)
{
@ -755,6 +655,314 @@ void Camera3DTestDemo::onTouchesRotateRightEnd(Touch* touch, Event* event)
{
_bRotateRight = false;
}
////////////////////////////////////////////////////////////
// CameraClippingDemo
CameraClippingDemo::CameraClippingDemo(void)
: BaseTest()
, _layer3D(nullptr)
, _cameraType(CameraType::FirstCamera)
, _cameraFirst(nullptr)
, _cameraThird(nullptr)
, _moveAction(nullptr)
, _drawAABB(nullptr)
, _drawFrustum(nullptr)
, _row(3)
{
}
CameraClippingDemo::~CameraClippingDemo(void)
{
}
std::string CameraClippingDemo::title() const
{
return "Camera Frustum Clipping";
}
void CameraClippingDemo::restartCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild(restartSpriteTestAction());
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraClippingDemo::nextCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( nextSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraClippingDemo::backCallback(Ref* sender)
{
auto s = new (std::nothrow) Camera3DTestScene();
s->addChild( backSpriteTestAction() );
Director::getInstance()->replaceScene(s);
s->release();
}
void CameraClippingDemo::onEnter()
{
BaseTest::onEnter();
schedule(schedule_selector(CameraClippingDemo::update), 0.0f);
auto s = Director::getInstance()->getWinSize();
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesBegan = CC_CALLBACK_2(CameraClippingDemo::onTouchesBegan, this);
listener->onTouchesMoved = CC_CALLBACK_2(CameraClippingDemo::onTouchesMoved, this);
listener->onTouchesEnded = CC_CALLBACK_2(CameraClippingDemo::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
auto layer3D=Layer::create();
addChild(layer3D,0);
_layer3D=layer3D;
// swich camera
MenuItemFont::setFontName("fonts/arial.ttf");
MenuItemFont::setFontSize(20);
auto menuItem1 = MenuItemFont::create("Switch Camera", CC_CALLBACK_1(CameraClippingDemo::switchViewCallback,this));
menuItem1->setColor(Color3B(0,200,20));
auto menu = Menu::create(menuItem1,NULL);
menu->setPosition(Vec2::ZERO);
menuItem1->setPosition(VisibleRect::left().x + 80, VisibleRect::top().y -70);
addChild(menu, 1);
// + -
MenuItemFont::setFontSize(40);
auto decrease = MenuItemFont::create(" - ", CC_CALLBACK_1(CameraClippingDemo::delSpriteCallback, this));
decrease->setColor(Color3B(0,200,20));
auto increase = MenuItemFont::create(" + ", CC_CALLBACK_1(CameraClippingDemo::addSpriteCallback, this));
increase->setColor(Color3B(0,200,20));
menu = Menu::create(decrease, increase, nullptr);
menu->alignItemsHorizontally();
menu->setPosition(Vec2(s.width - 60, VisibleRect::top().y -70));
addChild(menu, 1);
TTFConfig ttfCount("fonts/Marker Felt.ttf", 30);
_labelSprite3DCount = Label::createWithTTF(ttfCount,"0 sprits");
_labelSprite3DCount->setColor(Color3B(0,200,20));
_labelSprite3DCount->setPosition(Vec2(s.width/2, VisibleRect::top().y -70));
addChild(_labelSprite3DCount);
// aabb drawNode3D
_drawAABB = DrawNode3D::create();
_drawAABB->setCameraMask((unsigned short) CameraFlag::USER1);
addChild(_drawAABB);
// frustum drawNode3D
_drawFrustum = DrawNode3D::create();
_drawFrustum->setCameraMask((unsigned short) CameraFlag::USER1);
addChild(_drawFrustum);
// set camera
switchViewCallback(this);
// add sprite
addSpriteCallback(nullptr);
}
void CameraClippingDemo::onExit()
{
BaseTest::onExit();
if (_cameraFirst)
{
_cameraFirst = nullptr;
}
if (_cameraThird)
{
_cameraThird = nullptr;
}
}
void CameraClippingDemo::update(float dt)
{
_drawAABB->clear();
if(_cameraType == CameraType::ThirdCamera)
drawCameraFrustum();
Vector<Node*>& children = _layer3D->getChildren();
Vec3 corners[8];
for (const auto& iter: children)
{
const AABB& aabb = static_cast<Sprite3D*>(iter)->getAABB();
if (_cameraFirst->isVisibleInFrustum(&aabb))
{
aabb.getCorners(corners);
_drawAABB->drawCube(corners, Color4F(0, 1, 0, 1));
}
}
}
void CameraClippingDemo::reachEndCallBack()
{
_cameraFirst->stopActionByTag(100);
auto inverse = (MoveTo*)_moveAction->reverse();
inverse->retain();
_moveAction->release();
_moveAction = inverse;
auto rot = RotateBy::create(1.f, Vec3(0.f, 180.f, 0.f));
auto seq = Sequence::create(rot, _moveAction, CallFunc::create(CC_CALLBACK_0(CameraClippingDemo::reachEndCallBack, this)), nullptr);
seq->setTag(100);
_cameraFirst->runAction(seq);
}
void CameraClippingDemo::switchViewCallback(Ref* sender)
{
auto s = Director::getInstance()->getWinSize();
if (_cameraFirst == nullptr)
{
_cameraFirst = Camera::createPerspective(30, (GLfloat)s.width/s.height, 10, 200);
_cameraFirst->setCameraFlag(CameraFlag::USER8);
_cameraFirst->setPosition3D(Vec3(-100,0,0));
_cameraFirst->lookAt(Vec3(1000,0,0), Vec3(0, 1, 0));
_moveAction = MoveTo::create(4.f, Vec2(100, 0));
_moveAction->retain();
auto seq = Sequence::create(_moveAction, CallFunc::create(CC_CALLBACK_0(CameraClippingDemo::reachEndCallBack, this)), nullptr);
seq->setTag(100);
_cameraFirst->runAction(seq);
addChild(_cameraFirst);
}
if (_cameraThird == nullptr)
{
_cameraThird = Camera::createPerspective(60, (GLfloat)s.width/s.height, 1, 1000);
_cameraThird->setCameraFlag(CameraFlag::USER8);
_cameraThird->setPosition3D(Vec3(0, 130, 130));
_cameraThird->lookAt(Vec3(0,0,0), Vec3(0, 1, 0));
addChild(_cameraThird);
}
if(_cameraType == CameraType::FirstCamera)
{
_cameraType = CameraType::ThirdCamera;
_cameraThird->setCameraFlag(CameraFlag::USER1);
_cameraThird->enableFrustumCulling(false, false);
_cameraFirst->setCameraFlag(CameraFlag::USER8);
}
else if(_cameraType == CameraType::ThirdCamera)
{
_cameraType = CameraType::FirstCamera;
_cameraFirst->setCameraFlag(CameraFlag::USER1);
_cameraFirst->enableFrustumCulling(true, true);
_cameraThird->setCameraFlag(CameraFlag::USER8);
_drawFrustum->clear();
}
}
void CameraClippingDemo::addSpriteCallback(Ref* sender)
{
_layer3D->removeAllChildren();
_objects.clear();
_drawAABB->clear();
++_row;
for (int x = -_row; x < _row; x++)
{
for (int z = -_row; z < _row; z++)
{
auto sprite = Sprite3D::create("Sprite3DTest/orc.c3b");
sprite->setPosition3D(Vec3(x * 30, 0, z * 30));
sprite->setRotation3D(Vec3(0,180,0));
_objects.push_back(sprite);
_layer3D->addChild(sprite);
}
}
// set layer mask.
_layer3D->setCameraMask( (unsigned short) CameraFlag::USER1);
// update sprite number
char szText[16];
sprintf(szText,"%ld sprits",_layer3D->getChildrenCount());
_labelSprite3DCount->setString(szText);
}
void CameraClippingDemo::delSpriteCallback(Ref* sender)
{
if (_row == 0) return;
_layer3D->removeAllChildren();
_objects.clear();
--_row;
for (int x = -_row; x < _row; x++)
{
for (int z = -_row; z < _row; z++)
{
auto sprite = Sprite3D::create("Sprite3DTest/orc.c3b");
sprite->setPosition3D(Vec3(x * 30, 0, z * 30));
_objects.push_back(sprite);
_layer3D->addChild(sprite);
}
}
// set layer mask.
_layer3D->setCameraMask((unsigned short) CameraFlag::USER1);
// update sprite number
char szText[16];
sprintf(szText,"%ld sprits",_layer3D->getChildrenCount());
_labelSprite3DCount->setString(szText);
}
void CameraClippingDemo::drawCameraFrustum()
{
_drawFrustum->clear();
auto size = Director::getInstance()->getWinSize();
Color4F color(1.f, 1.f, 0.f, 1);
// top-left
Vec3 tl_0,tl_1;
Vec3 src(0,0,0);
_cameraFirst->unproject(size, &src, &tl_0);
src = Vec3(0,0,1);
_cameraFirst->unproject(size, &src, &tl_1);
// top-right
Vec3 tr_0,tr_1;
src = Vec3(size.width,0,0);
_cameraFirst->unproject(size, &src, &tr_0);
src = Vec3(size.width,0,1);
_cameraFirst->unproject(size, &src, &tr_1);
// bottom-left
Vec3 bl_0,bl_1;
src = Vec3(0,size.height,0);
_cameraFirst->unproject(size, &src, &bl_0);
src = Vec3(0,size.height,1);
_cameraFirst->unproject(size, &src, &bl_1);
// bottom-right
Vec3 br_0,br_1;
src = Vec3(size.width,size.height,0);
_cameraFirst->unproject(size, &src, &br_0);
src = Vec3(size.width,size.height,1);
_cameraFirst->unproject(size, &src, &br_1);
_drawFrustum->drawLine(tl_0, tl_1, color);
_drawFrustum->drawLine(tr_0, tr_1, color);
_drawFrustum->drawLine(bl_0, bl_1, color);
_drawFrustum->drawLine(br_0, br_1, color);
_drawFrustum->drawLine(tl_0, tr_0, color);
_drawFrustum->drawLine(tr_0, br_0, color);
_drawFrustum->drawLine(br_0, bl_0, color);
_drawFrustum->drawLine(bl_0, tl_0, color);
_drawFrustum->drawLine(tl_1, tr_1, color);
_drawFrustum->drawLine(tr_1, br_1, color);
_drawFrustum->drawLine(br_1, bl_1, color);
_drawFrustum->drawLine(bl_1, tl_1, color);
}
void Camera3DTestScene::runThisTest()
{
auto layer = nextSpriteTestAction();

View File

@ -27,11 +27,14 @@ THE SOFTWARE.
#include "../testBasic.h"
#include "../BaseTest.h"
#include "../Sprite3DTest/DrawNode3D.h"
#include <string>
namespace cocos2d {
class Sprite3D;
class Delay;
}
enum State
{
State_None = 0,
@ -106,6 +109,45 @@ protected:
Label* _ZoomInlabel;
Label* _ZoomOutlabel;
};
class CameraClippingDemo : public BaseTest
{
public:
CREATE_FUNC(CameraClippingDemo);
CameraClippingDemo(void);
virtual ~CameraClippingDemo(void);
void restartCallback(Ref* sender);
void nextCallback(Ref* sender);
void backCallback(Ref* sender);
virtual void onEnter() override;
virtual void onExit() override;
virtual void update(float dt) override;
// overrides
virtual std::string title() const override;
void reachEndCallBack();
void switchViewCallback(Ref* sender);
void addSpriteCallback(Ref* sender);
void delSpriteCallback(Ref* sender);
void drawCameraFrustum();
protected:
Label* _labelSprite3DCount;
Layer* _layer3D;
std::vector<Sprite3D*> _objects;
CameraType _cameraType;
Camera* _cameraFirst;
Camera* _cameraThird;
MoveBy* _moveAction;
DrawNode3D* _drawAABB;
DrawNode3D* _drawFrustum;
int _row;
};
class Camera3DTestScene : public TestScene
{
public: