Merge pull request #7853 from super626/v3

Better reskin model support
This commit is contained in:
minggo 2014-08-22 19:18:47 +08:00
commit 0701fe1dfb
53 changed files with 8000 additions and 6746 deletions

View File

@ -57,14 +57,13 @@
1516200E199E75C2006099B8 /* CCRay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6105179199CB1A600DC41CE /* CCRay.cpp */; };
1516200F199E75C2006099B8 /* CCSkeleton3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EA2A83E1987A6810077B3D4 /* CCSkeleton3D.cpp */; };
15162010199E75C2006099B8 /* CCAttachNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E3198639EF00FA95D0 /* CCAttachNode.cpp */; };
15162011199E75C2006099B8 /* CCSubMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E5198639EF00FA95D0 /* CCSubMesh.cpp */; };
15162012199E75C2006099B8 /* CCSubMeshState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E7198639EF00FA95D0 /* CCSubMeshState.cpp */; };
15162011199E75C2006099B8 /* CCMeshVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E5198639EF00FA95D0 /* CCMeshVertexIndexData.cpp */; };
15162012199E75C2006099B8 /* CCMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E7198639EF00FA95D0 /* CCMesh.cpp */; };
15162013199E75C2006099B8 /* CCBundleReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EA4786E195478E00068D9D1 /* CCBundleReader.cpp */; };
15162014199E75C2006099B8 /* CCBundle3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6AAF83F19404E0D0069DE01 /* CCBundle3D.cpp */; };
15162015199E75C2006099B8 /* CCAnimate3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6ACD89C193DC0CC005E0B8A /* CCAnimate3D.cpp */; };
15162016199E75C2006099B8 /* CCMeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6ACD895193D6693005E0B8A /* CCMeshSkin.cpp */; };
15162017199E75C2006099B8 /* CCAnimation3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6B26341193884D60088FE25 /* CCAnimation3D.cpp */; };
15162018199E75C2006099B8 /* CCMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594B91926D61F003EEF37 /* CCMesh.cpp */; };
15162019199E75C2006099B8 /* CCObjLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BB1926D61F003EEF37 /* CCObjLoader.cpp */; };
1516201A199E75C2006099B8 /* CCSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BD1926D61F003EEF37 /* CCSprite3D.cpp */; };
1516201B199E75C2006099B8 /* CCSprite3DMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BF1926D61F003EEF37 /* CCSprite3DMaterial.cpp */; };
@ -73,15 +72,14 @@
1516201E199E75FE006099B8 /* CCRay.h in Headers */ = {isa = PBXBuildFile; fileRef = B610517A199CB1A600DC41CE /* CCRay.h */; };
1516201F199E75FE006099B8 /* CCSkeleton3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA2A83F1987A6810077B3D4 /* CCSkeleton3D.h */; };
15162020199E75FE006099B8 /* CCAttachNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E4198639EF00FA95D0 /* CCAttachNode.h */; };
15162021199E75FE006099B8 /* CCSubMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E6198639EF00FA95D0 /* CCSubMesh.h */; };
15162022199E75FF006099B8 /* CCSubMeshState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E8198639EF00FA95D0 /* CCSubMeshState.h */; };
15162021199E75FE006099B8 /* CCMeshVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E6198639EF00FA95D0 /* CCMeshVertexIndexData.h */; };
15162022199E75FF006099B8 /* CCMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E8198639EF00FA95D0 /* CCMesh.h */; };
15162023199E75FF006099B8 /* CCBundleReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA4786F195478E00068D9D1 /* CCBundleReader.h */; };
15162024199E75FF006099B8 /* CCBundle3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6AAF84019404E0D0069DE01 /* CCBundle3D.h */; };
15162025199E75FF006099B8 /* CCAnimate3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6ACD89D193DC0CC005E0B8A /* CCAnimate3D.h */; };
15162026199E75FF006099B8 /* CCMeshSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = B6ACD896193D6693005E0B8A /* CCMeshSkin.h */; };
15162027199E75FF006099B8 /* CCAnimation3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B26342193884D60088FE25 /* CCAnimation3D.h */; };
15162028199E75FF006099B8 /* CCAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B2633C19381FBF0088FE25 /* CCAnimationCurve.h */; };
15162029199E75FF006099B8 /* CCMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594BA1926D61F003EEF37 /* CCMesh.h */; };
1516202A199E75FF006099B8 /* CCObjLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594BC1926D61F003EEF37 /* CCObjLoader.h */; };
1516202B199E75FF006099B8 /* CCSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594BE1926D61F003EEF37 /* CCSprite3D.h */; };
1516202C199E75FF006099B8 /* CCSprite3DMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594C01926D61F003EEF37 /* CCSprite3DMaterial.h */; };
@ -91,14 +89,13 @@
15162204199E7874006099B8 /* CCRay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6105179199CB1A600DC41CE /* CCRay.cpp */; };
15162205199E7874006099B8 /* CCSkeleton3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EA2A83E1987A6810077B3D4 /* CCSkeleton3D.cpp */; };
15162206199E7874006099B8 /* CCAttachNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E3198639EF00FA95D0 /* CCAttachNode.cpp */; };
15162207199E7874006099B8 /* CCSubMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E5198639EF00FA95D0 /* CCSubMesh.cpp */; };
15162208199E7874006099B8 /* CCSubMeshState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E7198639EF00FA95D0 /* CCSubMeshState.cpp */; };
15162207199E7874006099B8 /* CCMeshVertexIndexData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E5198639EF00FA95D0 /* CCMeshVertexIndexData.cpp */; };
15162208199E7874006099B8 /* CCMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3E9E80E7198639EF00FA95D0 /* CCMesh.cpp */; };
15162209199E7874006099B8 /* CCBundleReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EA4786E195478E00068D9D1 /* CCBundleReader.cpp */; };
1516220A199E7874006099B8 /* CCBundle3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6AAF83F19404E0D0069DE01 /* CCBundle3D.cpp */; };
1516220B199E7874006099B8 /* CCAnimate3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6ACD89C193DC0CC005E0B8A /* CCAnimate3D.cpp */; };
1516220C199E7874006099B8 /* CCMeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6ACD895193D6693005E0B8A /* CCMeshSkin.cpp */; };
1516220D199E7874006099B8 /* CCAnimation3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6B26341193884D60088FE25 /* CCAnimation3D.cpp */; };
1516220E199E7874006099B8 /* CCMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594B91926D61F003EEF37 /* CCMesh.cpp */; };
1516220F199E7874006099B8 /* CCObjLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BB1926D61F003EEF37 /* CCObjLoader.cpp */; };
15162210199E7874006099B8 /* CCSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BD1926D61F003EEF37 /* CCSprite3D.cpp */; };
15162211199E7874006099B8 /* CCSprite3DMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BF1926D61F003EEF37 /* CCSprite3DMaterial.cpp */; };
@ -107,15 +104,14 @@
15162214199E7A32006099B8 /* CCRay.h in Headers */ = {isa = PBXBuildFile; fileRef = B610517A199CB1A600DC41CE /* CCRay.h */; };
15162215199E7A32006099B8 /* CCSkeleton3D.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA2A83F1987A6810077B3D4 /* CCSkeleton3D.h */; };
15162216199E7A32006099B8 /* CCAttachNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E4198639EF00FA95D0 /* CCAttachNode.h */; };
15162217199E7A32006099B8 /* CCSubMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E6198639EF00FA95D0 /* CCSubMesh.h */; };
15162218199E7A32006099B8 /* CCSubMeshState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E8198639EF00FA95D0 /* CCSubMeshState.h */; };
15162217199E7A32006099B8 /* CCMeshVertexIndexData.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E6198639EF00FA95D0 /* CCMeshVertexIndexData.h */; };
15162218199E7A32006099B8 /* CCMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E9E80E8198639EF00FA95D0 /* CCMesh.h */; };
15162219199E7A32006099B8 /* CCBundleReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA4786F195478E00068D9D1 /* CCBundleReader.h */; };
1516221A199E7A32006099B8 /* CCBundle3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6AAF84019404E0D0069DE01 /* CCBundle3D.h */; };
1516221B199E7A32006099B8 /* CCAnimate3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6ACD89D193DC0CC005E0B8A /* CCAnimate3D.h */; };
1516221C199E7A32006099B8 /* CCMeshSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = B6ACD896193D6693005E0B8A /* CCMeshSkin.h */; };
1516221D199E7A32006099B8 /* CCAnimation3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B26342193884D60088FE25 /* CCAnimation3D.h */; };
1516221E199E7A32006099B8 /* CCAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B2633C19381FBF0088FE25 /* CCAnimationCurve.h */; };
1516221F199E7A32006099B8 /* CCMesh.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594BA1926D61F003EEF37 /* CCMesh.h */; };
15162220199E7A32006099B8 /* CCObjLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594BC1926D61F003EEF37 /* CCObjLoader.h */; };
15162221199E7A32006099B8 /* CCSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594BE1926D61F003EEF37 /* CCSprite3D.h */; };
15162222199E7A32006099B8 /* CCSprite3DMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594C01926D61F003EEF37 /* CCSprite3DMaterial.h */; };
@ -2534,10 +2530,10 @@
3E61781C1966A5A300DE83F5 /* CCController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCController.cpp; path = ../base/CCController.cpp; sourceTree = "<group>"; };
3E9E80E3198639EF00FA95D0 /* CCAttachNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAttachNode.cpp; sourceTree = "<group>"; };
3E9E80E4198639EF00FA95D0 /* CCAttachNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAttachNode.h; sourceTree = "<group>"; };
3E9E80E5198639EF00FA95D0 /* CCSubMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSubMesh.cpp; sourceTree = "<group>"; };
3E9E80E6198639EF00FA95D0 /* CCSubMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSubMesh.h; sourceTree = "<group>"; };
3E9E80E7198639EF00FA95D0 /* CCSubMeshState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSubMeshState.cpp; sourceTree = "<group>"; };
3E9E80E8198639EF00FA95D0 /* CCSubMeshState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSubMeshState.h; sourceTree = "<group>"; };
3E9E80E5198639EF00FA95D0 /* CCMeshVertexIndexData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCMeshVertexIndexData.cpp; sourceTree = "<group>"; };
3E9E80E6198639EF00FA95D0 /* CCMeshVertexIndexData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCMeshVertexIndexData.h; sourceTree = "<group>"; };
3E9E80E7198639EF00FA95D0 /* CCMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCMesh.cpp; sourceTree = "<group>"; };
3E9E80E8198639EF00FA95D0 /* CCMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCMesh.h; sourceTree = "<group>"; };
3EA0FB69191C841D00B170C8 /* UIVideoPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIVideoPlayer.h; sourceTree = "<group>"; };
3EA0FB6A191C841D00B170C8 /* UIVideoPlayerIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UIVideoPlayerIOS.mm; sourceTree = "<group>"; };
3EA2A83E1987A6810077B3D4 /* CCSkeleton3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSkeleton3D.cpp; sourceTree = "<group>"; };
@ -3084,8 +3080,6 @@
B29594B11926D5D9003EEF37 /* ccShader_3D_PositionTex.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_PositionTex.vert; sourceTree = "<group>"; };
B29594B21926D5EC003EEF37 /* CCMeshCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCMeshCommand.cpp; sourceTree = "<group>"; };
B29594B31926D5EC003EEF37 /* CCMeshCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCMeshCommand.h; sourceTree = "<group>"; };
B29594B91926D61F003EEF37 /* CCMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCMesh.cpp; sourceTree = "<group>"; };
B29594BA1926D61F003EEF37 /* CCMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCMesh.h; sourceTree = "<group>"; };
B29594BB1926D61F003EEF37 /* CCObjLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCObjLoader.cpp; sourceTree = "<group>"; };
B29594BC1926D61F003EEF37 /* CCObjLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCObjLoader.h; sourceTree = "<group>"; };
B29594BD1926D61F003EEF37 /* CCSprite3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSprite3D.cpp; sourceTree = "<group>"; };
@ -5311,10 +5305,10 @@
3EA2A83F1987A6810077B3D4 /* CCSkeleton3D.h */,
3E9E80E3198639EF00FA95D0 /* CCAttachNode.cpp */,
3E9E80E4198639EF00FA95D0 /* CCAttachNode.h */,
3E9E80E5198639EF00FA95D0 /* CCSubMesh.cpp */,
3E9E80E6198639EF00FA95D0 /* CCSubMesh.h */,
3E9E80E7198639EF00FA95D0 /* CCSubMeshState.cpp */,
3E9E80E8198639EF00FA95D0 /* CCSubMeshState.h */,
3E9E80E5198639EF00FA95D0 /* CCMeshVertexIndexData.cpp */,
3E9E80E6198639EF00FA95D0 /* CCMeshVertexIndexData.h */,
3E9E80E7198639EF00FA95D0 /* CCMesh.cpp */,
3E9E80E8198639EF00FA95D0 /* CCMesh.h */,
3EA4786E195478E00068D9D1 /* CCBundleReader.cpp */,
3EA4786F195478E00068D9D1 /* CCBundleReader.h */,
B6AAF83F19404E0D0069DE01 /* CCBundle3D.cpp */,
@ -5327,8 +5321,6 @@
B6B26342193884D60088FE25 /* CCAnimation3D.h */,
B6B2633B19381FBF0088FE25 /* CCAnimationCurve.inl */,
B6B2633C19381FBF0088FE25 /* CCAnimationCurve.h */,
B29594B91926D61F003EEF37 /* CCMesh.cpp */,
B29594BA1926D61F003EEF37 /* CCMesh.h */,
B29594BB1926D61F003EEF37 /* CCObjLoader.cpp */,
B29594BC1926D61F003EEF37 /* CCObjLoader.h */,
B29594BD1926D61F003EEF37 /* CCSprite3D.cpp */,
@ -5353,8 +5345,8 @@
1516201E199E75FE006099B8 /* CCRay.h in Headers */,
1516201F199E75FE006099B8 /* CCSkeleton3D.h in Headers */,
15162020199E75FE006099B8 /* CCAttachNode.h in Headers */,
15162021199E75FE006099B8 /* CCSubMesh.h in Headers */,
15162022199E75FF006099B8 /* CCSubMeshState.h in Headers */,
15162021199E75FE006099B8 /* CCMeshVertexIndexData.h in Headers */,
15162022199E75FF006099B8 /* CCMesh.h in Headers */,
15162023199E75FF006099B8 /* CCBundleReader.h in Headers */,
15162024199E75FF006099B8 /* CCBundle3D.h in Headers */,
15162025199E75FF006099B8 /* CCAnimate3D.h in Headers */,
@ -5362,7 +5354,6 @@
15162026199E75FF006099B8 /* CCMeshSkin.h in Headers */,
15162027199E75FF006099B8 /* CCAnimation3D.h in Headers */,
15162028199E75FF006099B8 /* CCAnimationCurve.h in Headers */,
15162029199E75FF006099B8 /* CCMesh.h in Headers */,
1516202A199E75FF006099B8 /* CCObjLoader.h in Headers */,
1516202B199E75FF006099B8 /* CCSprite3D.h in Headers */,
1516202C199E75FF006099B8 /* CCSprite3DMaterial.h in Headers */,
@ -5379,8 +5370,8 @@
15162214199E7A32006099B8 /* CCRay.h in Headers */,
15162215199E7A32006099B8 /* CCSkeleton3D.h in Headers */,
15162216199E7A32006099B8 /* CCAttachNode.h in Headers */,
15162217199E7A32006099B8 /* CCSubMesh.h in Headers */,
15162218199E7A32006099B8 /* CCSubMeshState.h in Headers */,
15162217199E7A32006099B8 /* CCMeshVertexIndexData.h in Headers */,
15162218199E7A32006099B8 /* CCMesh.h in Headers */,
15162219199E7A32006099B8 /* CCBundleReader.h in Headers */,
1516221A199E7A32006099B8 /* CCBundle3D.h in Headers */,
1516221B199E7A32006099B8 /* CCAnimate3D.h in Headers */,
@ -5388,7 +5379,6 @@
1516221C199E7A32006099B8 /* CCMeshSkin.h in Headers */,
1516221D199E7A32006099B8 /* CCAnimation3D.h in Headers */,
1516221E199E7A32006099B8 /* CCAnimationCurve.h in Headers */,
1516221F199E7A32006099B8 /* CCMesh.h in Headers */,
15162220199E7A32006099B8 /* CCObjLoader.h in Headers */,
15162221199E7A32006099B8 /* CCSprite3D.h in Headers */,
15162222199E7A32006099B8 /* CCSprite3DMaterial.h in Headers */,
@ -6913,14 +6903,13 @@
1516200E199E75C2006099B8 /* CCRay.cpp in Sources */,
1516200F199E75C2006099B8 /* CCSkeleton3D.cpp in Sources */,
15162010199E75C2006099B8 /* CCAttachNode.cpp in Sources */,
15162011199E75C2006099B8 /* CCSubMesh.cpp in Sources */,
15162012199E75C2006099B8 /* CCSubMeshState.cpp in Sources */,
15162011199E75C2006099B8 /* CCMeshVertexIndexData.cpp in Sources */,
15162012199E75C2006099B8 /* CCMesh.cpp in Sources */,
15162013199E75C2006099B8 /* CCBundleReader.cpp in Sources */,
15162014199E75C2006099B8 /* CCBundle3D.cpp in Sources */,
15162015199E75C2006099B8 /* CCAnimate3D.cpp in Sources */,
15162016199E75C2006099B8 /* CCMeshSkin.cpp in Sources */,
15162017199E75C2006099B8 /* CCAnimation3D.cpp in Sources */,
15162018199E75C2006099B8 /* CCMesh.cpp in Sources */,
15162019199E75C2006099B8 /* CCObjLoader.cpp in Sources */,
1516201A199E75C2006099B8 /* CCSprite3D.cpp in Sources */,
1516201B199E75C2006099B8 /* CCSprite3DMaterial.cpp in Sources */,
@ -6936,14 +6925,13 @@
15162204199E7874006099B8 /* CCRay.cpp in Sources */,
15162205199E7874006099B8 /* CCSkeleton3D.cpp in Sources */,
15162206199E7874006099B8 /* CCAttachNode.cpp in Sources */,
15162207199E7874006099B8 /* CCSubMesh.cpp in Sources */,
15162208199E7874006099B8 /* CCSubMeshState.cpp in Sources */,
15162207199E7874006099B8 /* CCMeshVertexIndexData.cpp in Sources */,
15162208199E7874006099B8 /* CCMesh.cpp in Sources */,
15162209199E7874006099B8 /* CCBundleReader.cpp in Sources */,
1516220A199E7874006099B8 /* CCBundle3D.cpp in Sources */,
1516220B199E7874006099B8 /* CCAnimate3D.cpp in Sources */,
1516220C199E7874006099B8 /* CCMeshSkin.cpp in Sources */,
1516220D199E7874006099B8 /* CCAnimation3D.cpp in Sources */,
1516220E199E7874006099B8 /* CCMesh.cpp in Sources */,
1516220F199E7874006099B8 /* CCObjLoader.cpp in Sources */,
15162210199E7874006099B8 /* CCSprite3D.cpp in Sources */,
15162211199E7874006099B8 /* CCSprite3DMaterial.cpp in Sources */,

View File

@ -961,7 +961,7 @@ public:
CC_DEPRECATED_ATTRIBUTE GLProgram* getShaderProgram() const { return getGLProgram(); }
GLProgramState *getGLProgramState() const;
void setGLProgramState(GLProgramState *glProgramState);
virtual void setGLProgramState(GLProgramState *glProgramState);
/**
* Sets the shader program for this node
@ -974,7 +974,7 @@ public:
*
* @param shaderProgram The shader program
*/
void setGLProgram(GLProgram *glprogram);
virtual void setGLProgram(GLProgram *glprogram);
CC_DEPRECATED_ATTRIBUTE void setShaderProgram(GLProgram *glprogram) { setGLProgram(glprogram); }
/// @} end of Shader Program

View File

@ -16,12 +16,11 @@ CCBundle3D.cpp \
CCBundleReader.cpp \
CCMesh.cpp \
CCMeshSkin.cpp \
CCMeshVertexIndexData.cpp \
CCSprite3DMaterial.cpp \
CCObjLoader.cpp \
CCSkeleton3D.cpp \
CCSprite3D.cpp \
CCSubMesh.cpp \
CCSubMeshState.cpp \
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/..

View File

@ -119,6 +119,11 @@ void AABB::reset()
_max.set(-99999.0f, -99999.0f, -99999.0f);
}
bool AABB::isEmpty() const
{
return _min.x > _max.x || _min.y > _max.y || _min.z > _max.z;
}
void AABB::updateMinMax(const Vec3* point, ssize_t num)
{
for (ssize_t i = 0; i < num; i++)

View File

@ -94,6 +94,8 @@ public:
* reset min and max value.
*/
void reset();
bool isEmpty() const;
/**
* update the _min and _max from the given point.

View File

@ -90,12 +90,12 @@ Animate3D* Animate3D::reverse() const
void Animate3D::startWithTarget(Node *target)
{
Sprite3D* sprite = dynamic_cast<Sprite3D*>(target);
CCASSERT(sprite && sprite->getSkin() && _animation, "Animate3D apply to Sprite3D only");
CCASSERT(sprite && sprite->getSkeleton() && _animation, "Animate3D apply to Sprite3D only");
ActionInterval::startWithTarget(target);
_boneCurves.clear();
auto skin = sprite->getSkin();
auto skin = sprite->getSkeleton();
for (unsigned int i = 0; i < skin->getBoneCount(); i++) {
auto bone = skin->getBoneByIndex(i);
auto curve = _animation->getBoneCurveByName(bone->getName());

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
#define __CCBUNDLE3D_H__
#include <map>
#include <list>
#include "3d/CCBundle3DData.h"
@ -90,28 +91,39 @@ public:
*/
virtual bool loadAnimationData(const std::string& id, Animation3DData* animationdata);
/**
* load skeleton data from bundle
*
*/
virtual bool loadSkeletonData(const std::string& id, Skeleton3DData* skeletondata);
//since 3.3, to support reskin
virtual bool loadMeshDatas(MeshDatas& meshdatas);
//since 3.3, to support reskin
virtual bool loadNodes(NodeDatas& nodedatas);
//since 3.3, to support reskin
virtual bool loadMaterials(MaterialDatas& materialdatas);
//load .obj file
static bool loadObj(MeshDatas& meshdatas, MaterialDatas& materialdatas, NodeDatas& nodedatas, const std::string& fullPath, const char* mtl_basepath = nullptr);
protected:
bool loadJson(const std::string& path);
bool loadMeshDataJson(MeshData* meshdata);
bool loadMeshDataJson_0_1(MeshData* meshdata);
bool loadMeshDataJson_0_2(MeshData* meshdata);
bool loadMeshDatasJson(MeshDatas& meshdatas);
bool loadMeshDataJson_0_1(MeshDatas& meshdatas);
bool loadMeshDataJson_0_2(MeshDatas& meshdatas);
bool loadMeshDatasBinary(MeshDatas& meshdatas);
bool loadMeshDatasBinary_0_1(MeshDatas& meshdatas);
bool loadMeshDatasBinary_0_2(MeshDatas& meshdatas);
bool loadMaterialsJson(MaterialDatas& materialdatas);
bool loadMaterialDataJson_0_1(MaterialDatas& materialdatas);
bool loadMaterialDataJson_0_2(MaterialDatas& materialdatas);
bool loadMaterialsBinary(MaterialDatas& materialdatas);
bool loadMaterialsBinary_0_1(MaterialDatas& materialdatas);
bool loadMaterialsBinary_0_2(MaterialDatas& materialdatas);
bool loadMeshDataJson(MeshData* meshdata){return true;}
bool loadMeshDataJson_0_1(MeshData* meshdata){return true;}
bool loadMeshDataJson_0_2(MeshData* meshdata){return true;}
bool loadSkinDataJson(SkinData* skindata);
bool loadMaterialDataJson(MaterialData* materialdata);
bool loadMaterialDataJson_0_1(MaterialData* materialdata);
bool loadMaterialDataJson_0_2(MaterialData* materialdata);
bool loadMaterialDataJson(MaterialData* materialdata){return true;}
bool loadMaterialDataJson_0_1(MaterialData* materialdata){return true;}
bool loadMaterialDataJson_0_2(MaterialData* materialdata){return true;}
bool loadAnimationDataJson(Animation3DData* animationdata);
/**
* load data in binary
* @param path The c3b file path
@ -144,12 +156,32 @@ protected:
*/
bool loadAnimationDataBinary(Animation3DData* animationdata);
bool checkIsBone(const std::string& name);
/**
* load nodes of json
*/
bool loadNodesJson(NodeDatas& nodedatas);
NodeData* parseNodesRecursivelyJson(const rapidjson::Value& jvalue);
/**
* load nodes of binary
*/
bool loadNodesBinary(NodeDatas& nodedatas);
NodeData* parseNodesRecursivelyBinary(bool& skeleton);
/**
* get define data type
* @param str The type in string
*/
GLenum parseGLType(const std::string& str);
/**
* get define data type
* @param str The type in string
*/
NTextureData::Usage parseGLTextureType(const std::string& str);
/**
* get vertex attribute type
* @param str The type in string
@ -176,7 +208,7 @@ protected:
static Bundle3D* _instance;
std::string _modelRelativePath;
std::string _modelPath;
std::string _path;
std::string _version;// the c3b or c3t version
@ -190,7 +222,6 @@ protected:
BundleReader _binaryReader;
unsigned int _referenceCount;
Reference* _references;
bool _isBinary;
};

View File

@ -47,6 +47,73 @@ struct MeshVertexAttrib
int attribSizeBytes;
};
struct ModelData;
/** Node data, since 3.3 */
struct NodeData
{
std::string id;
Mat4 transform;
std::vector<ModelData*> modelNodeDatas;
std::vector<NodeData*> children;
virtual ~NodeData()
{
resetData();
}
virtual void resetData()
{
id.clear();
transform.setIdentity();
for (auto& it : children)
{
delete it;
}
children.clear();
}
};
/** model node data, since 3.3 */
struct ModelData
{
std::string subMeshId;
std::string matrialId;
std::vector<std::string> bones;
std::vector<Mat4> invBindPose;
virtual ~ModelData()
{
resetData();
}
virtual void resetData()
{
bones.clear();
invBindPose.clear();
}
};
/** node datas, since 3.3 */
struct NodeDatas
{
std::vector<NodeData*> skeleton; //skeleton
std::vector<NodeData*> nodes; // nodes, CCNode, Sprite3D or part of Sprite3D
void resetData()
{
for(auto& it : skeleton)
{
delete it;
}
skeleton.clear();
for(auto& it : nodes)
{
delete it;
}
nodes.clear();
}
};
/**mesh data*/
struct MeshData
{
@ -54,11 +121,21 @@ struct MeshData
std::vector<float> vertex;
int vertexSizeInFloat;
std::vector<IndexArray> subMeshIndices;
std::vector<std::string> subMeshIds; //subMesh Names (since 3.3)
int numIndex;
std::vector<MeshVertexAttrib> attribs;
int attribCount;
public:
int getPerVertexSize() const
{
int vertexsize = 0;
for(const auto& attrib : attribs)
{
vertexsize += attrib.attribSizeBytes;
}
return vertexsize;
}
void resetData()
{
vertex.clear();
@ -80,6 +157,25 @@ public:
}
};
/** mesh datas */
struct MeshDatas
{
std::vector<MeshData*> meshDatas;
void resetData()
{
for(auto& it : meshDatas)
{
delete it;
}
meshDatas.clear();
}
~MeshDatas()
{
resetData();
}
};
/**skin data*/
struct SkinData
{
@ -149,47 +245,7 @@ struct SkinData
};
/**skin data*/
struct Skeleton3DData
{
std::vector<std::string> boneNames; //bone names
std::vector<Mat4> inverseBindPoseMatrices; //bind pose of skin bone
std::vector<Mat4> boneOriginMatrices; // original bone transform
//bone child info, both skinbone and node bone
std::map<int, std::vector<int> > boneChild;//key parent, value child
int rootBoneIndex;
void resetData()
{
boneNames.clear();
inverseBindPoseMatrices.clear();
boneOriginMatrices.clear();
boneChild.clear();
rootBoneIndex = -1;
}
void addBoneNames(const std::string& name)
{
auto it = std::find(boneNames.begin(), boneNames.end(), name);
if (it == boneNames.end())
boneNames.push_back(name);
}
int getBoneNameIndex(const std::string& name)const
{
int i = 0;
for (auto iter : boneNames)
{
if ((iter) == name)
return i;
i++;
}
return -1;
}
};
/**material data*/
/**material data, */
struct MaterialData
{
std::map<int, std::string> texturePaths; //submesh id, texture path
@ -199,6 +255,61 @@ struct MaterialData
}
};
/**new material, since 3.3 */
struct NTextureData
{
enum class Usage {
Unknown = 0,
None = 1,
Diffuse = 2,
Emissive = 3,
Ambient = 4,
Specular = 5,
Shininess = 6,
Normal = 7,
Bump = 8,
Transparency = 9,
Reflection = 10
};
std::string id;
std::string filename;
Usage type;
GLenum wrapS;
GLenum wrapT;
} ;
struct NMaterialData
{
std::vector<NTextureData> textures;
std::string id;
const NTextureData* getTextureData(const NTextureData::Usage& type) const
{
for(const auto& it : textures)
{
if (it.type == type)
return &it;
}
return nullptr;
}
};
/** material datas, since 3.3 */
struct MaterialDatas
{
std::vector<NMaterialData> materials;
void resetData()
{
materials.clear();
}
const NMaterialData* getMaterialData(const std::string& materialid) const
{
for(const auto& it : materials)
{
if (it.id == materialid)
return &it;
}
return nullptr;
}
};
/**animation data*/
struct Animation3DData
{

View File

@ -22,16 +22,14 @@
THE SOFTWARE.
****************************************************************************/
#include "CCMesh.h"
#include <list>
#include <fstream>
#include <iostream>
#include <sstream>
#include "3d/CCSubMesh.h"
#include "3d/CCObjLoader.h"
#include "3d/CCSprite3DMaterial.h"
#include "3d/CCMesh.h"
#include "3d/CCMeshSkin.h"
#include "3d/CCMeshVertexIndexData.h"
#include "base/ccMacros.h"
#include "base/CCEventCustom.h"
@ -40,347 +38,263 @@
#include "base/CCEventType.h"
#include "base/CCDirector.h"
#include "renderer/ccGLStateCache.h"
#include "renderer/CCTexture2D.h"
#include "renderer/CCTextureCache.h"
#include "renderer/CCGLProgramCache.h"
using namespace std;
NS_CC_BEGIN
bool RenderMeshData::hasVertexAttrib(int attrib)
{
for (auto itr = _vertexAttribs.begin(); itr != _vertexAttribs.end(); itr++)
{
if ((*itr).vertexAttrib == attrib)
return true; //already has
}
return false;
}
bool RenderMeshData::init(const std::vector<float>& positions,
const std::vector<float>& normals,
const std::vector<float>& texs,
const std::vector<IndexArray>& indices)
{
CC_ASSERT(positions.size()<65536 * 3 && "index may out of bound");
_vertexAttribs.clear();
_vertexNum = positions.size() / 3; //number of vertex
if (_vertexNum == 0)
return false;
if ((normals.size() != 0 && _vertexNum * 3 != normals.size()) || (texs.size() != 0 && _vertexNum * 2 != texs.size()))
return false;
MeshVertexAttrib meshvertexattrib;
meshvertexattrib.size = 3;
meshvertexattrib.type = GL_FLOAT;
meshvertexattrib.attribSizeBytes = meshvertexattrib.size * sizeof(float);
meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_POSITION;
_vertexAttribs.push_back(meshvertexattrib);
//normal
if (normals.size())
{
//add normal flag
meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_NORMAL;
_vertexAttribs.push_back(meshvertexattrib);
}
//
if (texs.size())
{
meshvertexattrib.size = 2;
meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_TEX_COORD;
meshvertexattrib.attribSizeBytes = meshvertexattrib.size * sizeof(float);
_vertexAttribs.push_back(meshvertexattrib);
}
_vertexs.clear();
_vertexsizeBytes = calVertexSizeBytes();
_vertexs.reserve(_vertexNum * _vertexsizeBytes / sizeof(float));
bool hasNormal = hasVertexAttrib(GLProgram::VERTEX_ATTRIB_NORMAL);
bool hasTexCoord = hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD);
//position, normal, texCoordinate into _vertexs
for(int i = 0; i < _vertexNum; i++)
{
_vertexs.push_back(positions[i * 3]);
_vertexs.push_back(positions[i * 3 + 1]);
_vertexs.push_back(positions[i * 3 + 2]);
if (hasNormal)
{
_vertexs.push_back(normals[i * 3]);
_vertexs.push_back(normals[i * 3 + 1]);
_vertexs.push_back(normals[i * 3 + 2]);
}
if (hasTexCoord)
{
_vertexs.push_back(texs[i * 2]);
_vertexs.push_back(texs[i * 2 + 1]);
}
}
_subMeshIndices = indices;
return true;
}
bool RenderMeshData::init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& attribs)
{
_vertexs = vertices;
_subMeshIndices = indices;
_vertexAttribs = attribs;
_vertexsizeBytes = calVertexSizeBytes();
return true;
}
int RenderMeshData::calVertexSizeBytes()
{
int sizeBytes = 0;
for (auto it = _vertexAttribs.begin(); it != _vertexAttribs.end(); it++) {
sizeBytes += (*it).size;
CCASSERT((*it).type == GL_FLOAT, "use float");
}
sizeBytes *= sizeof(float);
return sizeBytes;
}
Mesh::Mesh()
:_vertexBuffer(0)
: _visible(true)
, _texture(nullptr)
, _skin(nullptr)
, _meshIndexData(nullptr)
, _visibleChanged(nullptr)
, _glProgramState(nullptr)
, _blend(BlendFunc::ALPHA_NON_PREMULTIPLIED)
{
}
Mesh::~Mesh()
{
_subMeshes.clear();
cleanAndFreeBuffers();
CC_SAFE_RELEASE(_texture);
CC_SAFE_RELEASE(_skin);
CC_SAFE_RELEASE(_meshIndexData);
CC_SAFE_RELEASE(_glProgramState);
}
GLuint Mesh::getVertexBuffer() const
{
return _meshIndexData->getVertexBuffer()->getVBO();
}
bool Mesh::hasVertexAttrib(int attrib) const
{
return _meshIndexData->getMeshVertexData()->hasVertexAttrib(attrib);
}
ssize_t Mesh::getMeshVertexAttribCount() const
{
return _meshIndexData->getMeshVertexData()->getMeshVertexAttribCount();
}
const MeshVertexAttrib& Mesh::getMeshVertexAttribute(int idx)
{
return _meshIndexData->getMeshVertexData()->getMeshVertexAttrib(idx);
}
int Mesh::getVertexSizeInBytes() const
{
return _meshIndexData->getVertexBuffer()->getSizePerVertex();
}
Mesh* Mesh::create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const IndexArray& indices)
{
std::vector<IndexArray> submeshIndices;
submeshIndices.push_back(indices);
return create(positions, normals, texs, submeshIndices);
}
Mesh* Mesh::create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& indices)
{
auto mesh = new Mesh();
if(mesh && mesh->init(positions, normals, texs, indices))
int perVertexSizeInFloat = 0;
std::vector<float> vertices;
std::vector<MeshVertexAttrib> attribs;
MeshVertexAttrib att;
att.size = 3;
att.type = GL_FLOAT;
att.attribSizeBytes = att.size * sizeof(float);
if (positions.size())
{
mesh->autorelease();
return mesh;
perVertexSizeInFloat += 3;
att.vertexAttrib = GLProgram::VERTEX_ATTRIB_POSITION;
attribs.push_back(att);
}
CC_SAFE_DELETE(mesh);
return nullptr;
}
Mesh* Mesh::create(const std::vector<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& attribs)
{
std::vector<IndexArray> submeshIndices;
submeshIndices.push_back(indices);
return create(vertices, vertexSizeInFloat, submeshIndices, attribs);
}
Mesh* Mesh::create(const std::vector<float> &vertices, int vertexSizeInFloat, const std::vector<IndexArray> &indices, const std::vector<MeshVertexAttrib> &attribs)
{
auto mesh = new Mesh();
if (mesh && mesh->init(vertices, vertexSizeInFloat, indices, attribs))
if (normals.size())
{
mesh->autorelease();
return mesh;
perVertexSizeInFloat += 3;
att.vertexAttrib = GLProgram::VERTEX_ATTRIB_NORMAL;
attribs.push_back(att);
}
CC_SAFE_DELETE(mesh);
return nullptr;
}
bool Mesh::init(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& indices)
{
bool bRet = _renderdata.init(positions, normals, texs, indices);
if (!bRet)
return false;
buildSubMeshes();
buildBuffer();
calOriginAABB(positions, 3);
return true;
}
bool Mesh::init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& attribs)
{
bool bRet = _renderdata.init(vertices, vertexSizeInFloat, indices, attribs);
if (!bRet)
return false;
buildSubMeshes();
buildBuffer();
unsigned int perVertexSize = _renderdata.calVertexSizeBytes() / sizeof(float);
calOriginAABB(vertices, perVertexSize);
return true;
}
void Mesh::buildSubMeshes()
{
_subMeshes.clear();
for (auto& it : _renderdata._subMeshIndices) {
auto subMesh = SubMesh::create(PrimitiveType::TRIANGLES, IndexFormat::INDEX16, it);
_subMeshes.pushBack(subMesh);
}
}
void Mesh::cleanAndFreeBuffers()
{
if(glIsBuffer(_vertexBuffer))
if (texs.size())
{
glDeleteBuffers(1, &_vertexBuffer);
_vertexBuffer = 0;
perVertexSizeInFloat += 2;
att.vertexAttrib = GLProgram::VERTEX_ATTRIB_TEX_COORD;
att.size = 2;
att.attribSizeBytes = att.size * sizeof(float);
attribs.push_back(att);
}
for (auto& it : _subMeshes) {
(*it).cleanAndFreeBuffers();
}
}
void Mesh::calOriginAABB(const std::vector<float>& vertices, unsigned int stride)
{
ssize_t vertexNum = vertices.size() / stride;
for(unsigned int i = 0; i < vertexNum; i++)
bool hasNormal = (normals.size() != 0);
bool hasTexCoord = (texs.size() != 0);
//position, normal, texCoordinate into _vertexs
size_t vertexNum = positions.size() / 3;
for(size_t i = 0; i < vertexNum; i++)
{
Vec3 point = Vec3(vertices[i * stride], vertices[i * stride + 1], vertices[i * stride + 2]);
_originAABB.updateMinMax(&point, 1);
}
}
vertices.push_back(positions[i * 3]);
vertices.push_back(positions[i * 3 + 1]);
vertices.push_back(positions[i * 3 + 2]);
void Mesh::buildBuffer()
{
cleanAndFreeBuffers();
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,
_renderdata._vertexs.size() * sizeof(_renderdata._vertexs[0]),
&_renderdata._vertexs[0],
GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
for (size_t i = 0; i < _subMeshes.size(); i++) {
_subMeshes.at(i)->buildBuffer(_renderdata._subMeshIndices[i]);
}
}
void Mesh::restore()
{
_vertexBuffer = 0;
for (auto& it : _subMeshes) {
it->_indexBuffer = 0;
}
buildBuffer();
}
const AABB& Mesh::getOriginAABB() const
{
return _originAABB;
}
/**
* MeshCache
*/
MeshCache* MeshCache::_cacheInstance = nullptr;
MeshCache* MeshCache::getInstance()
{
if (_cacheInstance == nullptr)
_cacheInstance = new MeshCache();
return _cacheInstance;
}
void MeshCache::destroyInstance()
{
if (_cacheInstance)
CC_SAFE_DELETE(_cacheInstance);
}
Mesh* MeshCache::getMesh(const std::string& key) const
{
auto it = _meshes.find(key);
if (it != _meshes.end())
return it->second;
return nullptr;
}
bool MeshCache::addMesh(const std::string& key, Mesh* mesh)
{
auto it = _meshes.find(key);
if (it == _meshes.end())
{
mesh->retain();
_meshes[key] = mesh;
return true;
}
return false;
}
void MeshCache::removeAllMeshes()
{
for (auto it : _meshes) {
CC_SAFE_RELEASE(it.second);
}
_meshes.clear();
}
void MeshCache::removeUnusedMesh()
{
for( auto it=_meshes.cbegin(); it!=_meshes.cend(); /* nothing */) {
if(it->second->getReferenceCount() == 1)
if (hasNormal)
{
it->second->release();
_meshes.erase(it++);
vertices.push_back(normals[i * 3]);
vertices.push_back(normals[i * 3 + 1]);
vertices.push_back(normals[i * 3 + 2]);
}
if (hasTexCoord)
{
vertices.push_back(texs[i * 2]);
vertices.push_back(texs[i * 2 + 1]);
}
else
++it;
}
return create(vertices, perVertexSizeInFloat, indices, attribs);
}
MeshCache::MeshCache()
Mesh* Mesh::create(const std::vector<float>& vertices, int perVertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& attribs)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
// listen the event that renderer was recreated on Android/WP8
_rendererRecreatedListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, CC_CALLBACK_1(MeshCache::listenRendererRecreated, this));
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_rendererRecreatedListener, -1);
#endif
}
MeshCache::~MeshCache()
{
removeAllMeshes();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
Director::getInstance()->getEventDispatcher()->removeEventListener(_rendererRecreatedListener);
#endif
MeshData meshdata;
meshdata.attribs = attribs;
meshdata.vertex = vertices;
meshdata.subMeshIndices.push_back(indices);
meshdata.subMeshIds.push_back("");
auto meshvertexdata = MeshVertexData::create(meshdata);
auto indexbuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, (int)indices.size());
AABB aabb = MeshVertexData::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), indices);
auto indexData = MeshIndexData::create("", meshvertexdata, indexbuffer, aabb);
return create("", indexData);
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
void MeshCache::listenRendererRecreated(EventCustom* event)
Mesh* Mesh::create(const std::string& name, MeshIndexData* indexData, MeshSkin* skin)
{
for (auto iter = _meshes.begin(); iter != _meshes.end(); ++iter)
auto state = new Mesh();
state->autorelease();
state->bindMeshCommand();
state->_name = name;
state->setMeshIndexData(indexData);
state->setSkin(skin);
return state;
}
void Mesh::setVisible(bool visible)
{
if (_visible != visible)
{
auto mesh = iter->second;
mesh->restore();
_visible = visible;
if (_visibleChanged)
_visibleChanged();
}
}
#endif
void Mesh::setTexture(const std::string& texPath)
{
auto tex = Director::getInstance()->getTextureCache()->addImage(texPath);
setTexture(tex);
}
void Mesh::setTexture(Texture2D* tex)
{
if (tex != _texture)
{
CC_SAFE_RETAIN(tex);
CC_SAFE_RELEASE(_texture);
_texture = tex;
bindMeshCommand();
}
}
void Mesh::setSkin(MeshSkin* skin)
{
if (_skin != skin)
{
CC_SAFE_RETAIN(skin);
CC_SAFE_RELEASE(_skin);
_skin = skin;
calcuateAABB();
}
}
void Mesh::setMeshIndexData(MeshIndexData* subMesh)
{
if (_meshIndexData != subMesh)
{
CC_SAFE_RETAIN(subMesh);
CC_SAFE_RELEASE(_meshIndexData);
_meshIndexData = subMesh;
calcuateAABB();
bindMeshCommand();
}
}
void Mesh::setGLProgramState(GLProgramState* glProgramState)
{
if (_glProgramState != glProgramState)
{
CC_SAFE_RETAIN(glProgramState);
CC_SAFE_RELEASE(_glProgramState);
_glProgramState = glProgramState;
bindMeshCommand();
}
}
void Mesh::calcuateAABB()
{
if (_meshIndexData)
{
_aabb = _meshIndexData->getAABB();
if (_skin)
{
Bone3D* root = _skin->getRootBone();
if (root)
{
_aabb.transform(root->getWorldMat());
}
}
}
}
void Mesh::bindMeshCommand()
{
if (_glProgramState && _meshIndexData && _texture)
{
GLuint texID = _texture ? _texture->getName() : 0;
_meshCommand.genMaterialID(texID, _glProgramState, _meshIndexData->getVertexBuffer()->getVBO(), _meshIndexData->getIndexBuffer()->getVBO(), _blend);
_meshCommand.setCullFaceEnabled(true);
_meshCommand.setDepthTestEnabled(true);
}
}
void Mesh::setBlendFunc(const BlendFunc &blendFunc)
{
if(_blend.src != blendFunc.src || _blend.dst != blendFunc.dst)
{
_blend = blendFunc;
bindMeshCommand();
}
}
const BlendFunc &Mesh::getBlendFunc() const
{
return _blend;
}
GLenum Mesh::getPrimitiveType() const
{
return _meshIndexData->getPrimitiveType();
}
ssize_t Mesh::getIndexCount() const
{
return _meshIndexData->getIndexBuffer()->getIndexNumber();
}
GLenum Mesh::getIndexFormat() const
{
return GL_UNSIGNED_SHORT;
}
GLuint Mesh::getIndexBuffer() const
{
return _meshIndexData->getIndexBuffer()->getVBO();
}
NS_CC_END

View File

@ -29,190 +29,122 @@
#include <vector>
#include "3d/CCBundle3DData.h"
#include "3d/CCSubMesh.h"
#include "3d/CCAABB.h"
#include "3d/3dExport.h"
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "base/CCVector.h"
#include "math/CCMath.h"
#include "renderer/CCGLProgram.h"
#include "CCAABB.h"
#include "3d/3dExport.h"
#include "renderer/CCGLProgramState.h"
#include "renderer/CCMeshCommand.h"
NS_CC_BEGIN
class EventListenerCustom;
class EventCustom;
class CC_3D_DLL RenderMeshData
{
typedef std::vector<unsigned short> IndexArray;
friend class Mesh;
public:
RenderMeshData(): _vertexsizeBytes(0)
{
}
bool hasVertexAttrib(int attrib);
bool init(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& subMeshIndices);
bool init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& subMeshIndices, const std::vector<MeshVertexAttrib>& attribs);
protected:
int calVertexSizeBytes();
int _vertexsizeBytes;
ssize_t _vertexNum;
std::vector<float> _vertexs;
std::vector<IndexArray> _subMeshIndices;
std::vector<MeshVertexAttrib> _vertexAttribs;
};
class Texture2D;
class MeshSkin;
class MeshIndexData;
/**
* Mesh: Geometry with a collection of vertex.
* Supporting various vertex formats.
* Mesh: contains ref to index buffer, GLProgramState, texture, skin, blend function, aabb and so on
*/
class CC_3D_DLL Mesh : public Ref
{
typedef std::vector<unsigned short> IndexArray;
friend class Sprite3D;
public:
typedef std::vector<unsigned short> IndexArray;
/**create mesh from positions, normals, and so on, sigle SubMesh*/
static Mesh* create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const IndexArray& indices);
/**create mesh from positions, normals, and so on, multi-SubMesh*/
static Mesh* create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& subMeshIndices);
/**create mesh with vertex attributes*/
CC_DEPRECATED_ATTRIBUTE static Mesh* create(const std::vector<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, int numIndex, const std::vector<MeshVertexAttrib>& attribs, int attribCount) { return create(vertices, vertexSizeInFloat, indices, attribs); }
CC_DEPRECATED_ATTRIBUTE static Mesh* create(const std::vector<float>& vertices, int perVertexSizeInFloat, const IndexArray& indices, int numIndex, const std::vector<MeshVertexAttrib>& attribs, int attribCount){ return create(vertices, perVertexSizeInFloat, indices, attribs); }
/**
* create Mesh
* @param vertices vertices buffer data
* @param vertexSizeInFloat size of each vertex
* @param indices index buffer data that denotes how to connect the vertex, sigle SubMesh
* @param attribs vertex attributes
*/
static Mesh* create(const std::vector<float>& vertices, int vertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& attribs);
static Mesh* create(const std::vector<float>& vertices, int perVertexSizeInFloat, const IndexArray& indices, const std::vector<MeshVertexAttrib>& attribs);
/** create mesh */
static Mesh* create(const std::string& name, MeshIndexData* indexData, MeshSkin* skin = nullptr);
/**
* create Mesh
* @param vertices vertices buffer data
* @param vertexSizeInFloat size of each vertex
* @param subMeshIndices index buffer data that denotes how to connect the vertex, multi-SubMesh
* @param attribs vertex attributes
*/
static Mesh* create(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& subMeshIndices, const std::vector<MeshVertexAttrib>& attribs);
/**get vertex buffer*/
inline GLuint getVertexBuffer() const { return _vertexBuffer; }
/**get mesh vertex attribute count*/
ssize_t getMeshVertexAttribCount() const { return _renderdata._vertexAttribs.size(); }
/**get MeshVertexAttribute by index*/
const MeshVertexAttrib& getMeshVertexAttribute(int idx) const { return _renderdata._vertexAttribs[idx]; }
GLuint getVertexBuffer() const;
/**has vertex attribute?*/
bool hasVertexAttrib(int attrib) { return _renderdata.hasVertexAttrib(attrib); }
bool hasVertexAttrib(int attrib) const;
/**get mesh vertex attribute count*/
ssize_t getMeshVertexAttribCount() const;
/**get MeshVertexAttribute by index*/
const MeshVertexAttrib& getMeshVertexAttribute(int idx);
/**get per vertex size in bytes*/
int getVertexSizeInBytes() const { return _renderdata._vertexsizeBytes; }
int getVertexSizeInBytes() const;
/**texture getter and setter*/
void setTexture(const std::string& texPath);
void setTexture(Texture2D* tex);
Texture2D* getTexture() const { return _texture; }
/**get sub mesh count*/
ssize_t getSubMeshCount() const { return _subMeshes.size(); }
/**visible getter and setter*/
void setVisible(bool visible);
bool isVisible() const { return _visible; }
/**get sub mesh by index*/
SubMesh* getSubMesh(int index) const { return _subMeshes.at(index); }
/**skin getter */
MeshSkin* getSkin() const { return _skin; }
/**build vertex buffer from renderdata*/
void restore();
/**mesh index data getter */
MeshIndexData* getMeshIndexData() const { return _meshIndexData; }
/** get origin aabb that calculate from vertices*/
const AABB& getOriginAABB() const;
/**get GLProgramState*/
GLProgramState* getGLProgramState() const { return _glProgramState; }
/**name getter */
const std::string& getName() const { return _name; }
void setBlendFunc(const BlendFunc &blendFunc);
const BlendFunc &getBlendFunc() const;
/**to be deprecated, those functions have been moved to SubMesh*/
/** get primitive type*/
CC_DEPRECATED_ATTRIBUTE PrimitiveType getPrimitiveType() const { return _subMeshes.at(0)->getPrimitiveType(); }
GLenum getPrimitiveType() const;
/**get index count*/
CC_DEPRECATED_ATTRIBUTE ssize_t getIndexCount() const { return _subMeshes.at(0)->getIndexCount(); }
ssize_t getIndexCount() const;
/**get index format*/
CC_DEPRECATED_ATTRIBUTE IndexFormat getIndexFormat() const { return _subMeshes.at(0)->getIndexFormat(); }
GLenum getIndexFormat() const;
/**get index buffer*/
CC_DEPRECATED_ATTRIBUTE GLuint getIndexBuffer() const {return _subMeshes.at(0)->getIndexBuffer(); }
GLuint getIndexBuffer() const;
/**get AABB*/
const AABB& getAABB() const { return _aabb; }
CC_CONSTRUCTOR_ACCESS:
Mesh();
virtual ~Mesh();
/**init mesh*/
bool init(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<IndexArray>& indices);
/**init mesh*/
bool init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<IndexArray>& indices, const std::vector<MeshVertexAttrib>& attribs);
/**build sub meshes*/
void buildSubMeshes();
/**build buffer*/
void buildBuffer();
/**free buffer*/
void cleanAndFreeBuffers();
GLProgram* getDefaultGLProgram(bool textured);
/*
* calculate AABB by origin vertices
* @param the vertices list
* @param stride the stride between two vertex's position data.
*/
void calOriginAABB(const std::vector<float>& vertices, unsigned int stride);
void setGLProgramState(GLProgramState* glProgramState);
MeshCommand& getMeshCommand() { return _meshCommand; }
/**skin setter*/
void setSkin(MeshSkin* skin);
/**Mesh index data setter*/
void setMeshIndexData(MeshIndexData* indexdata);
/**name setter*/
void setName(const std::string& name) { _name = name; }
void calcuateAABB();
void bindMeshCommand();
protected:
GLuint _vertexBuffer;
Vector<SubMesh*> _subMeshes;
RenderMeshData _renderdata;
Texture2D* _texture; //texture that submesh is using
MeshSkin* _skin; //skin
bool _visible; // is the submesh visible
AABB _originAABB;
};
/**
* Mesh Cache
*/
class MeshCache
{
public:
/**get & destroy*/
static MeshCache* getInstance();
static void destroyInstance();
/**get mesh from cache*/
Mesh* getMesh(const std::string& key) const;
/**add mesh to cache*/
bool addMesh(const std::string& key, Mesh* mesh);
/**remove all meshes*/
void removeAllMeshes();
/**remove unused meshes*/
void removeUnusedMesh();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
void listenRendererRecreated(EventCustom* event);
#endif
CC_CONSTRUCTOR_ACCESS:
MeshCache();
~MeshCache();
protected:
static MeshCache* _cacheInstance;//instance
std::unordered_map<std::string, Mesh*> _meshes; //cached meshes
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
EventListenerCustom* _rendererRecreatedListener;
#endif
//since 3.3
std::string _name;
MeshIndexData* _meshIndexData;
GLProgramState* _glProgramState;
MeshCommand _meshCommand;
BlendFunc _blend;
AABB _aabb;
std::function<void()> _visibleChanged;
};
NS_CC_END
#endif // __CCMESH_H_
#endif // __CCMESH_H__

View File

@ -37,6 +37,7 @@ static int PALETTE_ROWS = 3;
MeshSkin::MeshSkin()
: _rootBone(nullptr)
, _matrixPalette(nullptr)
, _skeleton(nullptr)
{
}
@ -47,77 +48,26 @@ MeshSkin::~MeshSkin()
CC_SAFE_RELEASE(_skeleton);
}
MeshSkin* MeshSkin::create(Skeleton3D* skeleton, const std::string& filename, const std::string& name)
MeshSkin* MeshSkin::create(Skeleton3D* skeleton, const std::vector<std::string>& boneNames, const std::vector<Mat4>& invBindPose)
{
//load skin here;
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
std::string key = fullPath + "#" + name;
const auto skindata = MeshSkinDataCache::getInstance()->getMeshSkinData(key);
if (skindata)
{
auto skin = new MeshSkin();
skin->_skeleton = skeleton;
skeleton->retain();
skin->initFromSkinData(*skindata);
skin->autorelease();
return skin;
}
else
{
auto instance = Bundle3D::getInstance();
bool ret = instance->load(fullPath);
if (ret)
{
SkinData data;
if (instance->loadSkinData(name, &data))
{
auto skin = new MeshSkin();
skin->_skeleton = skeleton;
skeleton->retain();
skin->initFromSkinData(data);
skin->autorelease();
MeshSkinDataCache::getInstance()->addMeshSkinData(key, data);
return skin;
}
}
}
auto skin = new MeshSkin();
skin->_skeleton = skeleton;
skeleton->retain();
return nullptr;
}
bool MeshSkin::initFromSkinData(const SkinData& skindata)
{
ssize_t i = 0;
for (; i < skindata.skinBoneNames.size(); i++) {
auto bone = Bone3D::create(skindata.skinBoneNames[i]);
bone->_invBindPose = skindata.inverseBindPoseMatrices[i];
bone->setOriPose(skindata.skinBoneOriginMatrices[i]);
_invBindPoses.push_back(skindata.inverseBindPoseMatrices[i]);
addSkinBone(bone);
}
for (i = 0; i < skindata.nodeBoneNames.size(); i++) {
auto bone = Bone3D::create(skindata.nodeBoneNames[i]);
bone->setOriPose(skindata.nodeBoneOriginMatrices[i]);
addNodeBone(bone);
}
for (auto it : skindata.boneChild) {
auto parent = getBoneByIndex(it.first);
for (auto childIt : it.second) {
auto child = getBoneByIndex(childIt);
child->_parent = parent;
parent->_children.pushBack(child);
}
CCASSERT(boneNames.size() == invBindPose.size(), "bone names' num should equals to invBindPose's num");
for (const auto& it : boneNames) {
auto bone = skeleton->getBoneByName(it);
skin->addSkinBone(bone);
}
skin->_invBindPoses = invBindPose;
skin->autorelease();
setRootBone(getBoneByIndex(skindata.rootBoneIndex));
_rootBone->resetPose();
return true;
return skin;
}
ssize_t MeshSkin::getBoneCount() const
{
return _skinBones.size() + _nodeBones.size();
return _skinBones.size();
}
//get bone
@ -125,9 +75,6 @@ Bone3D* MeshSkin::getBoneByIndex(unsigned int index) const
{
if (index < _skinBones.size())
return _skinBones.at(index);
index -= _skinBones.size();
if (index < _nodeBones.size())
return _nodeBones.at(index);
return nullptr;
}
@ -138,25 +85,9 @@ Bone3D* MeshSkin::getBoneByName(const std::string& id) const
if (it->getName() == id)
return it;
}
//search from node bones
for (const auto& it : _nodeBones) {
if (it->getName() == id )
return it;
}
return nullptr;
}
Bone3D* MeshSkin::getRootBone() const
{
return _rootBone;
}
void MeshSkin::setRootBone(Bone3D* joint)
{
CC_SAFE_RETAIN(joint);
CC_SAFE_RELEASE(_rootBone);
_rootBone = joint;
}
int MeshSkin::getBoneIndex(Bone3D* bone) const
{
int i = 0;
@ -164,19 +95,13 @@ int MeshSkin::getBoneIndex(Bone3D* bone) const
if (_skinBones.at(i) == bone)
return i;
}
int index = 0;
for (; index < _nodeBones.size(); index++, i++) {
if (_nodeBones.at(index) == bone)
return i;
}
return -1;
}
//compute matrix palette used by gpu skin
Vec4* MeshSkin::getMatrixPalette()
{
updateBoneMatrix();
if (_matrixPalette == nullptr)
{
_matrixPalette = new Vec4[_skinBones.size() * PALETTE_ROWS];
@ -199,17 +124,9 @@ ssize_t MeshSkin::getMatrixPaletteSize() const
return _skinBones.size() * PALETTE_ROWS;
}
//refresh bone world matrix
void MeshSkin::updateBoneMatrix()
{
_rootBone->setWorldMatDirty(true);
_rootBone->updateWorldMat();
}
void MeshSkin::removeAllBones()
{
_skinBones.clear();
_nodeBones.clear();
CC_SAFE_DELETE_ARRAY(_matrixPalette);
CC_SAFE_RELEASE(_rootBone);
}
@ -219,59 +136,17 @@ void MeshSkin::addSkinBone(Bone3D* bone)
_skinBones.pushBack(bone);
}
void MeshSkin::addNodeBone(Bone3D* bone)
Bone3D* MeshSkin::getRootBone() const
{
_nodeBones.pushBack(bone);
}
////////////////////////////////////////////////////////////////////////
MeshSkinDataCache* MeshSkinDataCache::_cacheInstance = nullptr;
MeshSkinDataCache* MeshSkinDataCache::getInstance()
{
if (_cacheInstance == nullptr)
_cacheInstance = new MeshSkinDataCache();
return _cacheInstance;
}
void MeshSkinDataCache::destroyInstance()
{
if (_cacheInstance)
Bone3D* root = nullptr;
if (_skinBones.size())
{
CC_SAFE_DELETE(_cacheInstance);
root = _skinBones.at(0);
while (root->getParentBone()) {
root = root->getParentBone();
}
}
}
const SkinData* MeshSkinDataCache::getMeshSkinData(const std::string& key) const
{
auto it = _skinDatas.find(key);
if (it != _skinDatas.end())
return &it->second;
return nullptr;
}
bool MeshSkinDataCache::addMeshSkinData(const std::string& key, const SkinData& skin)
{
if (_skinDatas.find(key) != _skinDatas.end())
return false; // already have this key
_skinDatas[key] = skin;
return true;
}
void MeshSkinDataCache::removeAllMeshSkinData()
{
_skinDatas.clear();
}
MeshSkinDataCache::MeshSkinDataCache()
{
}
MeshSkinDataCache::~MeshSkinDataCache()
{
return root;
}
NS_CC_END

View File

@ -53,6 +53,8 @@ public:
/**create a new meshskin if do not want to share meshskin*/
static MeshSkin* create(Skeleton3D* skeleton, const std::string& filename, const std::string& name);
static MeshSkin* create(Skeleton3D* skeleton, const std::vector<std::string>& boneNames, const std::vector<Mat4>& invBindPose);
/**get total bone count, skin bone + node bone*/
ssize_t getBoneCount() const;
@ -60,10 +62,6 @@ public:
Bone3D* getBoneByIndex(unsigned int index) const;
Bone3D* getBoneByName(const std::string& id) const;
/**get & set root bone*/
Bone3D* getRootBone() const;
void setRootBone(Bone3D* bone);
/**get bone index*/
int getBoneIndex(Bone3D* bone) const;
@ -73,8 +71,8 @@ public:
/**getSkinBoneCount() * 3*/
ssize_t getMatrixPaletteSize() const;
/**refresh bone world matrix*/
void updateBoneMatrix();
/**get root bone of the skin*/
Bone3D* getRootBone() const;
CC_CONSTRUCTOR_ACCESS:
@ -82,23 +80,16 @@ CC_CONSTRUCTOR_ACCESS:
~MeshSkin();
/**init from skin data*/
bool initFromSkinData(const SkinData& skindata);
/**remove all bones*/
void removeAllBones();
/**add skin bone*/
void addSkinBone(Bone3D* bone);
/**add Node bone*/
void addNodeBone(Bone3D* bone);
protected:
Vector<Bone3D*> _skinBones; // bones with skin
std::vector<Mat4> _invBindPoses; //inverse bind pose of bone
Vector<Bone3D*> _nodeBones; //bones without skin, only used to compute transform of children
Bone3D* _rootBone;
Skeleton3D* _skeleton; //skeleton the skin refered
@ -110,34 +101,6 @@ protected:
Vec4* _matrixPalette;
};
/**
* MeshSkinData Cache
*/
class MeshSkinDataCache
{
public:
/**get & destroy*/
static MeshSkinDataCache* getInstance();
static void destroyInstance();
/**get mesh skin data from cache*/
const SkinData* getMeshSkinData(const std::string& key) const;
/**add mesh skin data to cache*/
bool addMeshSkinData(const std::string& key, const SkinData& skinData);
/**remove all mesh skin data*/
void removeAllMeshSkinData();
protected:
MeshSkinDataCache();
~MeshSkinDataCache();
static MeshSkinDataCache* _cacheInstance; // instance
std::unordered_map<std::string, SkinData> _skinDatas; //cached skindatas
};
NS_CC_END
#endif // __CCSKIN_H__

View File

@ -0,0 +1,168 @@
/****************************************************************************
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 <list>
#include <fstream>
#include <iostream>
#include <sstream>
#include "3d/CCMeshVertexIndexData.h"
#include "3d/CCObjLoader.h"
#include "3d/CCSprite3DMaterial.h"
#include "3d/CCMesh.h"
#include "base/ccMacros.h"
#include "base/CCEventCustom.h"
#include "base/CCEventListenerCustom.h"
#include "base/CCEventDispatcher.h"
#include "base/CCEventType.h"
#include "base/CCDirector.h"
#include "renderer/ccGLStateCache.h"
using namespace std;
NS_CC_BEGIN
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
MeshIndexData* MeshIndexData::create(const std::string& id, MeshVertexData* vertexData, IndexBuffer* indexbuffer, const AABB& aabb)
{
auto meshindex = new MeshIndexData();
meshindex->_id = id;
meshindex->_indexBuffer = indexbuffer;
meshindex->_vertexData = vertexData;
indexbuffer->retain();
vertexData->retain();
meshindex->_aabb = aabb;
meshindex->autorelease();
return meshindex;
}
const VertexBuffer* MeshIndexData::getVertexBuffer() const
{
return _vertexData->getVertexBuffer();
}
MeshIndexData::MeshIndexData()
: _indexBuffer(nullptr)
, _vertexData(nullptr)
, _primitiveType(GL_TRIANGLES)
{
}
MeshIndexData::~MeshIndexData()
{
CC_SAFE_RELEASE(_indexBuffer);
CC_SAFE_RELEASE(_vertexData);
}
MeshVertexData* MeshVertexData::create(const MeshData& meshdata)
{
auto vertexdata = new MeshVertexData();
int pervertexsize = meshdata.getPerVertexSize();
vertexdata->_vertexBuffer = VertexBuffer::create(pervertexsize, (int)(meshdata.vertex.size() / (pervertexsize / 4)));
vertexdata->_vertexData = VertexData::create();
CC_SAFE_RETAIN(vertexdata->_vertexData);
CC_SAFE_RETAIN(vertexdata->_vertexBuffer);
int offset = 0;
for (const auto& it : meshdata.attribs) {
vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(offset, it.vertexAttrib, it.type, it.size));
offset += it.attribSizeBytes;
}
vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(0, GLProgram::VERTEX_ATTRIB_POSITION, GL_FLOAT, 3));
vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(offsetof(V3F_C4B_T2F, colors), GLProgram::VERTEX_ATTRIB_COLOR, GL_UNSIGNED_BYTE, 4, true));
vertexdata->_vertexData->setStream(vertexdata->_vertexBuffer, VertexStreamAttribute(offsetof(V3F_C4B_T2F, texCoords), GLProgram::VERTEX_ATTRIB_TEX_COORD, GL_FLOAT, 2));
vertexdata->_attribs = meshdata.attribs;
if(vertexdata->_vertexBuffer)
{
vertexdata->_vertexBuffer->updateVertices((void*)&meshdata.vertex[0], (int)meshdata.vertex.size() * 4, 0);
}
AABB aabb;
for (size_t i = 0; i < meshdata.subMeshIndices.size(); i++) {
auto& index = meshdata.subMeshIndices[i];
auto indexBuffer = IndexBuffer::create(IndexBuffer::IndexType::INDEX_TYPE_SHORT_16, (int)(index.size()));
indexBuffer->updateIndices(&index[0], (int)index.size(), 0);
aabb = MeshVertexData::calculateAABB(meshdata.vertex, meshdata.getPerVertexSize(), index);
std::string id = (i < meshdata.subMeshIds.size() ? meshdata.subMeshIds[i] : "");
MeshIndexData* indexdata = MeshIndexData::create(id, vertexdata, indexBuffer, aabb);
vertexdata->_indexs.pushBack(indexdata);
}
vertexdata->autorelease();
return vertexdata;
}
const AABB& MeshVertexData::calculateAABB(const std::vector<float>& vertex, int stride, const std::vector<unsigned short>& index)
{
static AABB aabb;
stride /= 4;
for(const auto& it : index)
{
Vec3 point = Vec3(vertex[it * stride ], vertex[ it * stride + 1], vertex[it * stride + 2 ]);
aabb.updateMinMax(&point, 1);
}
return aabb;
}
MeshIndexData* MeshVertexData::getMeshIndexDataById(const std::string& id) const
{
for (auto it : _indexs) {
if (it->getId() == id)
return it;
}
return nullptr;
}
bool MeshVertexData::hasVertexAttrib(int attrib) const
{
for (const auto& it : _attribs) {
if (it.vertexAttrib == attrib)
return true;
}
return false;
}
MeshVertexData::MeshVertexData()
: _vertexData(nullptr)
, _vertexBuffer(nullptr)
, _vertexCount(0)
{
}
MeshVertexData::~MeshVertexData()
{
CC_SAFE_RELEASE(_vertexData);
CC_SAFE_RELEASE(_vertexBuffer);
_indexs.clear();
}
NS_CC_END

View File

@ -0,0 +1,130 @@
/****************************************************************************
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 __CCMESHVERTEXINDEXDATA_H__
#define __CCMESHVERTEXINDEXDATA_H__
#include <string>
#include <vector>
#include "3d/CCBundle3DData.h"
#include "3d/CCAABB.h"
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "math/CCMath.h"
#include "renderer/CCGLProgram.h"
#include "renderer/CCVertexIndexData.h"
#include "renderer/CCVertexIndexBuffer.h"
#include "3d/3dExport.h"
NS_CC_BEGIN
class MeshVertexData;
class MeshIndexData : public Ref
{
public:
/** create */
static MeshIndexData* create(const std::string& id, MeshVertexData* vertexData, IndexBuffer* indexbuffer, const AABB& aabb);
/**get index buffer*/
const IndexBuffer* getIndexBuffer() const { return _indexBuffer; }
/**get vertex buffer*/
const VertexBuffer* getVertexBuffer() const;
/**get vertex data*/
const MeshVertexData* getMeshVertexData() const { return _vertexData; }
/** aabb getter and setter */
void setAABB(const AABB& aabb) { _aabb = aabb; }
const AABB& getAABB() const { return _aabb; }
/** id setter and getter */
void setId(const std::string& id) { _id = id; }
const std::string& getId() const { return _id; }
/**primitive type setter & getter*/
GLenum getPrimitiveType() const { return _primitiveType; }
void setPrimitiveType(GLenum primitive) { _primitiveType = primitive; }
CC_CONSTRUCTOR_ACCESS:
MeshIndexData();
virtual ~MeshIndexData();
protected:
IndexBuffer* _indexBuffer; //index buffer
MeshVertexData* _vertexData; //vertex buffer
AABB _aabb; // original aabb of the submesh
std::string _id; //id
GLenum _primitiveType;
friend class MeshVertexData;
friend class Sprite3D;
};
class MeshVertexData : public Ref
{
friend class Sprite3D;
friend class Mesh;
public:
/**create*/
static MeshVertexData* create(const MeshData& meshdata);
/** get vertexbuffer */
const VertexBuffer* getVertexBuffer() const { return _vertexBuffer; }
/** get attributes count */
ssize_t getMeshVertexAttribCount() const { return _attribs.size(); }
/** get attribute by index */
const MeshVertexAttrib& getMeshVertexAttrib(ssize_t index) const { return _attribs[index]; }
/** get index data count */
ssize_t getMeshIndexDataCount() const { return _indexs.size(); }
/** get index data by index */
MeshIndexData* getMeshIndexDataByIndex(int index) const { return _indexs.at(index); }
/** get index data by id */
MeshIndexData* getMeshIndexDataById(const std::string& id) const;
/**has vertex attribute?*/
bool hasVertexAttrib(int attrib) const;
CC_CONSTRUCTOR_ACCESS:
MeshVertexData();
virtual ~MeshVertexData();
static const AABB& calculateAABB(const std::vector<float>& vertex, int stride, const std::vector<unsigned short>& index);
protected:
VertexData* _vertexData; //mesh vertex data
VertexBuffer* _vertexBuffer; // vertex buffer
Vector<MeshIndexData*> _indexs; //index data
std::vector<MeshVertexAttrib> _attribs; //vertex attributes
int _vertexCount; //vertex count
};
NS_CC_END
#endif // __CCMESHVERTEXINDEXDATA_H__

View File

@ -249,7 +249,6 @@ void Bone3D::updateLocalMat()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Skeleton3D::Skeleton3D()
: _rootBone(nullptr)
{
}
@ -259,64 +258,16 @@ Skeleton3D::~Skeleton3D()
removeAllBones();
}
//create a new meshskin if do not want to share meshskin
Skeleton3D* Skeleton3D::create(const std::string& filename, const std::string& name)
Skeleton3D* Skeleton3D::create(const std::vector<NodeData*>& skeletondata)
{
//load skin here;
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
std::string key(fullPath + "#" + name);
const auto skeletondata = Skeleton3DDataCache::getInstance()->getSkeletonData(key);
if (skeletondata)
{
auto skeleton = new Skeleton3D();
skeleton->initFromSkeletonData(*skeletondata);
skeleton->autorelease();
return skeleton;
auto skeleton = new Skeleton3D();
for (const auto& it : skeletondata) {
auto bone = skeleton->createBone3D(*it);
bone->resetPose();
skeleton->_rootBones.pushBack(bone);
}
else
{
auto instance = Bundle3D::getInstance();
bool ret = instance->load(fullPath);
if (ret)
{
Skeleton3DData data;
if (instance->loadSkeletonData(name, &data))
{
auto skeleton = new Skeleton3D();
skeleton->initFromSkeletonData(data);
skeleton->autorelease();
Skeleton3DDataCache::getInstance()->addSkeletonData(key, data);
return skeleton;
}
}
}
return nullptr;
}
bool Skeleton3D::initFromSkeletonData(const Skeleton3DData& skeletondata)
{
ssize_t i = 0;
for (; i < skeletondata.boneNames.size(); i++) {
auto bone = Bone3D::create(skeletondata.boneNames[i]);
bone->setOriPose(skeletondata.boneOriginMatrices[i]);
addBone(bone);
}
for (auto it : skeletondata.boneChild) {
auto parent = getBoneByIndex(it.first);
for (auto childIt : it.second) {
auto child = getBoneByIndex(childIt);
child->_parent = parent;
parent->_children.pushBack(child);
}
}
setRootBone(getBoneByIndex(skeletondata.rootBoneIndex));
if (_rootBone)
_rootBone->resetPose();
return true;
skeleton->autorelease();
return skeleton;
}
ssize_t Skeleton3D::getBoneCount() const
@ -343,15 +294,14 @@ Bone3D* Skeleton3D::getBoneByName(const std::string& id) const
return nullptr;
}
Bone3D* Skeleton3D::getRootBone() const
ssize_t Skeleton3D::getRootCount() const
{
return _rootBone;
return _rootBones.size();
}
void Skeleton3D::setRootBone(Bone3D* joint)
Bone3D* Skeleton3D::getRootBone(int index) const
{
CC_SAFE_RETAIN(joint);
CC_SAFE_RELEASE(_rootBone);
_rootBone = joint;
return _rootBones.at(index);
}
int Skeleton3D::getBoneIndex(Bone3D* bone) const
@ -368,14 +318,16 @@ int Skeleton3D::getBoneIndex(Bone3D* bone) const
//refresh bone world matrix
void Skeleton3D::updateBoneMatrix()
{
_rootBone->setWorldMatDirty(true);
_rootBone->updateWorldMat();
for (const auto& it : _rootBones) {
it->setWorldMatDirty(true);
it->updateWorldMat();
}
}
void Skeleton3D::removeAllBones()
{
_bones.clear();
CC_SAFE_RELEASE(_rootBone);
_rootBones.clear();
}
void Skeleton3D::addBone(Bone3D* bone)
@ -383,54 +335,17 @@ void Skeleton3D::addBone(Bone3D* bone)
_bones.pushBack(bone);
}
////////////////////////////////////////////////////////////////////////
Skeleton3DDataCache* Skeleton3DDataCache::_cacheInstance = nullptr;
Skeleton3DDataCache* Skeleton3DDataCache::getInstance()
Bone3D* Skeleton3D::createBone3D(const NodeData& nodedata)
{
if (_cacheInstance == nullptr)
_cacheInstance = new Skeleton3DDataCache();
return _cacheInstance;
}
void Skeleton3DDataCache::destroyInstance()
{
if (_cacheInstance)
{
CC_SAFE_DELETE(_cacheInstance);
auto bone = Bone3D::create(nodedata.id);
for (const auto& it : nodedata.children) {
auto child = createBone3D(*it);
bone->addChildBone(child);
child->_parent = bone;
}
}
const Skeleton3DData* Skeleton3DDataCache::getSkeletonData(const std::string& key) const
{
auto it = _skeletonDatas.find(key);
if (it != _skeletonDatas.end())
return &it->second;
return nullptr;
}
bool Skeleton3DDataCache::addSkeletonData(const std::string& key, const Skeleton3DData& data)
{
if (_skeletonDatas.find(key) != _skeletonDatas.end())
return false; // already have this key
_skeletonDatas[key] = data;
return true;
}
void Skeleton3DDataCache::removeAllSkeletonData()
{
_skeletonDatas.clear();
}
Skeleton3DDataCache::Skeleton3DDataCache()
{
}
Skeleton3DDataCache::~Skeleton3DDataCache()
{
_bones.pushBack(bone);
bone->_oriPose = nodedata.transform;
return bone;
}
NS_CC_END

View File

@ -188,8 +188,7 @@ class CC_3D_DLL Skeleton3D: public Ref
{
public:
/**create a new meshskin if do not want to share Skeleton3D*/
static Skeleton3D* create(const std::string& filename, const std::string& name);
static Skeleton3D* create(const std::vector<NodeData*>& skeletondata);
/**get total bone count*/
ssize_t getBoneCount() const;
@ -199,8 +198,8 @@ public:
Bone3D* getBoneByName(const std::string& id) const;
/**get & set root bone*/
Bone3D* getRootBone() const;
void setRootBone(Bone3D* bone);
ssize_t getRootCount() const;
Bone3D* getRootBone(int index) const;
/**get bone index*/
int getBoneIndex(Bone3D* bone) const;
@ -214,48 +213,20 @@ CC_CONSTRUCTOR_ACCESS:
~Skeleton3D();
/**init from skeleton data*/
bool initFromSkeletonData(const Skeleton3DData& skeletondata);
/**remove all bones*/
void removeAllBones();
/**add bone*/
void addBone(Bone3D* bone);
/** create Bone3D from NodeData */
Bone3D* createBone3D(const NodeData& nodedata);
protected:
Vector<Bone3D*> _bones; // bones
Bone3D* _rootBone;
};
/**
* Skeleton3DData Cache
*/
class Skeleton3DDataCache
{
public:
/**get & destroy*/
static Skeleton3DDataCache* getInstance();
static void destroyInstance();
/**get mesh skin data from cache*/
const Skeleton3DData* getSkeletonData(const std::string& key) const;
/**add skeleton data to cache*/
bool addSkeletonData(const std::string& key, const Skeleton3DData& skeletonData);
/**remove all skeleton data*/
void removeAllSkeletonData();
CC_CONSTRUCTOR_ACCESS:
Skeleton3DDataCache();
~Skeleton3DDataCache();
static Skeleton3DDataCache* _cacheInstance; // instance
std::unordered_map<std::string, Skeleton3DData> _skeletonDatas; //cached skeleton datas
Vector<Bone3D*> _rootBones;
};
NS_CC_END

View File

@ -23,14 +23,11 @@
****************************************************************************/
#include "3d/CCSprite3D.h"
#include "3d/CCMesh.h"
#include "3d/CCObjLoader.h"
#include "3d/CCMeshSkin.h"
#include "3d/CCBundle3D.h"
#include "3d/CCSprite3DMaterial.h"
#include "3d/CCSubMesh.h"
#include "3d/CCAttachNode.h"
#include "3d/CCSubMeshState.h"
#include "3d/CCSkeleton3D.h"
#include "base/CCDirector.h"
@ -46,7 +43,7 @@
NS_CC_BEGIN
std::string s_attributeNames[] = {GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::ATTRIBUTE_NAME_NORMAL, GLProgram::ATTRIBUTE_NAME_BLEND_WEIGHT, GLProgram::ATTRIBUTE_NAME_BLEND_INDEX};
std::string s_attributeNames[] = {GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::ATTRIBUTE_NAME_TEX_COORD1, GLProgram::ATTRIBUTE_NAME_TEX_COORD2,GLProgram::ATTRIBUTE_NAME_TEX_COORD3,GLProgram::ATTRIBUTE_NAME_TEX_COORD4,GLProgram::ATTRIBUTE_NAME_TEX_COORD5,GLProgram::ATTRIBUTE_NAME_TEX_COORD6,GLProgram::ATTRIBUTE_NAME_TEX_COORD7,GLProgram::ATTRIBUTE_NAME_NORMAL, GLProgram::ATTRIBUTE_NAME_BLEND_WEIGHT, GLProgram::ATTRIBUTE_NAME_BLEND_INDEX};
Sprite3D* Sprite3D::create(const std::string &modelPath)
{
@ -62,7 +59,6 @@ Sprite3D* Sprite3D::create(const std::string &modelPath)
CC_SAFE_DELETE(sprite);
return nullptr;
}
Sprite3D* Sprite3D::create(const std::string &modelPath, const std::string &texturePath)
{
auto sprite = create(modelPath);
@ -76,33 +72,24 @@ Sprite3D* Sprite3D::create(const std::string &modelPath, const std::string &text
bool Sprite3D::loadFromCache(const std::string& path)
{
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path);
//find from the cache
std::string key = fullPath + "#";
auto mesh = MeshCache::getInstance()->getMesh(key);
if (mesh)
auto spritedata = Sprite3DCache::getInstance()->getSpriteData(path);
if (spritedata)
{
_mesh = mesh;
_mesh->retain();
for (auto it : spritedata->meshVertexDatas) {
_meshVertexDatas.pushBack(it);
}
_skeleton = Skeleton3D::create(spritedata->nodedatas->skeleton);
CC_SAFE_RETAIN(_skeleton);
char str[20];
for (int i = 0; i < (int)_mesh->getSubMeshCount(); i++) {
sprintf(str, "submesh%d", i);
std::string submeshkey = key + std::string(str);
auto tex = Sprite3DMaterialCache::getInstance()->getSprite3DMaterial(submeshkey);
auto submeshstate = SubMeshState::create();
submeshstate->setTexture(tex);
_subMeshStates.pushBack(submeshstate);
for(const auto& it : spritedata->nodedatas->nodes)
{
if(it)
{
createNode(it, this, *(spritedata->materialdatas), spritedata->nodedatas->nodes.size() == 1);
}
}
_skeleton = Skeleton3D::create(fullPath, "");
CC_SAFE_RETAIN(_skeleton);
_skin = MeshSkin::create(_skeleton, fullPath, "");
CC_SAFE_RETAIN(_skin);
genGLProgramState();
return true;
}
@ -113,114 +100,79 @@ bool Sprite3D::loadFromCache(const std::string& path)
bool Sprite3D::loadFromObj(const std::string& path)
{
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path);
std::string key = fullPath + "#";
//.mtl file directory
std::string dir = "";
auto last = fullPath.rfind("/");
if (last != -1)
dir = fullPath.substr(0, last + 1);
ObjLoader::shapes_t shapes;
std::string errstr = ObjLoader::LoadObj(shapes, fullPath.c_str(), dir.c_str());
if (!errstr.empty())
return false;
//convert to mesh and material
std::vector<std::vector<unsigned short> > submeshIndices;
std::vector<std::string> matnames;
std::string texname;
for (auto it = shapes.shapes.begin(); it != shapes.shapes.end(); it++)
MeshDatas meshdatas;
MaterialDatas* materialdatas = new MaterialDatas();
NodeDatas* nodeDatas = new NodeDatas();
bool ret = Bundle3D::loadObj(meshdatas, *materialdatas, *nodeDatas, fullPath);
if (ret && initFrom(*nodeDatas, meshdatas, *materialdatas))
{
submeshIndices.push_back((*it).mesh.indices);
texname = (*it).material.diffuse_texname;
if (!texname.empty())
texname = dir + (*it).material.diffuse_texname;
matnames.push_back(texname);
//add to cache
auto data = new Sprite3DCache::Sprite3DData();
data->materialdatas = materialdatas;
data->nodedatas = nodeDatas;
data->meshVertexDatas = _meshVertexDatas;
Sprite3DCache::getInstance()->addSprite3DData(path, data);
return true;
}
_mesh = Mesh::create(shapes.positions, shapes.normals, shapes.texcoords, submeshIndices);
_mesh->retain();
if (_mesh == nullptr)
return false;
//add mesh to cache
MeshCache::getInstance()->addMesh(key, _mesh);
delete materialdatas;
delete nodeDatas;
genMaterials(key, matnames);
genGLProgramState();
return true;
return false;
}
bool Sprite3D::loadFromC3x(const std::string& path)
{
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(path);
std::string key = fullPath + "#";
//load from .c3b or .c3t
auto bundle = Bundle3D::getInstance();
if (!bundle->load(fullPath))
return false;
MeshData meshdata;
bool ret = bundle->loadMeshData("", &meshdata);
if (!ret)
MeshDatas meshdatas;
MaterialDatas* materialdatas = new MaterialDatas();
NodeDatas* nodeDatas = new NodeDatas();
if (bundle->loadMeshDatas(meshdatas)
&& bundle->loadMaterials(*materialdatas)
&& bundle->loadNodes(*nodeDatas)
&& initFrom(*nodeDatas, meshdatas, *materialdatas))
{
return false;
//add to cache
auto data = new Sprite3DCache::Sprite3DData();
data->materialdatas = materialdatas;
data->nodedatas = nodeDatas;
data->meshVertexDatas = _meshVertexDatas;
Sprite3DCache::getInstance()->addSprite3DData(path, data);
return true;
}
_mesh = Mesh::create(meshdata.vertex, meshdata.vertexSizeInFloat, meshdata.subMeshIndices, meshdata.attribs);
CC_SAFE_RETAIN(_mesh);
//add mesh to cache
MeshCache::getInstance()->addMesh(key, _mesh);
_skeleton = Skeleton3D::create(fullPath, "");
CC_SAFE_RETAIN(_skeleton);
_skin = MeshSkin::create(_skeleton, fullPath, "");
CC_SAFE_RETAIN(_skin);
delete materialdatas;
delete nodeDatas;
MaterialData materialdata;
ret = bundle->loadMaterialData("", &materialdata);
if (ret)
{
std::vector<std::string> texpaths;
texpaths.resize(_mesh->getSubMeshCount(), "");
for (auto& it : materialdata.texturePaths)
{
texpaths[it.first] = it.second;
}
genMaterials(key, texpaths);
}
genGLProgramState();
return true;
return false;
}
Sprite3D::Sprite3D()
: _mesh(nullptr)
, _skin(nullptr)
, _skeleton(nullptr)
: _skeleton(nullptr)
, _blend(BlendFunc::ALPHA_NON_PREMULTIPLIED)
, _aabbDirty(true)
{
}
Sprite3D::~Sprite3D()
{
_subMeshStates.clear();
CC_SAFE_RELEASE_NULL(_mesh);
CC_SAFE_RELEASE_NULL(_skin);
_meshes.clear();
_meshVertexDatas.clear();
CC_SAFE_RELEASE_NULL(_skeleton);
removeAllAttachNode();
}
bool Sprite3D::initWithFile(const std::string &path)
{
_subMeshStates.clear();
CC_SAFE_RELEASE_NULL(_mesh);
CC_SAFE_RELEASE_NULL(_skin);
_meshes.clear();
_meshVertexDatas.clear();
CC_SAFE_RELEASE_NULL(_skeleton);
removeAllAttachNode();
if (loadFromCache(path))
return true;
@ -241,69 +193,240 @@ bool Sprite3D::initWithFile(const std::string &path)
return false;
}
bool Sprite3D::initFrom(const NodeDatas& nodeDatas, const MeshDatas& meshdatas, const MaterialDatas& materialdatas)
{
for(const auto& it : meshdatas.meshDatas)
{
if(it)
{
// Mesh* mesh = Mesh::create(*it);
// _meshes.pushBack(mesh);
auto meshvertex = MeshVertexData::create(*it);
_meshVertexDatas.pushBack(meshvertex);
}
}
_skeleton = Skeleton3D::create(nodeDatas.skeleton);
CC_SAFE_RETAIN(_skeleton);
for(const auto& it : nodeDatas.nodes)
{
if(it)
{
createNode(it, this, materialdatas, nodeDatas.nodes.size() == 1);
}
}
for(const auto& it : nodeDatas.skeleton)
{
if(it)
{
createAttachSprite3DNode(it,materialdatas);
}
}
genGLProgramState();
return true;
}
Sprite3D* Sprite3D::createSprite3DNode(NodeData* nodedata,ModelData* modeldata,const MaterialDatas& matrialdatas)
{
auto sprite = new Sprite3D();
if (sprite)
{
auto mesh = Mesh::create(nodedata->id, getMeshIndexData(modeldata->subMeshId));
if (modeldata->matrialId == "" && matrialdatas.materials.size())
{
const NTextureData* textureData = matrialdatas.materials[0].getTextureData(NTextureData::Usage::Diffuse);
mesh->setTexture(textureData->filename);
}
else
{
const NMaterialData* materialData=matrialdatas.getMaterialData(modeldata->matrialId);
if(materialData)
{
const NTextureData* textureData = materialData->getTextureData(NTextureData::Usage::Diffuse);
if(textureData)
{
auto tex = Director::getInstance()->getTextureCache()->addImage(textureData->filename);
if(tex)
{
Texture2D::TexParams texParams;
texParams.minFilter = GL_LINEAR;
texParams.magFilter = GL_LINEAR;
texParams.wrapS = textureData->wrapS;
texParams.wrapT = textureData->wrapT;
tex->setTexParameters(texParams);
mesh->setTexture(tex);
}
}
}
}
sprite->setAdditionalTransform(&nodedata->transform);
sprite->addMesh(mesh);
sprite->autorelease();
sprite->genGLProgramState();
}
return sprite;
}
void Sprite3D::createAttachSprite3DNode(NodeData* nodedata,const MaterialDatas& matrialdatas)
{
for(const auto& it : nodedata->modelNodeDatas)
{
if(it && getAttachNode(nodedata->id))
{
auto sprite = createSprite3DNode(nodedata,it,matrialdatas);
if (sprite)
{
getAttachNode(nodedata->id)->addChild(sprite);
}
}
}
for(const auto& it : nodedata->children)
{
createAttachSprite3DNode(it,matrialdatas);
}
}
void Sprite3D::genGLProgramState()
{
auto programstate = GLProgramState::getOrCreateWithGLProgram(getDefaultGLProgram(_mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD)));
long offset = 0;
auto attributeCount = _mesh->getMeshVertexAttribCount();
for (auto k = 0; k < attributeCount; k++) {
auto meshattribute = _mesh->getMeshVertexAttribute(k);
programstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib],
meshattribute.size,
meshattribute.type,
GL_FALSE,
_mesh->getVertexSizeInBytes(),
(GLvoid*)offset);
offset += meshattribute.attribSizeBytes;
}
setGLProgramState(programstate);
auto count = _mesh->getSubMeshCount();
_meshCommands.resize(count);
for (int i = 0; i < count; i++) {
auto tex = _subMeshStates.at(i)->getTexture();
GLuint texID = tex ? tex->getName() : 0;
_meshCommands[i].genMaterialID(texID, programstate, _mesh, _blend);
}
}
GLProgram* Sprite3D::getDefaultGLProgram(bool textured)
{
bool hasSkin = _skin && _mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_INDEX)
&& _mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_WEIGHT);
if(textured)
std::unordered_map<const MeshVertexData*, GLProgramState*> glProgramestates;
for(auto& mesh : _meshVertexDatas)
{
if (hasSkin)
return GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_SKINPOSITION_TEXTURE);
bool textured = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD);
bool hasSkin = mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_INDEX)
&& mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_WEIGHT);
return GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION_TEXTURE);
GLProgram* glProgram = nullptr;
if(textured)
{
if (hasSkin)
glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_SKINPOSITION_TEXTURE);
else
glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION_TEXTURE);
}
else
{
glProgram = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION);
}
auto programstate = GLProgramState::create(glProgram);
long offset = 0;
auto attributeCount = mesh->getMeshVertexAttribCount();
for (auto k = 0; k < attributeCount; k++) {
auto meshattribute = mesh->getMeshVertexAttrib(k);
programstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib],
meshattribute.size,
meshattribute.type,
GL_FALSE,
mesh->getVertexBuffer()->getSizePerVertex(),
(GLvoid*)offset);
offset += meshattribute.attribSizeBytes;
}
glProgramestates[mesh] = programstate;
}
else
{
return GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION);
for (auto& it : _meshes) {
auto glProgramState = glProgramestates[it->getMeshIndexData()->getMeshVertexData()];
it->setGLProgramState(glProgramState);
}
}
void Sprite3D::genMaterials(const std::string& keyprefix, const std::vector<std::string>& texpaths)
void Sprite3D::createNode(NodeData* nodedata, Node* root, const MaterialDatas& matrialdatas, bool singleSprite)
{
_subMeshStates.clear();
char str[20];
auto cache = Director::getInstance()->getTextureCache();
int index = 0;
for (auto& it : texpaths) {
auto tex = cache->addImage(it);
auto subMeshState = SubMeshState::create();
subMeshState->setTexture(tex);
_subMeshStates.pushBack(subMeshState);
Node* node=nullptr;
for(const auto& it : nodedata->modelNodeDatas)
{
if(it)
{
if(it->bones.size() > 0 || singleSprite)
{
auto mesh = Mesh::create(nodedata->id, getMeshIndexData(it->subMeshId));
if(mesh)
{
_meshes.pushBack(mesh);
if (_skeleton && it->bones.size())
{
auto skin = MeshSkin::create(_skeleton, it->bones, it->invBindPose);
mesh->setSkin(skin);
}
mesh->_visibleChanged = std::bind(&Sprite3D::onAABBDirty, this);
//add to cache
sprintf(str, "submesh%d", index);
std::string submeshkey = keyprefix + std::string(str);
Sprite3DMaterialCache::getInstance()->addSprite3DMaterial(submeshkey, tex);
index++;
if (it->matrialId == "" && matrialdatas.materials.size())
{
const NTextureData* textureData = matrialdatas.materials[0].getTextureData(NTextureData::Usage::Diffuse);
mesh->setTexture(textureData->filename);
}
else
{
const NMaterialData* materialData=matrialdatas.getMaterialData(it->matrialId);
if(materialData)
{
const NTextureData* textureData = materialData->getTextureData(NTextureData::Usage::Diffuse);
if(textureData)
{
auto tex = Director::getInstance()->getTextureCache()->addImage(textureData->filename);
if(tex)
{
Texture2D::TexParams texParams;
texParams.minFilter = GL_LINEAR;
texParams.magFilter = GL_LINEAR;
texParams.wrapS = textureData->wrapS;
texParams.wrapT = textureData->wrapT;
tex->setTexParameters(texParams);
mesh->setTexture(tex);
}
}
}
}
}
}
else
{
auto sprite = createSprite3DNode(nodedata,it,matrialdatas);
if (sprite)
{
if(root)
{
root->addChild(sprite);
}
}
node=sprite;
}
}
}
if(nodedata->modelNodeDatas.size() ==0 )
{
node= Node::create();
if(node)
{
node->setAdditionalTransform(&nodedata->transform);
if(root)
{
root->addChild(node);
}
}
}
for(const auto& it : nodedata->children)
{
createNode(it,node, matrialdatas, singleSprite);
}
}
MeshIndexData* Sprite3D::getMeshIndexData(const std::string& indexId) const
{
for (auto it : _meshVertexDatas) {
auto index = it->getMeshIndexDataById(indexId);
if (index)
return index;
}
return nullptr;
}
void Sprite3D::addMesh(Mesh* mesh)
{
auto meshVertex = mesh->getMeshIndexData()->_vertexData;
_meshVertexDatas.pushBack(meshVertex);
_meshes.pushBack(mesh);
}
void Sprite3D::setTexture(const std::string& texFile)
@ -314,18 +437,19 @@ void Sprite3D::setTexture(const std::string& texFile)
void Sprite3D::setTexture(Texture2D* texture)
{
_subMeshStates.at(0)->setTexture(texture);
for (auto& state : _meshes) {
state->setTexture(texture);
}
}
AttachNode* Sprite3D::getAttachNode(const std::string& boneName)
{
auto it = _attachments.find(boneName);
if (it != _attachments.end())
return it->second;
if (_skin)
if (_skeleton)
{
auto bone = _skin->getBoneByName(boneName);
auto bone = _skeleton->getBoneByName(boneName);
auto attachNode = AttachNode::create(bone);
addChild(attachNode);
_attachments[boneName] = attachNode;
@ -355,30 +479,31 @@ void Sprite3D::removeAllAttachNode()
void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
// if (_skeleton)
// _skeleton->updateBoneMatrix();
if (_skeleton)
_skeleton->updateBoneMatrix();
GLProgramState* programstate = getGLProgramState();
Color4F color(getDisplayedColor());
color.a = getDisplayedOpacity() / 255.0f;
for (ssize_t i = 0; i < _mesh->getSubMeshCount(); i++) {
auto submeshstate = _subMeshStates.at(i);
if (!submeshstate->isVisible())
continue;
auto submesh = _mesh->getSubMesh((int)i);
auto& meshCommand = _meshCommands[i];
GLuint textureID = submeshstate->getTexture() ? submeshstate->getTexture()->getName() : 0;
meshCommand.init(_globalZOrder, textureID, programstate, _blend, _mesh->getVertexBuffer(), submesh->getIndexBuffer(), (GLenum)submesh->getPrimitiveType(), (GLenum)submesh->getIndexFormat(), submesh->getIndexCount(), transform);
meshCommand.setCullFaceEnabled(true);
meshCommand.setDepthTestEnabled(true);
if (_skin)
int i = 0;
for (auto& mesh : _meshes) {
if (!mesh->isVisible())
{
meshCommand.setMatrixPaletteSize((int)_skin->getMatrixPaletteSize());
meshCommand.setMatrixPalette(_skin->getMatrixPalette());
i++;
continue;
}
auto programstate = mesh->getGLProgramState();
auto& meshCommand = mesh->getMeshCommand();
GLuint textureID = mesh->getTexture() ? mesh->getTexture()->getName() : 0;
meshCommand.init(_globalZOrder, textureID, programstate, _blend, mesh->getVertexBuffer(), mesh->getIndexBuffer(), mesh->getPrimitiveType(), mesh->getIndexFormat(), mesh->getIndexCount(), transform);
auto skin = mesh->getSkin();
if (skin)
{
meshCommand.setMatrixPaletteSize((int)skin->getMatrixPaletteSize());
meshCommand.setMatrixPalette(skin->getMatrixPalette());
}
//support tint and fade
meshCommand.setDisplayColor(Vec4(color.r, color.g, color.b, color.a));
@ -386,11 +511,28 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
}
}
void Sprite3D::setGLProgramState(GLProgramState *glProgramState)
{
Node::setGLProgramState(glProgramState);
for (auto& state : _meshes) {
state->setGLProgramState(glProgramState);
}
}
void Sprite3D::setGLProgram(GLProgram *glprogram)
{
Node::setGLProgram(glprogram);
setGLProgramState(getGLProgramState());
}
void Sprite3D::setBlendFunc(const BlendFunc &blendFunc)
{
if(_blend.src != blendFunc.src || _blend.dst != blendFunc.dst)
{
_blend = blendFunc;
for(auto& state : _meshes)
{
state->setBlendFunc(blendFunc);
}
}
}
@ -399,23 +541,22 @@ const BlendFunc& Sprite3D::getBlendFunc() const
return _blend;
}
AABB Sprite3D::getAABB() const
const AABB& Sprite3D::getAABB() const
{
Mat4 nodeToWorldTransform(getNodeToWorldTransform());
// If nodeToWorldTransform matrix isn't changed, we don't need to transform aabb.
if (memcmp(_nodeToWorldTransform.m, nodeToWorldTransform.m, sizeof(Mat4)) == 0)
if (memcmp(_nodeToWorldTransform.m, nodeToWorldTransform.m, sizeof(Mat4)) == 0 && !_aabbDirty)
{
return _aabb;
}
else
{
_aabb.reset();
Mat4 transform(nodeToWorldTransform);
_aabb = _mesh->getOriginAABB();
if (getSkin() && getSkin()->getRootBone())
{
transform = nodeToWorldTransform * getSkin()->getRootBone()->getWorldMat();
for (const auto& it : _meshes) {
if (it->isVisible())
_aabb.merge(it->getAABB());
}
_aabb.transform(transform);
@ -434,16 +575,104 @@ Rect Sprite3D::getBoundingBox() const
void Sprite3D::setCullFace(GLenum cullFace)
{
for (auto& it : _meshCommands) {
it.setCullFace(cullFace);
for (auto& it : _meshes) {
it->getMeshCommand().setCullFace(cullFace);
}
}
void Sprite3D::setCullFaceEnabled(bool enable)
{
for (auto& it : _meshCommands) {
it.setCullFaceEnabled(enable);
for (auto& it : _meshes) {
it->getMeshCommand().setCullFaceEnabled(enable);
}
}
Mesh* Sprite3D::getMeshByIndex(int index) const
{
CCASSERT(index < _meshes.size(), "invald index");
return _meshes.at(index);
}
/**get SubMeshState by Name */
Mesh* Sprite3D::getMeshByName(const std::string& name) const
{
for (const auto& it : _meshes) {
if (it->getName() == name)
return it;
}
return nullptr;
}
MeshSkin* Sprite3D::getSkin() const
{
for (const auto& it : _meshes) {
if (it->getSkin())
return it->getSkin();
}
return nullptr;
}
///////////////////////////////////////////////////////////////////////////////////
Sprite3DCache* Sprite3DCache::_cacheInstance = nullptr;
Sprite3DCache* Sprite3DCache::getInstance()
{
if (_cacheInstance == nullptr)
_cacheInstance = new Sprite3DCache();
return _cacheInstance;
}
void Sprite3DCache::destroyInstance()
{
if (_cacheInstance)
{
delete _cacheInstance;
_cacheInstance = nullptr;
}
}
Sprite3DCache::Sprite3DData* Sprite3DCache::getSpriteData(const std::string& key) const
{
auto it = _spriteDatas.find(key);
if (it != _spriteDatas.end())
return it->second;
return nullptr;
}
bool Sprite3DCache::addSprite3DData(const std::string& key, Sprite3DCache::Sprite3DData* spritedata)
{
auto it = _spriteDatas.find(key);
if (it == _spriteDatas.end())
{
_spriteDatas[key] = spritedata;
return true;
}
return false;
}
void Sprite3DCache::removeSprite3DData(const std::string& key)
{
auto it = _spriteDatas.find(key);
if (it != _spriteDatas.end())
{
delete it->second;
}
_spriteDatas.erase(it);
}
void Sprite3DCache::removeAllSprite3DData()
{
for (auto& it : _spriteDatas) {
delete it.second;
}
_spriteDatas.clear();
}
Sprite3DCache::Sprite3DCache()
{
}
Sprite3DCache::~Sprite3DCache()
{
removeAllSprite3DData();
}
NS_CC_END

View File

@ -33,9 +33,13 @@
#include "base/CCProtocols.h"
#include "2d/CCNode.h"
#include "renderer/CCMeshCommand.h"
#include "CCAABB.h"
#include "3d/CCAABB.h"
#include "3d/CCBundle3DData.h"
#include "3d/CCMesh.h"
#include "3d/CCMeshVertexIndexData.h"
#include "3d/3dExport.h"
NS_CC_BEGIN
class GLProgramState;
@ -45,14 +49,15 @@ class MeshSkin;
class AttachNode;
class SubMeshState;
class Skeleton3D;
struct NodeData;
class SubMesh;
/** Sprite3D: A sprite can be loaded from 3D model files, .obj, .c3t, .c3b, then can be drawed as sprite */
class CC_3D_DLL Sprite3D : public Node, public BlendProtocol
{
public:
/** creates a Sprite3D*/
static Sprite3D* create(const std::string &modelPath);
// creates a Sprite3D. It only supports one texture, and overrides the internal texture with 'texturePath'
static Sprite3D* create(const std::string &modelPath, const std::string &texturePath);
@ -61,13 +66,18 @@ public:
void setTexture(Texture2D* texture);
/**get SubMeshState by index*/
SubMeshState* getSubMeshState(int index) const;
Mesh* getMeshByIndex(int index) const;
/**get SubMeshState by Name */
Mesh* getMeshByName(const std::string& name) const;
/**get mesh*/
Mesh* getMesh() const { return _mesh; }
Mesh* getMesh() const { return _meshes.at(0); }
/**get skin*/
MeshSkin* getSkin() const { return _skin; }
CC_DEPRECATED_ATTRIBUTE MeshSkin* getSkin() const;
Skeleton3D* getSkeleton() const { return _skeleton; }
/**get AttachNode by bone name, return nullptr if not exist*/
AttachNode* getAttachNode(const std::string& boneName);
@ -82,13 +92,19 @@ public:
virtual void setBlendFunc(const BlendFunc &blendFunc) override;
virtual const BlendFunc &getBlendFunc() const override;
// overrides
/** set GLProgramState, you should bind attributes by yourself */
virtual void setGLProgramState(GLProgramState *glProgramState) override;
/** just rember bind attributes */
virtual void setGLProgram(GLProgram *glprogram) override;
/*
* Get AABB
* If the sprite has animation, it can't be calculated accuratly,
* because bone can drive the vertices, we just use the origin vertices
* to calculate the AABB.
*/
AABB getAABB() const;
const AABB& getAABB() const;
/**
* Returns 2d bounding-box
@ -107,6 +123,8 @@ CC_CONSTRUCTOR_ACCESS:
virtual ~Sprite3D();
bool initWithFile(const std::string &path);
bool initFrom(const NodeDatas& nodedatas, const MeshDatas& meshdatas, const MaterialDatas& materialdatas);
/**load sprite3d from cache, return true if succeed, false otherwise*/
bool loadFromCache(const std::string& path);
@ -119,30 +137,77 @@ CC_CONSTRUCTOR_ACCESS:
/**draw*/
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
/**get default shader*/
virtual GLProgram* getDefaultGLProgram(bool textured = true);
/**generate default GLProgramState*/
void genGLProgramState();
/**generate materials, and add them to cache, keyprefix is used as key prefix when added to cache*/
void genMaterials(const std::string& keyprefix, const std::vector<std::string>& texpaths);
void createNode(NodeData* nodedata, Node* root, const MaterialDatas& matrialdatas, bool singleSprite);
void createAttachSprite3DNode(NodeData* nodedata,const MaterialDatas& matrialdatas);
Sprite3D* createSprite3DNode(NodeData* nodedata,ModelData* modeldata,const MaterialDatas& matrialdatas);
/**get MeshIndexData by Id*/
MeshIndexData* getMeshIndexData(const std::string& indexId) const;
void addMesh(Mesh* mesh);
void onAABBDirty() { _aabbDirty = true; }
protected:
Mesh* _mesh;//mesh
MeshSkin* _skin;//skin
Skeleton3D* _skeleton; //skeleton
std::vector<MeshCommand> _meshCommands; //render command each for one submesh
Vector<SubMeshState*> _subMeshStates; // SubMeshStates
Vector<MeshVertexData*> _meshVertexDatas;
std::unordered_map<std::string, AttachNode*> _attachments;
BlendFunc _blend;
Vector<Mesh*> _meshes;
mutable AABB _aabb; // cache current aabb
mutable Mat4 _nodeToWorldTransform; // cache the matrix
bool _aabbDirty;
};
///////////////////////////////////////////////////////
class Sprite3DCache
{
public:
struct Sprite3DData
{
Vector<MeshVertexData*> meshVertexDatas;
NodeDatas* nodedatas;
MaterialDatas* materialdatas;
~Sprite3DData()
{
if (nodedatas)
delete nodedatas;
if (materialdatas)
delete materialdatas;
meshVertexDatas.clear();
}
};
/**get & destroy*/
static Sprite3DCache* getInstance();
static void destroyInstance();
Sprite3DData* getSpriteData(const std::string& key) const;
bool addSprite3DData(const std::string& key, Sprite3DData* spritedata);
void removeSprite3DData(const std::string& key);
void removeAllSprite3DData();
CC_CONSTRUCTOR_ACCESS:
Sprite3DCache();
~Sprite3DCache();
protected:
static Sprite3DCache* _cacheInstance;
std::unordered_map<std::string, Sprite3DData*> _spriteDatas; //cached sprite datas
};
extern std::string CC_3D_DLL s_attributeNames[];//attribute names array

View File

@ -1,97 +0,0 @@
/****************************************************************************
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 "CCSubMesh.h"
#include <list>
#include <fstream>
#include <iostream>
#include <sstream>
#include "3d/CCObjLoader.h"
#include "3d/CCSprite3DMaterial.h"
#include "base/ccMacros.h"
#include "base/CCEventCustom.h"
#include "base/CCEventListenerCustom.h"
#include "base/CCEventDispatcher.h"
#include "base/CCEventType.h"
#include "base/CCDirector.h"
#include "renderer/ccGLStateCache.h"
using namespace std;
NS_CC_BEGIN
SubMesh::SubMesh()
: _indexBuffer(0)
, _primitiveType(PrimitiveType::TRIANGLES)
, _indexFormat(IndexFormat::INDEX16)
, _indexCount(0)
{
}
SubMesh::~SubMesh()
{
cleanAndFreeBuffers();
}
SubMesh* SubMesh::create(PrimitiveType primitivetype, IndexFormat indexformat, const std::vector<unsigned short>& indices)
{
auto submesh = new SubMesh();
submesh->_primitiveType = primitivetype;
submesh->_indexFormat = indexformat;
submesh->autorelease();
return submesh;
}
void SubMesh::cleanAndFreeBuffers()
{
if(glIsBuffer(_indexBuffer))
{
glDeleteBuffers(1, &_indexBuffer);
_indexBuffer = 0;
}
_indexCount = 0;
}
void SubMesh::buildBuffer(const std::vector<unsigned short>& indices)
{
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
unsigned int indexSize = 2;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * indices.size(), &indices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
_indexCount = indices.size();
}
NS_CC_END

View File

@ -1,99 +0,0 @@
/****************************************************************************
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 __CCSUBMESH_H__
#define __CCSUBMESH_H__
#include <string>
#include <vector>
#include "3d/CCBundle3DData.h"
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "math/CCMath.h"
#include "renderer/CCGLProgram.h"
#include "3d/3dExport.h"
NS_CC_BEGIN
/** Defines supported index formats. */
enum class IndexFormat
{
INDEX8 = GL_UNSIGNED_BYTE,
INDEX16 = GL_UNSIGNED_SHORT,
};
/** Defines supported primitive types. */
enum class PrimitiveType
{
TRIANGLES = GL_TRIANGLES,
TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
LINES = GL_LINES,
LINE_STRIP = GL_LINE_STRIP,
POINTS = GL_POINTS
};
/**
* SubMesh: Defines the way the mesh's vertices how to be connected together.
*/
class CC_3D_DLL SubMesh : public Ref
{
friend class Mesh;
public:
/**create submesh from primitivetype indexformat and indices*/
static SubMesh* create(PrimitiveType primitivetype, IndexFormat indexformat, const std::vector<unsigned short>& indices);
/** get primitive type*/
PrimitiveType getPrimitiveType() const { return _primitiveType; }
/**get index count*/
ssize_t getIndexCount() const { return _indexCount; }
/**get index format*/
IndexFormat getIndexFormat() const { return _indexFormat; }
/**get index buffer*/
GLuint getIndexBuffer() const {return _indexBuffer; }
CC_CONSTRUCTOR_ACCESS:
SubMesh();
virtual ~SubMesh();
/**build buffer*/
void buildBuffer(const std::vector<unsigned short>& indices);
/**free buffer*/
void cleanAndFreeBuffers();
protected:
PrimitiveType _primitiveType;
IndexFormat _indexFormat;
GLuint _indexBuffer;
ssize_t _indexCount;
};
NS_CC_END
#endif // __CCMESH_H_

View File

@ -1,89 +0,0 @@
/****************************************************************************
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 <list>
#include <fstream>
#include <iostream>
#include <sstream>
#include "3d/CCSubMeshState.h"
#include "3d/CCMeshSkin.h"
#include "3d/CCSubMesh.h"
#include "base/ccMacros.h"
#include "base/CCEventCustom.h"
#include "base/CCEventListenerCustom.h"
#include "base/CCEventDispatcher.h"
#include "base/CCEventType.h"
#include "base/CCDirector.h"
#include "renderer/ccGLStateCache.h"
#include "renderer/CCTexture2D.h"
using namespace std;
NS_CC_BEGIN
SubMeshState::SubMeshState()
: _visible(true)
, _texture(nullptr)
, _skin(nullptr)
{
}
SubMeshState::~SubMeshState()
{
CC_SAFE_RELEASE(_texture);
CC_SAFE_RELEASE(_skin);
}
SubMeshState* SubMeshState::create()
{
auto state = new SubMeshState();
state->autorelease();
return state;
}
void SubMeshState::setTexture(Texture2D* tex)
{
if (tex != _texture)
{
CC_SAFE_RETAIN(tex);
CC_SAFE_RELEASE(_texture);
_texture = tex;
}
}
void SubMeshState::setSkin(MeshSkin* skin)
{
if (_skin != skin)
{
CC_SAFE_RETAIN(skin);
CC_SAFE_RELEASE(_skin);
_skin = skin;
}
}
NS_CC_END

View File

@ -1,78 +0,0 @@
/****************************************************************************
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 __CCSUBMESHSTATE_H__
#define __CCSUBMESHSTATE_H__
#include <string>
#include <vector>
#include "3d/CCBundle3DData.h"
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "math/CCMath.h"
#include "renderer/CCGLProgram.h"
#include "3d/3dExport.h"
NS_CC_BEGIN
class Texture2D;
class MeshSkin;
/**
* SubMeshState: visibility and apperence of submesh
*/
class CC_3D_DLL SubMeshState : public Ref
{
public:
/**create submesh from primitivetype indexformat and indices*/
static SubMeshState* create();
/**texture getter and setter*/
void setTexture(Texture2D* tex);
Texture2D* getTexture() const { return _texture; }
/**visible getter and setter*/
void setVisible(bool visible) { _visible = visible; }
bool isVisible() const { return _visible; }
/**skin getter and setter*/
void setSkin(MeshSkin* skin);
MeshSkin* getSkin() const { return _skin; }
CC_CONSTRUCTOR_ACCESS:
SubMeshState();
virtual ~SubMeshState();
protected:
Texture2D* _texture; //texture that submesh is using
MeshSkin* _skin; //skin
bool _visible; // is the submesh visible
};
NS_CC_END
#endif // __CCSUBMESHSTATE_H__

View File

@ -9,12 +9,11 @@ CCBundle3D.cpp
CCBundleReader.cpp
CCMesh.cpp
CCMeshSkin.cpp
CCMeshVertexIndexData.cpp
CCSprite3DMaterial.cpp
CCObjLoader.cpp
CCSkeleton3D.cpp
CCSprite3D.cpp
CCSubMesh.cpp
CCSubMeshState.cpp
)

View File

@ -35,7 +35,7 @@
#include "3d/CCAnimate3D.h"
#include "3d/CCAnimation3D.h"
#include "3d/CCSprite3DMaterial.h"
#include "3d/CCSubMeshState.h"
#include "3d/CCAttachNode.h"
#include "3d/CCMeshVertexIndexData.h"
#endif

View File

@ -24,14 +24,13 @@
<ClCompile Include="..\CCBundleReader.cpp" />
<ClCompile Include="..\CCMesh.cpp" />
<ClCompile Include="..\CCMeshSkin.cpp" />
<ClCompile Include="..\CCMeshVertexIndexData.cpp" />
<ClCompile Include="..\CCOBB.cpp" />
<ClCompile Include="..\CCObjLoader.cpp" />
<ClCompile Include="..\CCRay.cpp" />
<ClCompile Include="..\CCSkeleton3D.cpp" />
<ClCompile Include="..\CCSprite3D.cpp" />
<ClCompile Include="..\CCSprite3DMaterial.cpp" />
<ClCompile Include="..\CCSubMesh.cpp" />
<ClCompile Include="..\CCSubMeshState.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\3dExport.h" />
@ -45,14 +44,13 @@
<ClInclude Include="..\CCBundleReader.h" />
<ClInclude Include="..\CCMesh.h" />
<ClInclude Include="..\CCMeshSkin.h" />
<ClInclude Include="..\CCMeshVertexIndexData.h" />
<ClInclude Include="..\CCOBB.h" />
<ClInclude Include="..\CCObjLoader.h" />
<ClInclude Include="..\CCRay.h" />
<ClInclude Include="..\CCSkeleton3D.h" />
<ClInclude Include="..\CCSprite3D.h" />
<ClInclude Include="..\CCSprite3DMaterial.h" />
<ClInclude Include="..\CCSubMesh.h" />
<ClInclude Include="..\CCSubMeshState.h" />
<ClInclude Include="..\cocos3d.h" />
</ItemGroup>
<PropertyGroup Label="Globals">

View File

@ -48,10 +48,7 @@
<ClCompile Include="..\CCSprite3DMaterial.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\CCSubMesh.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\CCSubMeshState.cpp">
<ClCompile Include="..\CCMeshVertexIndexData.cpp">
<Filter>3d</Filter>
</ClCompile>
</ItemGroup>
@ -104,17 +101,14 @@
<ClInclude Include="..\CCSprite3DMaterial.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\CCSubMesh.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\CCSubMeshState.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\cocos3d.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3dExport.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\CCMeshVertexIndexData.h">
<Filter>3d</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -94,6 +94,13 @@ const char* GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE = "CC_alpha_value";
const char* GLProgram::ATTRIBUTE_NAME_COLOR = "a_color";
const char* GLProgram::ATTRIBUTE_NAME_POSITION = "a_position";
const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD = "a_texCoord";
const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD1 = "a_texCoord1";
const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD2 = "a_texCoord2";
const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD3 = "a_texCoord3";
const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD4 = "a_texCoord4";
const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD5 = "a_texCoord5";
const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD6 = "a_texCoord6";
const char* GLProgram::ATTRIBUTE_NAME_TEX_COORD7 = "a_texCoord7";
const char* GLProgram::ATTRIBUTE_NAME_NORMAL = "a_normal";
const char* GLProgram::ATTRIBUTE_NAME_BLEND_WEIGHT = "a_blendWeight";
const char* GLProgram::ATTRIBUTE_NAME_BLEND_INDEX = "a_blendIndex";
@ -281,6 +288,13 @@ void GLProgram::bindPredefinedVertexAttribs()
{GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION},
{GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR},
{GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD},
{GLProgram::ATTRIBUTE_NAME_TEX_COORD1, GLProgram::VERTEX_ATTRIB_TEX_COORD1},
{GLProgram::ATTRIBUTE_NAME_TEX_COORD2, GLProgram::VERTEX_ATTRIB_TEX_COORD2},
{GLProgram::ATTRIBUTE_NAME_TEX_COORD3, GLProgram::VERTEX_ATTRIB_TEX_COORD3},
{GLProgram::ATTRIBUTE_NAME_TEX_COORD4, GLProgram::VERTEX_ATTRIB_TEX_COORD4},
{GLProgram::ATTRIBUTE_NAME_TEX_COORD5, GLProgram::VERTEX_ATTRIB_TEX_COORD5},
{GLProgram::ATTRIBUTE_NAME_TEX_COORD6, GLProgram::VERTEX_ATTRIB_TEX_COORD6},
{GLProgram::ATTRIBUTE_NAME_TEX_COORD7, GLProgram::VERTEX_ATTRIB_TEX_COORD7},
{GLProgram::ATTRIBUTE_NAME_NORMAL, GLProgram::VERTEX_ATTRIB_NORMAL},
};

View File

@ -84,6 +84,13 @@ public:
VERTEX_ATTRIB_POSITION,
VERTEX_ATTRIB_COLOR,
VERTEX_ATTRIB_TEX_COORD,
VERTEX_ATTRIB_TEX_COORD1,
VERTEX_ATTRIB_TEX_COORD2,
VERTEX_ATTRIB_TEX_COORD3,
VERTEX_ATTRIB_TEX_COORD4,
VERTEX_ATTRIB_TEX_COORD5,
VERTEX_ATTRIB_TEX_COORD6,
VERTEX_ATTRIB_TEX_COORD7,
VERTEX_ATTRIB_NORMAL,
VERTEX_ATTRIB_BLEND_WEIGHT,
VERTEX_ATTRIB_BLEND_INDEX,
@ -152,6 +159,13 @@ public:
static const char* ATTRIBUTE_NAME_COLOR;
static const char* ATTRIBUTE_NAME_POSITION;
static const char* ATTRIBUTE_NAME_TEX_COORD;
static const char* ATTRIBUTE_NAME_TEX_COORD1;
static const char* ATTRIBUTE_NAME_TEX_COORD2;
static const char* ATTRIBUTE_NAME_TEX_COORD3;
static const char* ATTRIBUTE_NAME_TEX_COORD4;
static const char* ATTRIBUTE_NAME_TEX_COORD5;
static const char* ATTRIBUTE_NAME_TEX_COORD6;
static const char* ATTRIBUTE_NAME_TEX_COORD7;
static const char* ATTRIBUTE_NAME_NORMAL;
static const char* ATTRIBUTE_NAME_BLEND_WEIGHT;
static const char* ATTRIBUTE_NAME_BLEND_INDEX;

View File

@ -172,18 +172,16 @@ void MeshCommand::restoreRenderState()
s_cullFace = 0;
}
void MeshCommand::genMaterialID(GLuint texID, void* glProgramState, void* mesh, const BlendFunc& blend)
void MeshCommand::genMaterialID(GLuint texID, void* glProgramState, GLuint vertexBuffer, GLuint indexBuffer, const BlendFunc& blend)
{
int* intstate = static_cast<int*>(glProgramState);
int* intmesh = static_cast<int*>(mesh);
int statekey[] = {intstate[0], 0}, meshkey[] = {intmesh[0], 0};
int statekey[] = {intstate[0], 0};
if (sizeof(void*) > sizeof(int))
{
statekey[1] = intstate[1];
meshkey[1] = intmesh[1];
}
int intArray[] = {(int)texID, statekey[0], statekey[1], meshkey[0], meshkey[1], (int)blend.src, (int)blend.dst};
int intArray[] = {(int)texID, statekey[0], statekey[1], (int)vertexBuffer, (int)indexBuffer, (int)blend.src, (int)blend.dst};
_materialID = XXH32((const void*)intArray, sizeof(intArray), 0);
}

View File

@ -70,7 +70,7 @@ public:
void batchDraw();
void postBatchDraw();
void genMaterialID(GLuint texID, void* glProgramState, void* mesh, const BlendFunc& blend);
void genMaterialID(GLuint texID, void* glProgramState, GLuint vertexBuffer, GLuint indexBuffer, const BlendFunc& blend);
uint32_t getMaterialID() const { return _materialID; }

View File

@ -353,7 +353,6 @@ void Camera3DTestDemo::addNewSpriteWithCoords(Vec3 p,std::string fileName,bool p
{
auto sprite = Sprite3D::create(fileName);
sprite->setScale(1);
_layer3D->addChild(sprite);
float globalZOrder=sprite->getGlobalZOrder();
sprite->setPosition3D( Vec3( p.x, p.y,p.z) );

View File

@ -26,10 +26,10 @@
#include "Sprite3DTest.h"
#include "3d/CCAnimation3D.h"
#include "3d/CCAnimate3D.h"
#include "3d/CCSubMesh.h"
#include "3d/CCAttachNode.h"
#include "3d/CCRay.h"
#include "3d/CCSprite3D.h"
#include "renderer/CCVertexIndexBuffer.h"
#include "DrawNode3D.h"
#include <algorithm>
@ -59,6 +59,7 @@ static std::function<Layer*()> createFunctions[] =
#endif
CL(Animate3DTest),
CL(AttachmentTest),
CL(Sprite3DReskinTest),
CL(Sprite3DWithOBBPerfromanceTest),
CL(Sprite3DMirrorTest)
};
@ -488,7 +489,7 @@ void Effect3DOutline::setTarget(EffectSprite3D *sprite)
if(sprite != _sprite)
{
GLProgram* glprogram;
if(!sprite->getSkin())
if(!sprite->getMesh()->getSkin())
glprogram = GLProgram::createWithFilenames(_vertShaderFile, _fragShaderFile);
else
glprogram = GLProgram::createWithFilenames(_vertSkinnedShaderFile, _fragSkinnedShaderFile);
@ -544,22 +545,21 @@ void Effect3DOutline::draw(const Mat4 &transform)
auto mesh = _sprite->getMesh();
glBindBuffer(GL_ARRAY_BUFFER, mesh->getVertexBuffer());
if(_sprite && _sprite->getSkin())
auto skin = _sprite->getMesh()->getSkin();
if(_sprite && skin)
{
auto function = std::bind(MatrixPalleteCallBack, std::placeholders::_1, std::placeholders::_2,
_sprite->getSkin()->getMatrixPaletteSize(), (float*)_sprite->getSkin()->getMatrixPalette());
skin->getMatrixPaletteSize(), (float*)skin->getMatrixPalette());
_glProgramState->setUniformCallback("u_matrixPalette", function);
}
if(_sprite)
_glProgramState->apply(transform);
for (ssize_t i = 0; i < mesh->getSubMeshCount(); i++) {
auto submesh = mesh->getSubMesh((int)i);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, submesh->getIndexBuffer());
glDrawElements((GLenum)submesh->getPrimitiveType(), (GLsizei)submesh->getIndexCount(), (GLenum)submesh->getIndexFormat(), 0);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, submesh->getIndexCount());
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->getIndexBuffer());
glDrawElements(mesh->getPrimitiveType(), mesh->getIndexCount(), mesh->getIndexFormat(), 0);
CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, mesh->getIndexCount());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisable(GL_DEPTH_TEST);
@ -998,7 +998,219 @@ void AttachmentTest::onTouchesEnded(const std::vector<Touch*>& touches, Event* e
}
_hasWeapon = !_hasWeapon;
}
Sprite3DReskinTest::Sprite3DReskinTest()
: _sprite(nullptr)
{
auto s = Director::getInstance()->getWinSize();
addNewSpriteWithCoords( Vec2(s.width/2, s.height/2) );
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesEnded = CC_CALLBACK_2(Sprite3DReskinTest::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
TTFConfig ttfConfig("fonts/arial.ttf", 20);
auto label1 = Label::createWithTTF(ttfConfig,"Hair");
auto item1 = MenuItemLabel::create(label1,CC_CALLBACK_1(Sprite3DReskinTest::menuCallback_switchHair,this) );
auto label2 = Label::createWithTTF(ttfConfig,"Glasses");
auto item2 = MenuItemLabel::create(label2, CC_CALLBACK_1(Sprite3DReskinTest::menuCallback_switchGlasses,this) );
auto label3 = Label::createWithTTF(ttfConfig,"Coat");
auto item3 = MenuItemLabel::create(label3,CC_CALLBACK_1(Sprite3DReskinTest::menuCallback_switchCoat,this) );
auto label4 = Label::createWithTTF(ttfConfig,"Pants");
auto item4 = MenuItemLabel::create(label4, CC_CALLBACK_1(Sprite3DReskinTest::menuCallback_switchPants,this) );
auto label5 = Label::createWithTTF(ttfConfig,"Shoes");
auto item5 = MenuItemLabel::create(label5,CC_CALLBACK_1(Sprite3DReskinTest::menuCallback_switchShoes,this) );
item1->setPosition( Vec2(VisibleRect::left().x+50, VisibleRect::bottom().y+item1->getContentSize().height*4 ) );
item2->setPosition( Vec2(VisibleRect::left().x+50, VisibleRect::bottom().y+item1->getContentSize().height *5 ) );
item3->setPosition( Vec2(VisibleRect::left().x+50, VisibleRect::bottom().y+item1->getContentSize().height*6 ) );
item4->setPosition( Vec2(VisibleRect::left().x+50, VisibleRect::bottom().y+item1->getContentSize().height *7 ) );
item5->setPosition( Vec2(VisibleRect::left().x+50, VisibleRect::bottom().y+item1->getContentSize().height *8 ) );
auto pMenu1 = CCMenu::create(item1,item2,item3,item4,item5,NULL);
pMenu1->setPosition(Vec2(0,0));
this->addChild(pMenu1, 10);
}
void Sprite3DReskinTest::menuCallback_switchHair(Ref* sender)
{
_useHairId++;
if(_useHairId > 1 )
{
_useHairId = 0;
}
if(_useHairId >= 0 && _sprite)
{
for(int i = 0; i < 2; i++ )
{
auto subMesh = _sprite->getMeshByName(_girlHair[i]);
if(subMesh)
{
if(i == _useHairId )
{
subMesh->setVisible(true);
}
else
{
subMesh->setVisible(false);
}
}
}
}
}
void Sprite3DReskinTest::menuCallback_switchGlasses(Ref* sender)
{
auto subMesh = _sprite->getMeshByName("Girl_Yanjing_01");
if(subMesh)
{
if(subMesh->isVisible())
{
subMesh->setVisible(false);
}
else
{
subMesh->setVisible(true);
}
}
}
void Sprite3DReskinTest::menuCallback_switchCoat(Ref* sender)
{
_useUpBodyId++;
if(_useUpBodyId > 1 )
{
_useUpBodyId = 0;
}
if(_useUpBodyId >= 0 && _sprite)
{
for(int i = 0; i < 2; i++ )
{
auto subMesh = _sprite->getMeshByName(_girlUpperBody[i]);
if(subMesh)
{
if(i == _useUpBodyId )
{
subMesh->setVisible(true);
}
else
{
subMesh->setVisible(false);
}
}
}
}
}
void Sprite3DReskinTest::menuCallback_switchPants(Ref* sender)
{
_usePantsId++;
if(_usePantsId > 1 )
{
_usePantsId = 0;
}
if(_usePantsId >= 0 && _sprite)
{
for(int i = 0; i < 2; i++ )
{
auto subMesh = _sprite->getMeshByName(_girlPants[i]);
if(subMesh)
{
if(i == _usePantsId )
{
subMesh->setVisible(true);
}
else
{
subMesh->setVisible(false);
}
}
}
}
}
void Sprite3DReskinTest::menuCallback_switchShoes(Ref* sender)
{
_useShoesId++;
if(_useShoesId > 1 )
{
_useShoesId = 0;
}
if(_useShoesId >= 0 && _sprite)
{
for(int i = 0; i < 2; i++ )
{
auto subMesh = _sprite->getMeshByName(_girlShoes[i]);
if(subMesh)
{
if(i == _useShoesId )
{
subMesh->setVisible(true);
}
else
{
subMesh->setVisible(false);
}
}
}
}
}
std::string Sprite3DReskinTest::title() const
{
return "Testing Sprite3D Reskin";
}
std::string Sprite3DReskinTest::subtitle() const
{
return "";
}
void Sprite3DReskinTest::addNewSpriteWithCoords(Vec2 p)
{
_girlPants[0]= "Girl_Xiashen_01";
_girlPants[1]= "Girl_Xiashen_02";
_girlUpperBody[0] = "Girl_Shangshen_01";
_girlUpperBody[1] = "Girl_Shangshen_02";
_girlShoes[0] = "Girl_Xie_01";
_girlShoes[1] = "Girl_Xie_02";
_girlHair[0]= "Girl_Toufa_01";
_girlHair[1]= "Girl_Toufa_02";
_usePantsId = 0;
_useUpBodyId = 0;
_useShoesId =0;
_useHairId = 0;
std::string fileName = "Sprite3DTest/ReskinGirl.c3b";
auto sprite = Sprite3D::create(fileName);
sprite->setScale(4);
sprite->setRotation3D(Vec3(0,0,0));
auto girlPants = sprite->getMeshByName(_girlPants[1]);
if(girlPants)
{
girlPants->setVisible(false);
}
auto girlShoes = sprite->getMeshByName(_girlShoes[1]);
if(girlShoes)
{
girlShoes->setVisible(false);
}
auto girlHair = sprite->getMeshByName(_girlHair[1]);
if(girlHair)
{
girlHair->setVisible(false);
}
auto girlUpBody = sprite->getMeshByName( _girlUpperBody[1]);
if(girlUpBody)
{
girlUpBody->setVisible(false);
}
addChild(sprite);
sprite->setPosition( Vec2( p.x, p.y-60) );
auto animation = Animation3D::create(fileName);
if (animation)
{
auto animate = Animate3D::create(animation);
sprite->runAction(RepeatForever::create(animate));
}
_sprite = sprite;
}
void Sprite3DReskinTest::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
{
}
Sprite3DWithOBBPerfromanceTest::Sprite3DWithOBBPerfromanceTest()
{
auto listener = EventListenerTouchAllAtOnce::create();

View File

@ -246,6 +246,31 @@ protected:
cocos2d::Sprite3D* _sprite;
};
class Sprite3DReskinTest : public Sprite3DTestDemo
{
public:
CREATE_FUNC(Sprite3DReskinTest);
Sprite3DReskinTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
void onTouchesEnded(const std::vector<Touch*>& touches, Event* event);
void addNewSpriteWithCoords(Vec2 p);
void menuCallback_switchHair(Ref* sender);
void menuCallback_switchGlasses(Ref* sender);
void menuCallback_switchCoat(Ref* sender);
void menuCallback_switchPants(Ref* sender);
void menuCallback_switchShoes(Ref* sender);
protected:
std::string _girlPants[2];
int _usePantsId;
std::string _girlUpperBody[2];
int _useUpBodyId;
std::string _girlShoes[2];
int _useShoesId;
std::string _girlHair[2];
int _useHairId;
cocos2d::Sprite3D* _sprite;
};
class Sprite3DWithOBBPerfromanceTest : public Sprite3DTestDemo
{
public:

View File

@ -60,6 +60,7 @@ Controller g_aTestNames[] = {
{ "FileUtils", []() { return new FileUtilsTestScene(); } },
{ "Fonts", []() { return new FontTestScene(); } },
{ "Interval", [](){return new IntervalTestScene(); } },
{ "Node: Camera 3D Test", [](){ return new Camera3DTestScene(); }},
{ "Node: Clipping", []() { return new ClippingNodeTestScene(); } },
{ "Node: Draw", [](){return new DrawPrimitivesTestScene();} },
{ "Node: Label - New API", [](){return new AtlasTestSceneNew(); } },
@ -76,7 +77,6 @@ Controller g_aTestNames[] = {
{ "Node: Spine", []() { return new SpineTestScene(); } },
{ "Node: Sprite", [](){return new SpriteTestScene(); } },
{ "Node: Sprite3D", [](){ return new Sprite3DTestScene(); }},
{ "Node: Camera 3D Test", [](){ return new Camera3DTestScene(); }},
{ "Node: TileMap", [](){return new TileMapTestScene(); } },
#if CC_TARGET_PLATFORM != CC_PLATFORM_WP8
{ "Node: FastTileMap", [](){return new TileMapTestSceneNew(); } },

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,7 @@ headers = %(cocosdir)s/cocos/3d/cocos3d.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 = .*3D$ Mesh SubMeshState AttachNode
classes = .*3D$ Mesh AttachNode
# 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
@ -35,9 +35,9 @@ classes = .*3D$ Mesh SubMeshState AttachNode
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip = Mesh::[create getOriginAABB],
SubMeshState::[getSkin setSkin create],
Sprite3D::[getSkin getSubMeshState getAABB],
skip = Mesh::[create getAABB],
Sprite3D::[getSkin getAABB],
Skeleton3D::[create],
Animation3D::[getBoneCurveByName],
Animation3DCache::[*],
Sprite3DMaterialCache::[*],