Merge pull request #7085 from super626/v3

Sprite3D animation
This commit is contained in:
minggo 2014-06-17 21:05:58 +08:00
commit 26cca348cb
44 changed files with 24823 additions and 268 deletions

View File

@ -1741,10 +1741,12 @@
B29594CB1926D61F003EEF37 /* CCSprite3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BD1926D61F003EEF37 /* CCSprite3D.cpp */; };
B29594CC1926D61F003EEF37 /* CCSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594BE1926D61F003EEF37 /* CCSprite3D.h */; };
B29594CD1926D61F003EEF37 /* CCSprite3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594BE1926D61F003EEF37 /* CCSprite3D.h */; };
B29594CE1926D61F003EEF37 /* CCSprite3DDataCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BF1926D61F003EEF37 /* CCSprite3DDataCache.cpp */; };
B29594CF1926D61F003EEF37 /* CCSprite3DDataCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BF1926D61F003EEF37 /* CCSprite3DDataCache.cpp */; };
B29594D01926D61F003EEF37 /* CCSprite3DDataCache.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594C01926D61F003EEF37 /* CCSprite3DDataCache.h */; };
B29594D11926D61F003EEF37 /* CCSprite3DDataCache.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594C01926D61F003EEF37 /* CCSprite3DDataCache.h */; };
B29594CE1926D61F003EEF37 /* CCSprite3DMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BF1926D61F003EEF37 /* CCSprite3DMaterial.cpp */; };
B29594CF1926D61F003EEF37 /* CCSprite3DMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B29594BF1926D61F003EEF37 /* CCSprite3DMaterial.cpp */; };
B29594D01926D61F003EEF37 /* CCSprite3DMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594C01926D61F003EEF37 /* CCSprite3DMaterial.h */; };
B29594D11926D61F003EEF37 /* CCSprite3DMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = B29594C01926D61F003EEF37 /* CCSprite3DMaterial.h */; };
B2D3D3B91948613300BA4831 /* CCBundle3DData.h in Headers */ = {isa = PBXBuildFile; fileRef = B2D3D3B81948613300BA4831 /* CCBundle3DData.h */; };
B2D3D3BA1948613300BA4831 /* CCBundle3DData.h in Headers */ = {isa = PBXBuildFile; fileRef = B2D3D3B81948613300BA4831 /* CCBundle3DData.h */; };
B37510711823AC9F00B3BA6A /* CCPhysicsBodyInfo_chipmunk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B37510451823AC7B00B3BA6A /* CCPhysicsBodyInfo_chipmunk.cpp */; };
B37510721823AC9F00B3BA6A /* CCPhysicsBodyInfo_chipmunk.h in Headers */ = {isa = PBXBuildFile; fileRef = B37510461823AC7B00B3BA6A /* CCPhysicsBodyInfo_chipmunk.h */; };
B37510731823AC9F00B3BA6A /* CCPhysicsContactInfo_chipmunk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B37510471823AC7B00B3BA6A /* CCPhysicsContactInfo_chipmunk.cpp */; };
@ -1773,6 +1775,24 @@
B3AF01A31842FBA400A98B85 /* b2MotorJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = B3AF019F1842FBA400A98B85 /* b2MotorJoint.h */; };
B3B12A5A17E7F44000026B4A /* libchipmunk Mac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A03F2CB81780BD04006731B9 /* libchipmunk Mac.a */; };
B3B12A5B17E7F45C00026B4A /* libchipmunk iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A07A4F3B178387670073F6A7 /* libchipmunk iOS.a */; };
B6AAF84119404E0D0069DE01 /* CCBundle3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6AAF83F19404E0D0069DE01 /* CCBundle3D.cpp */; };
B6AAF84219404E0D0069DE01 /* CCBundle3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6AAF83F19404E0D0069DE01 /* CCBundle3D.cpp */; };
B6AAF84319404E0D0069DE01 /* CCBundle3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6AAF84019404E0D0069DE01 /* CCBundle3D.h */; };
B6AAF84419404E0D0069DE01 /* CCBundle3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6AAF84019404E0D0069DE01 /* CCBundle3D.h */; };
B6ACD897193D6693005E0B8A /* CCMeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6ACD895193D6693005E0B8A /* CCMeshSkin.cpp */; };
B6ACD898193D6693005E0B8A /* CCMeshSkin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6ACD895193D6693005E0B8A /* CCMeshSkin.cpp */; };
B6ACD899193D6693005E0B8A /* CCMeshSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = B6ACD896193D6693005E0B8A /* CCMeshSkin.h */; };
B6ACD89A193D6693005E0B8A /* CCMeshSkin.h in Headers */ = {isa = PBXBuildFile; fileRef = B6ACD896193D6693005E0B8A /* CCMeshSkin.h */; };
B6ACD89E193DC0CC005E0B8A /* CCAnimate3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6ACD89C193DC0CC005E0B8A /* CCAnimate3D.cpp */; };
B6ACD89F193DC0CC005E0B8A /* CCAnimate3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6ACD89C193DC0CC005E0B8A /* CCAnimate3D.cpp */; };
B6ACD8A0193DC0CC005E0B8A /* CCAnimate3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6ACD89D193DC0CC005E0B8A /* CCAnimate3D.h */; };
B6ACD8A1193DC0CC005E0B8A /* CCAnimate3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6ACD89D193DC0CC005E0B8A /* CCAnimate3D.h */; };
B6B2633F19381FBF0088FE25 /* CCAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B2633C19381FBF0088FE25 /* CCAnimationCurve.h */; };
B6B2634019381FBF0088FE25 /* CCAnimationCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B2633C19381FBF0088FE25 /* CCAnimationCurve.h */; };
B6B26343193884D60088FE25 /* CCAnimation3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6B26341193884D60088FE25 /* CCAnimation3D.cpp */; };
B6B26344193884D60088FE25 /* CCAnimation3D.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6B26341193884D60088FE25 /* CCAnimation3D.cpp */; };
B6B26345193884D60088FE25 /* CCAnimation3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B26342193884D60088FE25 /* CCAnimation3D.h */; };
B6B26346193884D60088FE25 /* CCAnimation3D.h in Headers */ = {isa = PBXBuildFile; fileRef = B6B26342193884D60088FE25 /* CCAnimation3D.h */; };
ED9C6A9418599AD8000A5232 /* CCNodeGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */; };
ED9C6A9518599AD8000A5232 /* CCNodeGrid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */; };
ED9C6A9618599AD8000A5232 /* CCNodeGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = ED9C6A9318599AD8000A5232 /* CCNodeGrid.h */; };
@ -2792,8 +2812,9 @@
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>"; };
B29594BE1926D61F003EEF37 /* CCSprite3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSprite3D.h; sourceTree = "<group>"; };
B29594BF1926D61F003EEF37 /* CCSprite3DDataCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSprite3DDataCache.cpp; sourceTree = "<group>"; };
B29594C01926D61F003EEF37 /* CCSprite3DDataCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSprite3DDataCache.h; sourceTree = "<group>"; };
B29594BF1926D61F003EEF37 /* CCSprite3DMaterial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCSprite3DMaterial.cpp; sourceTree = "<group>"; };
B29594C01926D61F003EEF37 /* CCSprite3DMaterial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSprite3DMaterial.h; sourceTree = "<group>"; };
B2D3D3B81948613300BA4831 /* CCBundle3DData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBundle3DData.h; sourceTree = "<group>"; };
B37510451823AC7B00B3BA6A /* CCPhysicsBodyInfo_chipmunk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCPhysicsBodyInfo_chipmunk.cpp; sourceTree = "<group>"; };
B37510461823AC7B00B3BA6A /* CCPhysicsBodyInfo_chipmunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPhysicsBodyInfo_chipmunk.h; sourceTree = "<group>"; };
B37510471823AC7B00B3BA6A /* CCPhysicsContactInfo_chipmunk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCPhysicsContactInfo_chipmunk.cpp; sourceTree = "<group>"; };
@ -2807,6 +2828,16 @@
B375104F1823AC7B00B3BA6A /* CCPhysicsWorldInfo_chipmunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCPhysicsWorldInfo_chipmunk.h; sourceTree = "<group>"; };
B3AF019E1842FBA400A98B85 /* b2MotorJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MotorJoint.cpp; sourceTree = "<group>"; };
B3AF019F1842FBA400A98B85 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = "<group>"; };
B6AAF83F19404E0D0069DE01 /* CCBundle3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCBundle3D.cpp; sourceTree = "<group>"; };
B6AAF84019404E0D0069DE01 /* CCBundle3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBundle3D.h; sourceTree = "<group>"; };
B6ACD895193D6693005E0B8A /* CCMeshSkin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCMeshSkin.cpp; sourceTree = "<group>"; };
B6ACD896193D6693005E0B8A /* CCMeshSkin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCMeshSkin.h; sourceTree = "<group>"; };
B6ACD89C193DC0CC005E0B8A /* CCAnimate3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAnimate3D.cpp; sourceTree = "<group>"; };
B6ACD89D193DC0CC005E0B8A /* CCAnimate3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAnimate3D.h; sourceTree = "<group>"; };
B6B2633B19381FBF0088FE25 /* CCAnimationCurve.inl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CCAnimationCurve.inl; sourceTree = "<group>"; };
B6B2633C19381FBF0088FE25 /* CCAnimationCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAnimationCurve.h; sourceTree = "<group>"; };
B6B26341193884D60088FE25 /* CCAnimation3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCAnimation3D.cpp; sourceTree = "<group>"; };
B6B26342193884D60088FE25 /* CCAnimation3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCAnimation3D.h; sourceTree = "<group>"; };
ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CCNodeGrid.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
ED9C6A9318599AD8000A5232 /* CCNodeGrid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCNodeGrid.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -4817,14 +4848,25 @@
B29594B81926D61F003EEF37 /* 3d */ = {
isa = PBXGroup;
children = (
B6AAF83F19404E0D0069DE01 /* CCBundle3D.cpp */,
B6AAF84019404E0D0069DE01 /* CCBundle3D.h */,
B6ACD89C193DC0CC005E0B8A /* CCAnimate3D.cpp */,
B6ACD89D193DC0CC005E0B8A /* CCAnimate3D.h */,
B6ACD895193D6693005E0B8A /* CCMeshSkin.cpp */,
B6ACD896193D6693005E0B8A /* CCMeshSkin.h */,
B6B26341193884D60088FE25 /* CCAnimation3D.cpp */,
B6B26342193884D60088FE25 /* CCAnimation3D.h */,
B6B2633B19381FBF0088FE25 /* CCAnimationCurve.inl */,
B6B2633C19381FBF0088FE25 /* CCAnimationCurve.h */,
B29594B91926D61F003EEF37 /* CCMesh.cpp */,
B29594BA1926D61F003EEF37 /* CCMesh.h */,
B29594BB1926D61F003EEF37 /* CCObjLoader.cpp */,
B29594BC1926D61F003EEF37 /* CCObjLoader.h */,
B29594BD1926D61F003EEF37 /* CCSprite3D.cpp */,
B29594BE1926D61F003EEF37 /* CCSprite3D.h */,
B29594BF1926D61F003EEF37 /* CCSprite3DDataCache.cpp */,
B29594C01926D61F003EEF37 /* CCSprite3DDataCache.h */,
B29594BF1926D61F003EEF37 /* CCSprite3DMaterial.cpp */,
B29594C01926D61F003EEF37 /* CCSprite3DMaterial.h */,
B2D3D3B81948613300BA4831 /* CCBundle3DData.h */,
);
name = 3d;
path = ../cocos/3d;
@ -4851,7 +4893,7 @@
06CAAAC9186AD7EE0012A414 /* TriggerMng.h in Headers */,
2905FA6018CF08D100240AA3 /* UILayoutParameter.h in Headers */,
50ABBEA51925AB6F00A911A9 /* CCScriptSupport.h in Headers */,
B29594D01926D61F003EEF37 /* CCSprite3DDataCache.h in Headers */,
B29594D01926D61F003EEF37 /* CCSprite3DMaterial.h in Headers */,
1ABA68B01888D700007D1BB4 /* CCFontCharMap.h in Headers */,
5034CA3F191D591100CE6051 /* ccShader_Position_uColor.vert in Headers */,
50ABBD461925AB0000A911A9 /* CCVertex.h in Headers */,
@ -4892,6 +4934,7 @@
50ABBD8D1925AB4100A911A9 /* CCGLProgram.h in Headers */,
50ABBEA11925AB6F00A911A9 /* CCScheduler.h in Headers */,
50ABBDB71925AB4100A911A9 /* CCTexture2D.h in Headers */,
B2D3D3B91948613300BA4831 /* CCBundle3DData.h in Headers */,
2905FA6C18CF08D100240AA3 /* UIPageView.h in Headers */,
50FCEB9518C72017004AD434 /* ButtonReader.h in Headers */,
50ABBE811925AB6F00A911A9 /* CCEventType.h in Headers */,
@ -5183,6 +5226,11 @@
1A8C5A0F180E930E00EF57C3 /* DictionaryHelper.h in Headers */,
50FCEBBD18C72017004AD434 /* TextBMFontReader.h in Headers */,
50FCEBCB18C72017004AD434 /* WidgetReaderProtocol.h in Headers */,
B6B2633F19381FBF0088FE25 /* CCAnimationCurve.h in Headers */,
B6B26345193884D60088FE25 /* CCAnimation3D.h in Headers */,
B6ACD899193D6693005E0B8A /* CCMeshSkin.h in Headers */,
B6ACD8A0193DC0CC005E0B8A /* CCAnimate3D.h in Headers */,
B6AAF84319404E0D0069DE01 /* CCBundle3D.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -5339,7 +5387,7 @@
50ABBD3B1925AB0000A911A9 /* CCAffineTransform.h in Headers */,
5034CA38191D591100CE6051 /* ccShader_PositionColorLengthTexture.vert in Headers */,
50ABBE7C1925AB6F00A911A9 /* CCEventMouse.h in Headers */,
B29594D11926D61F003EEF37 /* CCSprite3DDataCache.h in Headers */,
B29594D11926D61F003EEF37 /* CCSprite3DMaterial.h in Headers */,
46A171011807CECB005B8026 /* CCPhysicsJoint.h in Headers */,
46A170FD1807CECB005B8026 /* CCPhysicsBody.h in Headers */,
2905FA6118CF08D100240AA3 /* UILayoutParameter.h in Headers */,
@ -5375,6 +5423,7 @@
1A01C68918F57BE800EFE3A6 /* CCBool.h in Headers */,
1A57007C180BC5A10088DEC7 /* CCActionInstant.h in Headers */,
50ABBE781925AB6F00A911A9 /* CCEventListenerTouch.h in Headers */,
B2D3D3BA1948613300BA4831 /* CCBundle3DData.h in Headers */,
B37510861823ACA100B3BA6A /* CCPhysicsWorldInfo_chipmunk.h in Headers */,
1A570080180BC5A10088DEC7 /* CCActionInterval.h in Headers */,
1A570084180BC5A10088DEC7 /* CCActionManager.h in Headers */,
@ -5678,6 +5727,11 @@
1A8C5A08180E930E00EF57C3 /* CocoStudio.h in Headers */,
1A8C5A10180E930E00EF57C3 /* DictionaryHelper.h in Headers */,
50ABBEB21925AB6F00A911A9 /* CCUserDefault.h in Headers */,
B6B2634019381FBF0088FE25 /* CCAnimationCurve.h in Headers */,
B6B26346193884D60088FE25 /* CCAnimation3D.h in Headers */,
B6ACD89A193D6693005E0B8A /* CCMeshSkin.h in Headers */,
B6ACD8A1193DC0CC005E0B8A /* CCAnimate3D.h in Headers */,
B6AAF84419404E0D0069DE01 /* CCBundle3D.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -6289,7 +6343,7 @@
1A8C59C3180E930E00EF57C3 /* CCComController.cpp in Sources */,
2905FA5218CF08D100240AA3 /* UIImageView.cpp in Sources */,
50ABBDBD1925AB4100A911A9 /* CCTextureCache.cpp in Sources */,
B29594CE1926D61F003EEF37 /* CCSprite3DDataCache.cpp in Sources */,
B29594CE1926D61F003EEF37 /* CCSprite3DMaterial.cpp in Sources */,
299754F4193EC95400A54AC3 /* ObjectFactory.cpp in Sources */,
2905FA7C18CF08D100240AA3 /* UIText.cpp in Sources */,
50FCEB9F18C72017004AD434 /* LayoutReader.cpp in Sources */,
@ -6329,6 +6383,10 @@
50ABBE931925AB6F00A911A9 /* CCProfiling.cpp in Sources */,
1ABA68AE1888D700007D1BB4 /* CCFontCharMap.cpp in Sources */,
2905FA4618CF08D100240AA3 /* UIButton.cpp in Sources */,
B6B26343193884D60088FE25 /* CCAnimation3D.cpp in Sources */,
B6ACD897193D6693005E0B8A /* CCMeshSkin.cpp in Sources */,
B6ACD89E193DC0CC005E0B8A /* CCAnimate3D.cpp in Sources */,
B6AAF84119404E0D0069DE01 /* CCBundle3D.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -6535,7 +6593,7 @@
50ABBE3E1925AB6F00A911A9 /* CCDataVisitor.cpp in Sources */,
1A57009F180BC5D20088DEC7 /* CCNode.cpp in Sources */,
B37510831823ACA100B3BA6A /* CCPhysicsShapeInfo_chipmunk.cpp in Sources */,
B29594CF1926D61F003EEF37 /* CCSprite3DDataCache.cpp in Sources */,
B29594CF1926D61F003EEF37 /* CCSprite3DMaterial.cpp in Sources */,
1A57010F180BC8EE0088DEC7 /* CCDrawingPrimitives.cpp in Sources */,
1A570113180BC8EE0088DEC7 /* CCDrawNode.cpp in Sources */,
1A57011C180BC90D0088DEC7 /* CCGrabber.cpp in Sources */,
@ -6770,6 +6828,10 @@
1ABA68AF1888D700007D1BB4 /* CCFontCharMap.cpp in Sources */,
50ABBE7A1925AB6F00A911A9 /* CCEventMouse.cpp in Sources */,
50ABBD981925AB4100A911A9 /* CCGLProgramStateCache.cpp in Sources */,
B6B26344193884D60088FE25 /* CCAnimation3D.cpp in Sources */,
B6ACD898193D6693005E0B8A /* CCMeshSkin.cpp in Sources */,
B6ACD89F193DC0CC005E0B8A /* CCAnimate3D.cpp in Sources */,
B6AAF84219404E0D0069DE01 /* CCBundle3D.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -528,6 +528,8 @@ void RepeatForever::step(float dt)
if (_innerAction->isDone())
{
float diff = _innerAction->getElapsed() - _innerAction->getDuration();
if (diff > _innerAction->getDuration())
diff = fmodf(diff, _innerAction->getDuration());
_innerAction->startWithTarget(_target);
// to prevent jerk. issue #390, 1247
_innerAction->step(0.0f);

View File

@ -77,7 +77,7 @@
</PreBuildEvent>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(EngineRoot)external\sqlite3\include;$(EngineRoot)external\unzip;$(EngineRoot)external\edtaa3func;$(EngineRoot)external\tinyxml2;$(EngineRoot)external\png\include\win32;$(EngineRoot)external\jpeg\include\win32;$(EngineRoot)external\tiff\include\win32;$(EngineRoot)external\webp\include\win32;$(EngineRoot)external\freetype2\include\win32;$(EngineRoot)external\win32-specific\icon\include;$(EngineRoot)external\win32-specific\zlib\include;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)external\xxhash;$(EngineRoot)external\ConvertUTF;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A\include;$(EngineRoot)external\sqlite3\include;$(EngineRoot)external\unzip;$(EngineRoot)external\edtaa3func;$(EngineRoot)external\tinyxml2;$(EngineRoot)external\png\include\win32;$(EngineRoot)external\jpeg\include\win32;$(EngineRoot)external\tiff\include\win32;$(EngineRoot)external\webp\include\win32;$(EngineRoot)external\freetype2\include\win32;$(EngineRoot)external\win32-specific\icon\include;$(EngineRoot)external\win32-specific\zlib\include;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)external\xxhash;$(EngineRoot)external\ConvertUTF;$(EngineRoot)external;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_LIB;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -175,10 +175,14 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClCompile Include="..\..\external\unzip\ioapi.cpp" />
<ClCompile Include="..\..\external\unzip\unzip.cpp" />
<ClCompile Include="..\..\external\xxhash\xxhash.c" />
<ClCompile Include="..\3d\CCAnimate3D.cpp" />
<ClCompile Include="..\3d\CCAnimation3D.cpp" />
<ClCompile Include="..\3d\CCBundle3D.cpp" />
<ClCompile Include="..\3d\CCMesh.cpp" />
<ClCompile Include="..\3d\CCMeshSkin.cpp" />
<ClCompile Include="..\3d\CCObjLoader.cpp" />
<ClCompile Include="..\3d\CCSprite3D.cpp" />
<ClCompile Include="..\3d\CCSprite3DDataCache.cpp" />
<ClCompile Include="..\3d\CCSprite3DMaterial.cpp" />
<ClCompile Include="..\base\atitc.cpp" />
<ClCompile Include="..\base\base64.cpp" />
<ClCompile Include="..\base\CCAutoreleasePool.cpp" />
@ -347,10 +351,16 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClInclude Include="..\..\external\unzip\ioapi.h" />
<ClInclude Include="..\..\external\unzip\unzip.h" />
<ClInclude Include="..\..\external\xxhash\xxhash.h" />
<ClInclude Include="..\3d\CCAnimate3D.h" />
<ClInclude Include="..\3d\CCAnimation3D.h" />
<ClInclude Include="..\3d\CCAnimationCurve.h" />
<ClInclude Include="..\3d\CCBundle3D.h" />
<ClInclude Include="..\3d\CCBundle3DData.h" />
<ClInclude Include="..\3d\CCMesh.h" />
<ClInclude Include="..\3d\CCMeshSkin.h" />
<ClInclude Include="..\3d\CCObjLoader.h" />
<ClInclude Include="..\3d\CCSprite3D.h" />
<ClInclude Include="..\3d\CCSprite3DDataCache.h" />
<ClInclude Include="..\3d\CCSprite3DMaterial.h" />
<ClInclude Include="..\base\atitc.h" />
<ClInclude Include="..\base\base64.h" />
<ClInclude Include="..\base\CCAutoreleasePool.h" />
@ -537,6 +547,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\win32-specific\gles\prebuilt\*.*" "$(Ou
<ClInclude Include="CCTweenFunction.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\3d\CCAnimationCurve.inl" />
<None Include="..\math\Mat4.inl" />
<None Include="..\math\MathUtil.inl" />
<None Include="..\math\MathUtilNeon.inl" />

View File

@ -562,12 +562,24 @@
<ClCompile Include="..\3d\CCSprite3D.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\3d\CCSprite3DDataCache.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\base\ObjectFactory.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="..\3d\CCBundle3D.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\3d\CCAnimate3D.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\3d\CCMeshSkin.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\3d\CCAnimation3D.cpp">
<Filter>3d</Filter>
</ClCompile>
<ClCompile Include="..\3d\CCSprite3DMaterial.cpp">
<Filter>3d</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\physics\CCPhysicsBody.h">
@ -1144,12 +1156,30 @@
<ClInclude Include="..\3d\CCSprite3D.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCSprite3DDataCache.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\base\ObjectFactory.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCBundle3D.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCAnimate3D.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCAnimationCurve.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCMeshSkin.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCAnimation3D.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCBundle3DData.h">
<Filter>3d</Filter>
</ClInclude>
<ClInclude Include="..\3d\CCSprite3DMaterial.h">
<Filter>3d</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\math\Mat4.inl">
@ -1173,5 +1203,8 @@
<None Include="..\math\Vec4.inl">
<Filter>math</Filter>
</None>
<None Include="..\3d\CCAnimationCurve.inl">
<Filter>3d</Filter>
</None>
</ItemGroup>
</Project>

146
cocos/3d/CCAnimate3D.cpp Normal file
View File

@ -0,0 +1,146 @@
/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "3d/CCAnimate3D.h"
#include "3d/CCAnimation3D.h"
#include "3d/CCSprite3D.h"
#include "3d/CCMeshSkin.h"
#include "base/ccMacros.h"
#include "platform/CCFileUtils.h"
NS_CC_BEGIN
//create Animate3D using Animation.
Animate3D* Animate3D::create(Animation3D* animation)
{
auto animate = new Animate3D();
animate->_animation = animation;
animation->retain();
animate->autorelease();
animate->setDuration(animation->getDuration());
return animate;
}
/** returns a clone of action */
Animate3D* Animate3D::clone() const
{
auto animate = const_cast<Animate3D*>(this);
auto copy = Animate3D::create(animate->_animation);
copy->_speed = _speed;
copy->_elapsed = _elapsed;
copy->_playBack = _playBack;
return copy;
}
/** returns a new action that performs the exactly the reverse action */
Animate3D* Animate3D::reverse() const
{
auto animate = clone();
animate->_playBack = !animate->_playBack;
return animate;
}
//! called before the action start. It will also set the target.
void Animate3D::startWithTarget(Node *target)
{
Sprite3D* sprite = dynamic_cast<Sprite3D*>(target);
CCASSERT(sprite && sprite->getSkin() && _animation, "Animate3D apply to Sprite3D only");
ActionInterval::startWithTarget(target);
_boneCurves.clear();
auto skin = sprite->getSkin();
for (unsigned int i = 0; i < skin->getBoneCount(); i++) {
auto bone = skin->getBoneByIndex(i);
auto curve = _animation->getBoneCurveByName(bone->getName());
if (curve)
{
_boneCurves[bone] = curve;
}
else
{
CCLOG("warning: bone %s not find in animation", bone->getName().c_str());
}
}
}
//! called every frame with it's delta time. DON'T override unless you know what you are doing.
void Animate3D::step(float dt)
{
ActionInterval::step(dt * _speed);
}
void Animate3D::update(float t)
{
if (_target)
{
float transDst[3], rotDst[4], scaleDst[3];
float* trans = nullptr, *rot = nullptr, *scale = nullptr;
if (_playBack)
t = 1 - t;
for (const auto& it : _boneCurves) {
auto bone = it.first;
auto curve = it.second;
if (curve->translateCurve)
{
curve->translateCurve->evaluate(t, transDst, EvaluateType::LINEAR);
trans = &transDst[0];
}
if (curve->rotCurve)
{
curve->rotCurve->evaluate(t, rotDst, EvaluateType::QUAT_SLERP);
rot = &rotDst[0];
}
if (curve->scaleCurve)
{
curve->scaleCurve->evaluate(t, scaleDst, EvaluateType::LINEAR);
scale = &scaleDst[0];
}
bone->setAnimationValue(trans, rot, scale, _weight);
}
}
}
Animate3D::Animate3D()
: _speed(1)
, _weight(1.f)
, _animation(nullptr)
, _playBack(false)
{
}
Animate3D::~Animate3D()
{
CC_SAFE_RELEASE(_animation);
}
NS_CC_END

82
cocos/3d/CCAnimate3D.h Normal file
View File

@ -0,0 +1,82 @@
/****************************************************************************
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 __CCANIMATE3D_H__
#define __CCANIMATE3D_H__
#include <map>
#include "3d/CCAnimation3D.h"
#include "base/ccMacros.h"
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "2d/CCActionInterval.h"
NS_CC_BEGIN
class Animation3D;
class Bone;
/**
* Animate3D
*/
class Animate3D: public ActionInterval
{
public:
//create Animate3D using Animation.
static Animate3D* create(Animation3D* animation);
//
// Overrides
//
virtual void step(float dt) override;
virtual void startWithTarget(Node *target) override;
virtual Animate3D* reverse() const override;
virtual Animate3D *clone() const override;
virtual void update(float t) override;
float getSpeed() const { return _speed; }
void setSpeed(float speed) { _speed = speed; }
bool getPlayBack() const { return _playBack; }
void setPlayBack(bool playBack) { _playBack = playBack; }
CC_CONSTRUCTOR_ACCESS:
Animate3D();
virtual ~Animate3D();
Animation3D* _animation;
float _speed;
float _weight;
bool _playBack;
std::map<Bone*, Animation3D::Curve*> _boneCurves; //weak ref
};
NS_CC_END
#endif // __CCANIMATE3D_H__

238
cocos/3d/CCAnimation3D.cpp Normal file
View File

@ -0,0 +1,238 @@
/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "3d/CCAnimation3D.h"
#include "3d/CCBundle3D.h"
#include "base/ccMacros.h"
#include "platform/CCFileUtils.h"
NS_CC_BEGIN
Animation3D* Animation3D::getOrCreate(const std::string& fileName, const std::string& animationName)
{
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
std::string key = fullPath + "#" + animationName;
auto animation = Animation3DCache::getInstance()->getAnimation(key);
if (animation != nullptr)
return animation;
//load animation here
animation = new Animation3D();
auto bundle = Bundle3D::getInstance();
Animation3DData animationdata;
if (bundle->load(fullPath) && bundle->loadAnimationData(animationName, &animationdata) && animation->init(animationdata))
{
Animation3DCache::getInstance()->addAnimation(key, animation);
animation->autorelease();
}
else
{
CC_SAFE_DELETE(animation);
animation = nullptr;
}
return animation;
}
Animation3D::Curve* Animation3D::getBoneCurveByName(const std::string& name) const
{
auto it = _boneCurves.find(name);
if (it != _boneCurves.end())
return it->second;
return nullptr;
}
Animation3D::Animation3D()
: _duration(0)
{
}
Animation3D::~Animation3D()
{
for (auto itor : _boneCurves) {
CC_SAFE_DELETE(itor.second);
}
}
Animation3D::Curve::Curve()
: translateCurve(nullptr)
, rotCurve(nullptr)
, scaleCurve(nullptr)
{
}
Animation3D::Curve::~Curve()
{
CC_SAFE_RELEASE_NULL(translateCurve);
CC_SAFE_RELEASE_NULL(rotCurve);
CC_SAFE_RELEASE_NULL(scaleCurve);
}
bool Animation3D::init(const Animation3DData &data)
{
_duration = data._totalTime;
for(const auto& iter : data._translationKeys)
{
Curve* curve = _boneCurves[iter.first];
if( curve == nullptr)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
if(iter.second.size() == 0) continue;
std::vector<float> keys;
std::vector<float> values;
for(const auto& keyIter : iter.second)
{
keys.push_back(keyIter._time);
values.push_back(keyIter._key.x);
values.push_back(keyIter._key.y);
values.push_back(keyIter._key.z);
}
curve->translateCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0], (int)keys.size());
if(curve->translateCurve) curve->translateCurve->retain();
}
for(const auto& iter : data._rotationKeys)
{
Curve* curve = _boneCurves[iter.first];
if( curve == nullptr)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
if(iter.second.size() == 0) continue;
std::vector<float> keys;
std::vector<float> values;
for(const auto& keyIter : iter.second)
{
keys.push_back(keyIter._time);
values.push_back(keyIter._key.x);
values.push_back(keyIter._key.y);
values.push_back(keyIter._key.z);
values.push_back(keyIter._key.w);
}
curve->rotCurve = Curve::AnimationCurveQuat::create(&keys[0], &values[0], (int)keys.size());
if(curve->rotCurve) curve->rotCurve->retain();
}
for(const auto& iter : data._scaleKeys)
{
Curve* curve = _boneCurves[iter.first];
if( curve == nullptr)
{
curve = new Curve();
_boneCurves[iter.first] = curve;
}
if(iter.second.size() == 0) continue;
std::vector<float> keys;
std::vector<float> values;
for(const auto& keyIter : iter.second)
{
keys.push_back(keyIter._time);
values.push_back(keyIter._key.x);
values.push_back(keyIter._key.y);
values.push_back(keyIter._key.z);
}
curve->scaleCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0], (int)keys.size());
if(curve->scaleCurve) curve->scaleCurve->retain();
}
return true;
}
////////////////////////////////////////////////////////////////
Animation3DCache* Animation3DCache::_cacheInstance = nullptr;
Animation3DCache* Animation3DCache::getInstance()
{
if (_cacheInstance == nullptr)
_cacheInstance = new Animation3DCache();
return _cacheInstance;
}
void Animation3DCache::destroyInstance()
{
CC_SAFE_DELETE(_cacheInstance);
}
Animation3D* Animation3DCache::getAnimation(const std::string& key)
{
auto it = _animations.find(key);
if (it != _animations.end())
return it->second;
return nullptr;
}
void Animation3DCache::addAnimation(const std::string& key, Animation3D* animation)
{
const auto& it = _animations.find(key);
if (it != _animations.end())
{
return; // already have this key
}
_animations[key] = animation;
animation->retain();
}
void Animation3DCache::removeAllAnimations()
{
for (auto itor : _animations) {
CC_SAFE_RELEASE(itor.second);
}
_animations.clear();
}
void Animation3DCache::removeUnusedAnimation()
{
for (auto itor = _animations.begin(); itor != _animations.end(); ) {
if (itor->second->getReferenceCount() == 1)
{
itor->second->release();
_animations.erase(itor++);
}
else
++itor;
}
}
Animation3DCache::Animation3DCache()
{
}
Animation3DCache::~Animation3DCache()
{
removeAllAnimations();
}
NS_CC_END

105
cocos/3d/CCAnimation3D.h Normal file
View File

@ -0,0 +1,105 @@
/****************************************************************************
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 __CCANIMATION3D_H__
#define __CCANIMATION3D_H__
#include <unordered_map>
#include "3d/CCAnimationCurve.h"
#include "base/ccMacros.h"
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "CCBundle3DData.h"
NS_CC_BEGIN
/**
* static animation data, shared
*/
class Animation3D: public Ref
{
friend class Bundle3D;
public:
class Curve
{
public:
typedef AnimationCurve<3> AnimationCurveVec3;
typedef AnimationCurve<4> AnimationCurveQuat;
AnimationCurveVec3* translateCurve;
AnimationCurveQuat* rotCurve;
AnimationCurveVec3* scaleCurve;
Curve();
~Curve();
};
//read all animation or only the animation with given animationName? animationName == "" read all.
static Animation3D* getOrCreate(const std::string& filename, const std::string& animationName = "");
float getDuration() const { return _duration; }
Curve* getBoneCurveByName(const std::string& name) const;
CC_CONSTRUCTOR_ACCESS:
Animation3D();
virtual ~Animation3D();
bool init(const Animation3DData& data);
protected:
std::unordered_map<std::string, Curve*> _boneCurves;//bone curves map, key bone name, value AnimationCurve
float _duration; //animation duration
};
class Animation3DCache
{
public:
static Animation3DCache* getInstance();
static void destroyInstance();
Animation3D* getAnimation(const std::string& key);
void addAnimation(const std::string& key, Animation3D* animation);
void removeAllAnimations();
void removeUnusedAnimation();
protected:
Animation3DCache();
~Animation3DCache();
static Animation3DCache* _cacheInstance;
std::unordered_map<std::string, Animation3D*> _animations;
};
NS_CC_END
#endif // __CCANIMATION3D_H__

View File

@ -0,0 +1,89 @@
/****************************************************************************
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 __CCANIMATIONCURVE_H__
#define __CCANIMATIONCURVE_H__
#include <unordered_map>
#include <functional>
#include "base/ccTypes.h"
#include "base/CCPlatformMacros.h"
#include "base/CCRef.h"
#include "math/CCMath.h"
NS_CC_BEGIN
enum class EvaluateType
{
LINEAR,
NEAR,
QUAT_SLERP,
USER_FUNCTION,
};
/**
* curve of bone's position, rotation or scale
*/
template <int componentSize>
class AnimationCurve: public Ref
{
public:
//create animation curve
static AnimationCurve* create(float* keytime, float* value, int count);
void evaluate(float time, float* dst, EvaluateType type) const;
void setEvaluateFun(std::function<void(float time, float* dst)> fun);
float getStartTime() const;
float getEndTime() const;
CC_CONSTRUCTOR_ACCESS:
AnimationCurve();
virtual ~AnimationCurve();
/**
* Determine index by time.
*/
int determineIndex(float time) const;
protected:
float* _value; //
float* _keytime; //key time(0 - 1), start time _keytime[0], end time _keytime[_count - 1]
int _count;
int _componentSizeByte; //component size in byte, position and scale 3 * sizeof(float), rotation 4 * sizeof(float)
std::function<void(float time, float* dst)> _evaluateFun;
};
NS_CC_END
#include "CCAnimationCurve.inl"
#endif

View File

@ -0,0 +1,145 @@
#include "3d/CCAnimationCurve.h"
NS_CC_BEGIN
template <int componentSize>
void AnimationCurve<componentSize>::evaluate(float time, float* dst, EvaluateType type) const
{
int floatSize = sizeof(float);
if (_count == 1 || time <= _keytime[0])
{
memcpy(dst, _value, _componentSizeByte);
return;
}
else if (time >= _keytime[_count - 1])
{
memcpy(dst, &_value[(_count - 1) * componentSize], _componentSizeByte);
return;
}
unsigned int index = determineIndex(time);
float scale = (_keytime[index + 1] - _keytime[index]);
float t = (time - _keytime[index]) / scale;
float* fromValue = &_value[index * componentSize];
float* toValue = fromValue + componentSize;
switch (type) {
case EvaluateType::LINEAR:
{
for (auto i = 0; i < componentSize; i++) {
dst[i] = fromValue[i] + (toValue[i] - fromValue[i]) * t;
}
}
break;
case EvaluateType::NEAR:
{
float* src = t > 0.5f ? toValue : fromValue;
memcpy(dst, src, _componentSizeByte);
}
break;
case EvaluateType::QUAT_SLERP:
{
// Evaluate.
Quaternion quat;
if (t >= 0)
Quaternion::slerp(Quaternion(fromValue), Quaternion(toValue), t, &quat);
else
Quaternion::slerp(Quaternion(toValue), Quaternion(fromValue), t, &quat);
dst[0] = quat.x, dst[1] = quat.y, dst[2] = quat.z, dst[3] = quat.w;
}
break;
case EvaluateType::USER_FUNCTION:
{
if (_evaluateFun)
_evaluateFun(time, dst);
}
break;
default:
break;
}
}
template <int componentSize>
void AnimationCurve<componentSize>::setEvaluateFun(std::function<void(float time, float* dst)> fun)
{
_evaluateFun = fun;
}
//create animation curve
template <int componentSize>
AnimationCurve<componentSize>* AnimationCurve<componentSize>::create(float* keytime, float* value, int count)
{
int floatSize = sizeof(float);
AnimationCurve* curve = new AnimationCurve();
curve->_keytime = new float[count];
memcpy(curve->_keytime, keytime, count * floatSize);
int compoentSizeByte = componentSize * floatSize;
int totalByte = count * compoentSizeByte;
curve->_value = new float[totalByte / floatSize];
memcpy(curve->_value, value, totalByte);
curve->_count = count;
curve->_componentSizeByte = compoentSizeByte;
curve->autorelease();
return curve;
}
template <int componentSize>
float AnimationCurve<componentSize>::getStartTime() const
{
return _keytime[0];
}
template <int componentSize>
float AnimationCurve<componentSize>::getEndTime() const
{
return _keytime[_count - 1];
}
template <int componentSize>
AnimationCurve<componentSize>::AnimationCurve()
: _keytime(nullptr)
, _value(nullptr)
, _count(0)
, _componentSizeByte(0)
, _evaluateFun(nullptr)
{
}
template <int componentSize>
AnimationCurve<componentSize>::~AnimationCurve()
{
CC_SAFE_DELETE(_keytime);
CC_SAFE_DELETE(_value);
}
template <int componentSize>
int AnimationCurve<componentSize>::determineIndex(float time) const
{
unsigned int min = 0;
unsigned int max = _count - 1;
unsigned int mid = 0;
do
{
mid = (min + max) >> 1;
if (time >= _keytime[mid] && time <= _keytime[mid + 1])
return mid;
else if (time < _keytime[mid])
max = mid - 1;
else
min = mid + 1;
} while (min <= max);
// We should never hit this!
return -1;
}
NS_CC_END

384
cocos/3d/CCBundle3D.cpp Normal file
View File

@ -0,0 +1,384 @@
/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "3d/CCBundle3D.h"
#include "base/ccMacros.h"
#include "platform/CCFileUtils.h"
#include "renderer/CCGLProgram.h"
NS_CC_BEGIN
void getChildMap(std::map<int, std::vector<int> >& map, SkinData* skinData, const rapidjson::Value& val)
{
if (!skinData)
return;
if (!val.HasMember("children"))
return;
std::string parent_name = val["id"].GetString();
int parent_name_index = skinData->getBoneNameIndex(parent_name);
const rapidjson::Value& children = val["children"];
for (rapidjson::SizeType i = 0; i < children.Size(); i++)
{
const rapidjson::Value& child = children[i];
std::string child_name = child["id"].GetString();
int child_name_index = skinData->getBoneNameIndex(child_name);
if (child_name_index >= 0)
{
map[parent_name_index].push_back(child_name_index);
getChildMap(map, skinData, child);
}
}
}
void getChildMapT(std::map<std::string, std::vector<std::string> >& map, const SkinData* skinData, const rapidjson::Value& val)
{
if (!skinData)
return;
if (!val.HasMember("children"))
return;
std::string parent_name = val["id"].GetString();
const rapidjson::Value& children = val["children"];
for (rapidjson::SizeType i = 0; i < children.Size(); i++)
{
const rapidjson::Value& child = children[i];
std::string child_name = child["id"].GetString();
map[parent_name].push_back(child_name);
getChildMapT(map, skinData, child);
}
}
Bundle3D* Bundle3D::_instance = nullptr;
Bundle3D* Bundle3D::getInstance()
{
if (_instance == nullptr)
_instance = new Bundle3D();
return _instance;
}
void Bundle3D::destroyInstance()
{
CC_SAFE_DELETE(_instance);
}
bool Bundle3D::load(const std::string& path)
{
if (_path == path)
return true;
getModelPath(path);
std::string strFileString = FileUtils::getInstance()->getStringFromFile(path);
ssize_t size = strFileString.length();
CC_SAFE_DELETE_ARRAY(_documentBuffer);
_documentBuffer = new char[size + 1];
memcpy(_documentBuffer, strFileString.c_str(), size);
_documentBuffer[size] = '\0';
if (_document.ParseInsitu<0>(_documentBuffer).HasParseError())
{
assert(0);
CC_SAFE_DELETE_ARRAY(_documentBuffer);
_path = "";
return false;
}
_path = path;
return true;
}
bool Bundle3D::loadMeshData(const std::string& id, MeshData* meshdata)
{
meshdata->resetData();
assert(_document.HasMember("mesh"));
const rapidjson::Value& mash_data_array = _document["mesh"];
assert(mash_data_array.IsArray());
const rapidjson::Value& mash_data_val = mash_data_array[(rapidjson::SizeType)0];
assert(mash_data_val.HasMember("body"));
const rapidjson::Value& mesh_data_body_array = mash_data_val["body"];
assert(mesh_data_body_array.IsArray());
const rapidjson::Value& mesh_data_body_array_0 = mesh_data_body_array[(rapidjson::SizeType)0];
// vertex_size
assert(mesh_data_body_array_0.HasMember("vertexsize"));
meshdata->vertexSizeInFloat = mesh_data_body_array_0["vertexsize"].GetInt();
// vertices
meshdata->vertex.resize(meshdata->vertexSizeInFloat);
const rapidjson::Value& mesh_data_body_vertices = mesh_data_body_array_0["vertices"];
for (rapidjson::SizeType i = 0; i < mesh_data_body_vertices.Size(); i++)
meshdata->vertex[i] = mesh_data_body_vertices[i].GetDouble();
// index_number
meshdata->numIndex = mesh_data_body_array_0["indexnum"].GetUint();
// indices
meshdata->indices.resize(meshdata->numIndex);
const rapidjson::Value& mesh_data_body_indices_val = mesh_data_body_array_0["indices"];
for (rapidjson::SizeType i = 0; i < mesh_data_body_indices_val.Size(); i++)
meshdata->indices[i] = (unsigned short)mesh_data_body_indices_val[i].GetUint();
// mesh_vertex_attribute
const rapidjson::Value& mesh_vertex_attribute = mash_data_val["attributes"];
meshdata->attribCount = mesh_vertex_attribute.Size();
meshdata->attribs.resize(meshdata->attribCount);
for (rapidjson::SizeType i = 0; i < mesh_vertex_attribute.Size(); i++)
{
const rapidjson::Value& mesh_vertex_attribute_val = mesh_vertex_attribute[i];
meshdata->attribs[i].size = mesh_vertex_attribute_val["size"].GetUint();
meshdata->attribs[i].attribSizeBytes = meshdata->attribs[i].size * parseGLTypeSize(mesh_vertex_attribute_val["type"].GetString());
meshdata->attribs[i].type = parseGLType(mesh_vertex_attribute_val["type"].GetString());
meshdata->attribs[i].vertexAttrib = parseGLProgramAttribute(mesh_vertex_attribute_val["attribute"].GetString());
}
return true;
}
bool Bundle3D::loadSkinData(const std::string& id, SkinData* skindata)
{
if (!_document.HasMember("skin")) return false;
skindata->resetData();
const rapidjson::Value& skin_data_array = _document["skin"];
assert(skin_data_array.IsArray());
const rapidjson::Value& skin_data_array_val_0 = skin_data_array[(rapidjson::SizeType)0];
if (!skin_data_array_val_0.HasMember("bones"))
return false;
const rapidjson::Value& skin_data_bones = skin_data_array_val_0["bones"];
for (rapidjson::SizeType i = 0; i < skin_data_bones.Size(); i++)
{
const rapidjson::Value& skin_data_bone = skin_data_bones[i];
std::string name = skin_data_bone["node"].GetString();
skindata->boneNames.push_back(name);
Mat4 mat_bind_pos;
const rapidjson::Value& bind_pos = skin_data_bone["bindshape"];
for (rapidjson::SizeType j = 0; j < bind_pos.Size(); j++)
{
mat_bind_pos.m[j] = bind_pos[j].GetDouble();
}
skindata->inverseBindPoseMatrices.push_back(mat_bind_pos);
}
const rapidjson::Value& skin_data_1 = skin_data_array[1];
const rapidjson::Value& bone_array_0 = skin_data_1["children"][(rapidjson::SizeType)0];
skindata->rootBoneIndex = skindata->getBoneNameIndex(bone_array_0["id"].GetString());
getChildMap(skindata->boneChild, skindata, bone_array_0);
return true;
}
bool Bundle3D::loadMaterialData(const std::string& id, MaterialData* materialdata)
{
if (!_document.HasMember("material"))
return false;
const rapidjson::Value& material_data_array = _document["material"];
const rapidjson::Value& material_data_array_0 = material_data_array[(rapidjson::SizeType)0];
const rapidjson::Value& material_data_base_array = material_data_array_0["base"];
const rapidjson::Value& material_data_base_array_0 = material_data_base_array[(rapidjson::SizeType)0];
materialdata->texturePath = _modelRelativePath + material_data_base_array_0["filename"].GetString();
return true;
}
bool Bundle3D::loadAnimationData(const std::string& id, Animation3DData* animationdata)
{
if (!_document.HasMember("animation")) return false;
animationdata->_rotationKeys.clear();
animationdata->_scaleKeys.clear();
animationdata->_translationKeys.clear();
const rapidjson::Value& animation_data_array = _document["animation"];
if (animation_data_array.Size()==0) return false;
const rapidjson::Value& animation_data_array_val_0 = animation_data_array[(rapidjson::SizeType)0];
animationdata->_totalTime = animation_data_array_val_0["length"].GetDouble();
const rapidjson::Value& bones = animation_data_array_val_0["bones"];
for (rapidjson::SizeType i = 0; i < bones.Size(); i++)
{
const rapidjson::Value& bone = bones[i];
std::string bone_name = bone["boneId"].GetString();
if ( bone.HasMember("keyframes"))
{
const rapidjson::Value& bone_keyframes = bone["keyframes"];
rapidjson::SizeType keyframe_size = bone_keyframes.Size();
for (rapidjson::SizeType j = 0; j < bone_keyframes.Size(); j++)
{
const rapidjson::Value& bone_keyframe = bone_keyframes[j];
if ( bone_keyframe.HasMember("translation"))
{
const rapidjson::Value& bone_keyframe_translation = bone_keyframe["translation"];
float keytime = bone_keyframe["keytime"].GetDouble();
Vec3 val = Vec3(bone_keyframe_translation[(rapidjson::SizeType)0].GetDouble(), bone_keyframe_translation[1].GetDouble(), bone_keyframe_translation[2].GetDouble());
animationdata->_translationKeys[bone_name].push_back(Animation3DData::Vec3Key(keytime,val));
}
if ( bone_keyframe.HasMember("rotation"))
{
const rapidjson::Value& bone_keyframe_rotation = bone_keyframe["rotation"];
float keytime = bone_keyframe["keytime"].GetDouble();
Quaternion val = Quaternion(bone_keyframe_rotation[(rapidjson::SizeType)0].GetDouble(),bone_keyframe_rotation[1].GetDouble(),bone_keyframe_rotation[2].GetDouble(),bone_keyframe_rotation[3].GetDouble());
animationdata->_rotationKeys[bone_name].push_back(Animation3DData::QuatKey(keytime,val));
}
if ( bone_keyframe.HasMember("scale"))
{
const rapidjson::Value& bone_keyframe_scale = bone_keyframe["scale"];
float keytime = bone_keyframe["keytime"].GetDouble();
Vec3 val = Vec3(bone_keyframe_scale[(rapidjson::SizeType)0].GetDouble(), bone_keyframe_scale[1].GetDouble(), bone_keyframe_scale[2].GetDouble());
animationdata->_scaleKeys[bone_name].push_back(Animation3DData::Vec3Key(keytime,val));
}
}
}
}
return true;
}
GLenum Bundle3D::parseGLType(const std::string& str)
{
if (str == "GL_FLOAT")
{
return GL_FLOAT;
}
else if (str == "GL_UNSIGNED_INT")
{
return GL_UNSIGNED_INT;
}
else
{
assert(0);
return 0;
}
}
unsigned int Bundle3D::parseGLTypeSize(const std::string& str)
{
if (str == "GL_FLOAT")
{
return sizeof(float);
}
else if (str == "GL_UNSIGNED_INT")
{
return sizeof(unsigned int);
}
else
{
assert(0);
return -1;
}
}
unsigned int Bundle3D::parseGLProgramAttribute(const std::string& str)
{
if (str == "VERTEX_ATTRIB_POSITION")
{
return GLProgram::VERTEX_ATTRIB_POSITION;
}
else if (str == "VERTEX_ATTRIB_COLOR")
{
return GLProgram::VERTEX_ATTRIB_COLOR;
}
else if (str == "VERTEX_ATTRIB_TEX_COORD")
{
return GLProgram::VERTEX_ATTRIB_TEX_COORD;
}
else if (str == "VERTEX_ATTRIB_NORMAL")
{
return GLProgram::VERTEX_ATTRIB_NORMAL;
}
else if (str == "VERTEX_ATTRIB_BLEND_WEIGHT")
{
return GLProgram::VERTEX_ATTRIB_BLEND_WEIGHT;
}
else if (str == "VERTEX_ATTRIB_BLEND_INDEX")
{
return GLProgram::VERTEX_ATTRIB_BLEND_INDEX;
}
else
{
assert(0);
return -1;
}
}
void Bundle3D::getModelPath(const std::string& path)
{
int index = path.find_last_of('/');
std::string fullModelPath;
fullModelPath = path.substr(0, index + 1);
auto list = FileUtils::getInstance()->getSearchPaths();
for( const auto &item : list )
{
if ( fullModelPath.find(item) != std::string::npos )
{
_modelRelativePath = fullModelPath.substr(item.length(), fullModelPath.length() + 1);
break;
}
}
}
Bundle3D::Bundle3D()
:_isBinary(false)
,_modelRelativePath("")
,_documentBuffer(nullptr)
,_path("")
{
}
Bundle3D::~Bundle3D()
{
CC_SAFE_DELETE_ARRAY(_documentBuffer);
}
NS_CC_END

105
cocos/3d/CCBundle3D.h Normal file
View File

@ -0,0 +1,105 @@
/****************************************************************************
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 __CCBUNDLE3D_H__
#define __CCBUNDLE3D_H__
#include <map>
#include "3d/CCBundle3DData.h"
#include "base/ccMacros.h"
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "json/document.h"
NS_CC_BEGIN
class Animation3D;
class Bundle3D
{
public:
static Bundle3D* getInstance();
static void destroyInstance();
bool load(const std::string& path);
/**
* load mesh data from bundle
* @param id The ID of the mesh, load the first Mesh in the bundle if it is empty
*/
bool loadMeshData(const std::string& id, MeshData* meshdata);
/**
* load skin data from bundle
* @param id The ID of the skin, load the first Skin in the bundle if it is empty
*/
bool loadSkinData(const std::string& id, SkinData* skindata);
/**
* load material data from bundle
* @param id The ID of the material, load the first Material in the bundle if it is empty
*/
bool loadMaterialData(const std::string& id, MaterialData* materialdata);
/**
* load material data from bundle
* @param id The ID of the animation, load the first animation in the bundle if it is empty
*/
bool loadAnimationData(const std::string& id, Animation3DData* animationdata);
protected:
GLenum parseGLType(const std::string& str);
unsigned int parseGLTypeSize(const std::string& str);
unsigned int parseGLProgramAttribute(const std::string& str);
// get model path
void getModelPath(const std::string& path);
CC_CONSTRUCTOR_ACCESS:
Bundle3D();
~Bundle3D();
protected:
static Bundle3D* _instance;
std::string _modelRelativePath;
char* _documentBuffer;
std::string _path;
rapidjson::Document _document;
bool _isBinary;
};
NS_CC_END
#endif // __CCANIMATE3D_H__

187
cocos/3d/CCBundle3DData.h Normal file
View File

@ -0,0 +1,187 @@
/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CC_BUNDLE_3D_DATA_H__
#define __CC_BUNDLE_3D_DATA_H__
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "math/CCMath.h"
#include <vector>
#include <map>
NS_CC_BEGIN
//mesh vertex attribute
struct MeshVertexAttrib
{
//attribute size
GLint size;
//GL_FLOAT
GLenum type;
//VERTEX_ATTRIB_POSITION,VERTEX_ATTRIB_COLOR,VERTEX_ATTRIB_TEX_COORD,VERTEX_ATTRIB_NORMAL, VERTEX_ATTRIB_BLEND_WEIGHT, VERTEX_ATTRIB_BLEND_INDEX, GLProgram for detail
int vertexAttrib;
//size in bytes
int attribSizeBytes;
};
struct MeshData
{
std::vector<float> vertex;
int vertexSizeInFloat;
std::vector<unsigned short> indices;
int numIndex;
std::vector<MeshVertexAttrib> attribs;
int attribCount;
public:
void resetData()
{
vertex.clear();
indices.clear();
attribs.clear();
vertexSizeInFloat = 0;
numIndex = 0;
attribCount = 0;
}
MeshData()
: vertexSizeInFloat(0)
, numIndex(0)
, attribCount(0)
{
}
~MeshData()
{
resetData();
}
};
struct SkinData
{
std::vector<std::string> boneNames;
std::vector<Mat4> inverseBindPoseMatrices; //bind pose of bone
std::map<int, std::vector<int> > boneChild;//key parent, value child
int rootBoneIndex;
void resetData()
{
boneNames.clear();
inverseBindPoseMatrices.clear();
boneChild.clear();
rootBoneIndex = -1;
}
int getBoneNameIndex(const std::string& name)const
{
std::vector<std::string>::const_iterator iter = boneNames.begin();
for (int i = 0; iter != boneNames.end(); ++iter, ++i)
{
if ((*iter) == name)
{
return i;
}
}
return -1;
}
};
struct MaterialData
{
std::string texturePath;
};
struct Animation3DData
{
public:
struct Vec3Key
{
Vec3Key()
: _time(0)
, _key(Vec3::ZERO)
{
}
Vec3Key(float time, const Vec3& v)
: _time(time)
, _key(v)
{
}
float _time;
Vec3 _key;
};
struct QuatKey
{
QuatKey()
: _time(0)
, _key(Quaternion::identity())
{
}
QuatKey(float time, const Quaternion& quat)
: _time(time)
, _key(quat)
{
}
float _time;
Quaternion _key;
};
public:
std::map<std::string, std::vector<Vec3Key>> _translationKeys;
std::map<std::string, std::vector<QuatKey>> _rotationKeys;
std::map<std::string, std::vector<Vec3Key>> _scaleKeys;
float _totalTime;
public:
Animation3DData()
:_totalTime(0)
{
}
Animation3DData(const Animation3DData& other)
: _totalTime(other._totalTime)
, _translationKeys(other._translationKeys)
, _rotationKeys(other._rotationKeys)
, _scaleKeys(other._scaleKeys)
{
}
void clear()
{
_totalTime = 0;
_translationKeys.clear();
_rotationKeys.clear();
_scaleKeys.clear();
}
};
NS_CC_END
#endif //__CC_BUNDLE_3D_DATA_H__

View File

@ -29,10 +29,17 @@
#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"
#include "CCObjLoader.h"
#include "CCSprite3DDataCache.h"
using namespace std;
@ -48,7 +55,7 @@ bool RenderMeshData::hasVertexAttrib(int attrib)
return false;
}
bool RenderMeshData::initFrom(const std::vector<float>& positions,
bool RenderMeshData::init(const std::vector<float>& positions,
const std::vector<float>& normals,
const std::vector<float>& texs,
const std::vector<unsigned short>& indices)
@ -56,7 +63,6 @@ bool RenderMeshData::initFrom(const std::vector<float>& positions,
CC_ASSERT(positions.size()<65536 * 3 && "index may out of bound");
_vertexAttribs.clear();
_vertexsizeBytes = 0;
_vertexNum = positions.size() / 3; //number of vertex
if (_vertexNum == 0)
@ -65,7 +71,6 @@ bool RenderMeshData::initFrom(const std::vector<float>& positions,
if ((normals.size() != 0 && _vertexNum * 3 != normals.size()) || (texs.size() != 0 && _vertexNum * 2 != texs.size()))
return false;
_vertexsizeBytes += 3;
MeshVertexAttrib meshvertexattrib;
meshvertexattrib.size = 3;
meshvertexattrib.type = GL_FLOAT;
@ -77,14 +82,12 @@ bool RenderMeshData::initFrom(const std::vector<float>& positions,
if (normals.size())
{
//add normal flag
_vertexsizeBytes += 3;
meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_NORMAL;
_vertexAttribs.push_back(meshvertexattrib);
}
//
if (texs.size())
{
_vertexsizeBytes += 2;
meshvertexattrib.size = 2;
meshvertexattrib.vertexAttrib = GLProgram::VERTEX_ATTRIB_TEX_COORD;
meshvertexattrib.attribSizeBytes = meshvertexattrib.size * sizeof(float);
@ -92,8 +95,8 @@ bool RenderMeshData::initFrom(const std::vector<float>& positions,
}
_vertexs.clear();
_vertexs.reserve(_vertexNum * _vertexsizeBytes);
_vertexsizeBytes *= sizeof(float);
_vertexsizeBytes = calVertexSizeBytes();
_vertexs.reserve(_vertexNum * _vertexsizeBytes / sizeof(float));
bool hasNormal = hasVertexAttrib(GLProgram::VERTEX_ATTRIB_NORMAL);
bool hasTexCoord = hasVertexAttrib(GLProgram::VERTEX_ATTRIB_TEX_COORD);
@ -122,6 +125,29 @@ bool RenderMeshData::initFrom(const std::vector<float>& positions,
return true;
}
bool RenderMeshData::init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<unsigned short>& indices, int numIndex, const std::vector<MeshVertexAttrib>& attribs, int attribCount)
{
_vertexs = vertices;
_indices = 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)
, _indexBuffer(0)
@ -148,9 +174,31 @@ Mesh* Mesh::create(const std::vector<float>& positions, const std::vector<float>
return nullptr;
}
Mesh* Mesh::create(const std::vector<float> &vertices, int vertexSizeInFloat, const std::vector<unsigned short> &indices, int numIndex, const std::vector<MeshVertexAttrib> &attribs, int attribCount)
{
auto mesh = new Mesh();
if (mesh && mesh->init(vertices, vertexSizeInFloat, indices, numIndex, attribs, attribCount))
{
mesh->autorelease();
return mesh;
}
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<unsigned short>& indices)
{
bool bRet = _renderdata.initFrom(positions, normals, texs, indices);
bool bRet = _renderdata.init(positions, normals, texs, indices);
if (!bRet)
return false;
restore();
return true;
}
bool Mesh::init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<unsigned short>& indices, int numIndex, const std::vector<MeshVertexAttrib>& attribs, int attribCount)
{
bool bRet = _renderdata.init(vertices, vertexSizeInFloat, indices, numIndex, attribs, attribCount);
if (!bRet)
return false;
@ -211,4 +259,92 @@ void Mesh::restore()
buildBuffer();
}
/**
* 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)
{
it->second->release();
_meshes.erase(it++);
}
else
++it;
}
}
MeshCache::MeshCache()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// listen the event when app go to foreground
_backToForegroundlistener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, CC_CALLBACK_1(MeshCache::listenBackToForeground, this));
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundlistener, -1);
#endif
}
MeshCache::~MeshCache()
{
removeAllMeshes();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundlistener);
#endif
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
void MeshCache::listenBackToForeground(EventCustom* event)
{
for (auto iter = _meshes.begin(); iter != _meshes.end(); ++iter)
{
auto mesh = iter->second;
mesh->restore();
}
}
#endif
NS_CC_END

View File

@ -28,6 +28,8 @@
#include <string>
#include <vector>
#include "3d/CCBundle3DData.h"
#include "base/CCRef.h"
#include "base/ccTypes.h"
#include "math/CCMath.h"
@ -35,18 +37,8 @@
NS_CC_BEGIN
//mesh vertex attribute
struct MeshVertexAttrib
{
//attribute size
GLint size;
//GL_FLOAT
GLenum type;
//VERTEX_ATTRIB_POSITION,VERTEX_ATTRIB_COLOR,VERTEX_ATTRIB_TEX_COORD,VERTEX_ATTRIB_NORMAL, GLProgram for detail
int vertexAttrib;
//size in bytes
int attribSizeBytes;
};
class EventListenerCustom;
class EventCustom;
class RenderMeshData
{
@ -56,9 +48,13 @@ public:
{
}
bool hasVertexAttrib(int attrib);
bool initFrom(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<unsigned short>& indices);
bool init(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<unsigned short>& indices);
bool init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<unsigned short>& indices, int numIndex, const std::vector<MeshVertexAttrib>& attribs, int attribCount);
protected:
int calVertexSizeBytes();
int _vertexsizeBytes;
ssize_t _vertexNum;
std::vector<float> _vertexs;
@ -89,6 +85,8 @@ public:
//create
static Mesh* create(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<unsigned short>& indices);
static Mesh* create(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<unsigned short>& indices, int numIndex, const std::vector<MeshVertexAttrib>& attribs, int attribCount);
//get vertex buffer
inline GLuint getVertexBuffer() const { return _vertexBuffer; }
@ -110,15 +108,19 @@ public:
//build vertex buffer from renderdata
void restore();
protected:
CC_CONSTRUCTOR_ACCESS:
Mesh();
virtual ~Mesh();
bool init(const std::vector<float>& positions, const std::vector<float>& normals, const std::vector<float>& texs, const std::vector<unsigned short>& indices);
bool init(const std::vector<float>& vertices, int vertexSizeInFloat, const std::vector<unsigned short>& indices, int numIndex, const std::vector<MeshVertexAttrib>& attribs, int attribCount);
//build buffer
void buildBuffer();
void cleanAndFreeBuffers();
protected:
PrimitiveType _primitiveType;
IndexFormat _indexFormat;
GLuint _vertexBuffer;
@ -128,6 +130,43 @@ protected:
RenderMeshData _renderdata;
};
/**
* MeshCache
*/
class MeshCache
{
public:
static MeshCache* getInstance();
static void destroyInstance();
Mesh* getMesh(const std::string& key) const;
bool addMesh(const std::string& key, Mesh* mesh);
void removeAllMeshes();
void removeUnusedMesh();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
void listenBackToForeground(EventCustom* event);
#endif
CC_CONSTRUCTOR_ACCESS:
MeshCache();
~MeshCache();
protected:
static MeshCache* _cacheInstance;
std::unordered_map<std::string, Mesh*> _meshes;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
EventListenerCustom* _backToForegroundlistener;
#endif
};
NS_CC_END
#endif // __CCMESH_H_

472
cocos/3d/CCMeshSkin.cpp Normal file
View File

@ -0,0 +1,472 @@
/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "3d/CCMeshSkin.h"
#include "3d/CCBundle3D.h"
#include "base/ccMacros.h"
#include "base/CCPlatformMacros.h"
#include "platform/CCFileUtils.h"
NS_CC_BEGIN
/**
* Sets the inverse bind pose matrix.
*
* @param m C3DMatrix representing the inverse bind pose for this Bone.
*/
void Bone::setInverseBindPose(const Mat4& m)
{
_invBindPose = m;
}
const Mat4& Bone::getInverseBindPose()
{
return _invBindPose;
}
void Bone::setWorldMatDirty(bool dirty)
{
_worldDirty = dirty;
for (auto it : _children) {
it->setWorldMatDirty(dirty);
}
}
//update own world matrix and children's
void Bone::updateWorldMat()
{
getWorldMat();
for (auto itor : _children) {
itor->updateWorldMat();
}
}
const Mat4& Bone::getWorldMat()
{
if (_worldDirty)
{
updateLocalMat();
if (_parent)
{
_world = _parent->getWorldMat() * _local;
}
else
_world = _local;
_worldDirty = false;
}
return _world;
}
void Bone::setAnimationValue(float* trans, float* rot, float* scale, float weight)
{
BoneBlendState state;
if (trans)
state.localTranslate.set(trans);
if (rot)
state.localRot.set(rot);
if (scale)
state.localScale.set(scale);
state.weight = weight;
_blendStates.push_back(state);
_localDirty = true;
}
void Bone::clearBoneBlendState()
{
_blendStates.clear();
for (auto it : _children) {
it->clearBoneBlendState();
}
}
/**
* Creates C3DBone.
*/
Bone* Bone::create(const std::string& id)
{
auto bone = new Bone(id);
bone->autorelease();
return bone;
}
/**
* Updates the joint matrix.
*
* @param matrixPalette The matrix palette to update.
*/
void Bone::updateJointMatrix(Vec4* matrixPalette)
{
{
static Mat4 t;
Mat4::multiply(_world, getInverseBindPose(), &t);
matrixPalette[0].set(t.m[0], t.m[4], t.m[8], t.m[12]);
matrixPalette[1].set(t.m[1], t.m[5], t.m[9], t.m[13]);
matrixPalette[2].set(t.m[2], t.m[6], t.m[10], t.m[14]);
}
}
//bone tree, we do not inherit from Node, Node has too many properties that we do not need. A clean Node is needed.
Bone* Bone::getParentBone()
{
return _parent;
}
int Bone::getChildBoneCount() const
{
return _children.size();
}
Bone* Bone::getChildBoneByIndex(int index)
{
return _children.at(index);
}
void Bone::addChildBone(Bone* bone)
{
if (_children.find(bone) == _children.end())
_children.pushBack(bone);
}
void Bone::removeChildBoneByIndex(int index)
{
_children.erase(index);
}
void Bone::removeChildBone(Bone* bone)
{
_children.eraseObject(bone);
}
void Bone::removeAllChildBone()
{
_children.clear();
}
Bone::Bone(const std::string& id)
: _name(id)
, _parent(nullptr)
, _localDirty(true)
, _worldDirty(true)
{
}
/**
* Destructor.
*/
Bone::~Bone()
{
removeAllChildBone();
}
void Bone::updateLocalMat()
{
if (_blendStates.size())
{
Vec3 translate(Vec3::ZERO), scale(Vec3::ONE);
Quaternion quat(Quaternion::identity());
float total = 0.f;
for (auto it: _blendStates) {
total += it.weight;
}
if (total)
{
//if (_blendStates.size() == 1)
if (true)
{
int cnt = _blendStates.size();
translate = _blendStates[cnt - 1].localTranslate;
scale = _blendStates[cnt - 1].localScale;
quat = _blendStates[cnt - 1].localRot;
}
else
{
float invTotal = 1.f / total;
for (auto it : _blendStates) {
float weight = (it.weight * invTotal);
translate += it.localTranslate * weight;
if (!it.localScale.isZero())
{
scale.x *= it.localScale.x * weight;
scale.y *= it.localScale.y * weight;
scale.z *= it.localScale.z * weight;
}
if (!it.localRot.isZero())
{
if (!quat.isZero())
{
Quaternion& q = _blendStates[0].localRot;
if (q.x * quat.x + q.y * quat.y + q.z * quat.z + q.w * quat.w < 0)
weight = -weight;
}
quat = Quaternion(it.localRot.x * weight + quat.x, it.localRot.y * weight + quat.y, it.localRot.z * weight + quat.z, it.localRot.w * weight + quat.w);
}
}
}
}
Mat4::createTranslation(translate, &_local);
_local.rotate(quat);
_local.scale(scale);
_blendStates.clear();
_localDirty = false;
}
else
{
CCLOG("use cached local");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int PALETTE_ROWS = 3;
MeshSkin::MeshSkin()
: _rootBone(nullptr)
, _matrixPalette(nullptr)
{
}
MeshSkin::~MeshSkin()
{
removeAllBones();
}
//create a new meshskin if do not want to share meshskin
MeshSkin* MeshSkin::create(const std::string& filename, const std::string& name)
{
//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->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->initFromSkinData(data);
skin->autorelease();
MeshSkinDataCache::getInstance()->addMeshSkinData(key, data);
return skin;
}
}
}
return nullptr;
}
bool MeshSkin::initFromSkinData(const SkinData& skindata)
{
setBoneCount((int)skindata.boneNames.size());
for (size_t i = 0; i < skindata.boneNames.size(); i++) {
auto bone = Bone::create(skindata.boneNames[i]);
bone->_invBindPose = skindata.inverseBindPoseMatrices[i];
addBone(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);
}
}
setRootBone(getBoneByIndex(skindata.rootBoneIndex));
return true;
}
unsigned int MeshSkin::getBoneCount() const
{
return _bones.size();
}
//get bone
Bone* MeshSkin::getBoneByIndex(unsigned int index) const
{
return _bones.at(index);
}
Bone* MeshSkin::getBoneByName(const std::string& id) const
{
for (auto it : _bones) {
if (it->getName() == id )
return it;
}
return nullptr;
}
//get & set root bone
Bone* MeshSkin::getRootBone() const
{
return _rootBone;
}
void MeshSkin::setRootBone(Bone* joint)
{
CC_SAFE_RETAIN(joint);
CC_SAFE_RELEASE(_rootBone);
_rootBone = joint;
}
void MeshSkin::setBoneCount(int boneCount)
{
removeAllBones();
// Resize the joints vector and initialize to NULL
_bones.reserve(boneCount);
// for (auto i = 0; i < boneCount; i++)
// {
// _bones.pushBack(nullptr);
// }
// Rebuild the matrix palette. Each matrix is 3 rows of Vec4.
CC_SAFE_DELETE_ARRAY(_matrixPalette);
if (boneCount > 0)
{
_matrixPalette = new Vec4[boneCount * PALETTE_ROWS];
for (unsigned int i = 0; i < boneCount * PALETTE_ROWS; i+=PALETTE_ROWS)
{
_matrixPalette[i+0].set(1.0f, 0.0f, 0.0f, 0.0f);
_matrixPalette[i+1].set(0.0f, 1.0f, 0.0f, 0.0f);
_matrixPalette[i+2].set(0.0f, 0.0f, 1.0f, 0.0f);
}
}
}
int MeshSkin::getBoneIndex(Bone* joint) const
{
for (auto i = 0; i < _bones.size(); i++) {
if (_bones.at(i) == joint)
return i;
}
return -1;
}
//compute matrix palette used by gpu skin
Vec4* MeshSkin::getMatrixPalette()
{
updateBoneMatrix();
int i = 0;
for (auto it : _bones )
{
it->updateJointMatrix(&_matrixPalette[i++ * PALETTE_ROWS]);
}
return _matrixPalette;
}
//getBoneCount() * 3
unsigned int MeshSkin::getMatrixPaletteSize() const
{
return _bones.size() * PALETTE_ROWS;
}
//refresh bone world matrix
void MeshSkin::updateBoneMatrix()
{
_rootBone->setWorldMatDirty(true);
_rootBone->updateWorldMat();
}
void MeshSkin::removeAllBones()
{
_bones.clear();
CC_SAFE_DELETE_ARRAY(_matrixPalette);
CC_SAFE_RELEASE(_rootBone);
}
void MeshSkin::addBone(Bone* bone)
{
_bones.pushBack(bone);
}
////////////////////////////////////////////////////////////////////////
MeshSkinDataCache* MeshSkinDataCache::_cacheInstance = nullptr;
MeshSkinDataCache* MeshSkinDataCache::getInstance()
{
if (_cacheInstance == nullptr)
_cacheInstance = new MeshSkinDataCache();
return _cacheInstance;
}
void MeshSkinDataCache::destroyInstance()
{
if (_cacheInstance)
{
CC_SAFE_DELETE(_cacheInstance);
}
}
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()
{
}
NS_CC_END

226
cocos/3d/CCMeshSkin.h Normal file
View File

@ -0,0 +1,226 @@
/****************************************************************************
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 __CCMESHSKIN_H__
#define __CCMESHSKIN_H__
#include <unordered_map>
#include "3d/CCBundle3DData.h"
#include "base/ccMacros.h"
#include "base/CCRef.h"
#include "base/CCVector.h"
#include "base/ccTypes.h"
#include "math/CCMath.h"
NS_CC_BEGIN
/**
* Defines a basic hierachial structure of transformation spaces.
*/
class Bone : public Ref
{
friend class MeshSkin;
public:
/**
* Returns the inverse bind pose matrix for this joint.
*
* @return Inverse bind pose matrix.
*/
const Mat4& getInverseBindPose();
//update own world matrix and children's
void updateWorldMat();
void setWorldMatDirty(bool dirty = true);
const Mat4& getWorldMat();
const std::string& getName() const { return _name; }
void setAnimationValue(float* trans, float* rot, float* scale, float weight = 1.0f);
void clearBoneBlendState();
/**
* Creates C3DBone.
*/
static Bone* create(const std::string& id);
/**
* Sets the inverse bind pose matrix.
*
* @param m C3DMatrix representing the inverse bind pose for this Bone.
*/
void setInverseBindPose(const Mat4& m);
/**
* Updates the joint matrix.
*
* @param matrixPalette The matrix palette to update.
*/
void updateJointMatrix(Vec4* matrixPalette);
//bone tree, we do not inherit from Node, Node has too many properties that we do not need. A clean Node is needed.
Bone* getParentBone();
int getChildBoneCount() const;
Bone* getChildBoneByIndex(int index);
void addChildBone(Bone* bone);
void removeChildBoneByIndex(int index);
void removeChildBone(Bone* bone);
void removeAllChildBone();
protected:
struct BoneBlendState
{
Vec3 localTranslate;
Quaternion localRot;
Vec3 localScale;
float weight;
BoneBlendState()
: localTranslate(Vec3::ZERO)
, localRot(Quaternion::identity())
, localScale(Vec3::ONE)
, weight(1.f)
{
}
};
/**
* Constructor.
*/
Bone(const std::string& id);
/**
* Destructor.
*/
virtual ~Bone();
/**
* Update local matrix
*/
void updateLocalMat();
std::string _name;
/**
* The Mat4 representation of the Joint's bind pose.
*/
Mat4 _invBindPose;
Bone* _parent;
Vector<Bone*> _children;
bool _localDirty;
bool _worldDirty;
Mat4 _world;
Mat4 _local;
std::vector<BoneBlendState> _blendStates;
};
/////////////////////////////////////////////////////////////////////////////
class MeshSkin: public Ref
{
public:
//create a new meshskin if do not want to share meshskin
static MeshSkin* create(const std::string& filename, const std::string& name);
unsigned int getBoneCount() const;
void setBoneCount(int boneCount);
//get bone
Bone* getBoneByIndex(unsigned int index) const;
Bone* getBoneByName(const std::string& id) const;
//get & set root bone
Bone* getRootBone() const;
void setRootBone(Bone* joint);
int getBoneIndex(Bone* joint) const;
//compute matrix palette used by gpu skin
Vec4* getMatrixPalette();
//getBoneCount() * 3
unsigned int getMatrixPaletteSize() const;
//refresh bone world matrix
void updateBoneMatrix();
CC_CONSTRUCTOR_ACCESS:
MeshSkin();
~MeshSkin();
bool initFromSkinData(const SkinData& skindata);
void removeAllBones();
void addBone(Bone* bone);
protected:
Vector<Bone*> _bones;
Bone* _rootBone;
// Pointer to the array of palette matrices.
// This array is passed to the vertex shader as a uniform.
// Each 4x3 row-wise matrix is represented as 3 Vec4's.
// The number of Vec4's is (_joints.size() * 3).
Vec4* _matrixPalette;
};
class MeshSkinDataCache
{
public:
static MeshSkinDataCache* getInstance();
static void destroyInstance();
const SkinData* getMeshSkinData(const std::string& key) const;
bool addMeshSkinData(const std::string& key, const SkinData& skinData);
void removeAllMeshSkinData();
protected:
MeshSkinDataCache();
~MeshSkinDataCache();
static MeshSkinDataCache* _cacheInstance;
std::unordered_map<std::string, SkinData> _skinDatas;
};
NS_CC_END
#endif // __CCSKIN_H__

View File

@ -23,9 +23,11 @@
****************************************************************************/
#include "3d/CCSprite3D.h"
#include "3d/CCSprite3DDataCache.h"
#include "3d/CCMesh.h"
#include "3d/CCObjLoader.h"
#include "3d/CCMeshSkin.h"
#include "3d/CCBundle3D.h"
#include "3d/CCSprite3DMaterial.h"
#include "base/CCDirector.h"
#include "base/CCPlatformMacros.h"
@ -40,7 +42,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};
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};
Sprite3D* Sprite3D::create(const std::string &modelPath)
{
@ -89,6 +91,22 @@ bool Sprite3D::loadFromObj(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)
{
_mesh = mesh;
_mesh->retain();
auto tex = Sprite3DMaterialCache::getInstance()->getSprite3DMaterial(key);
setTexture(tex);
genGLProgramState();
return true;
}
//.mtl file directory
std::string dir = "";
auto last = fullPath.rfind("/");
@ -130,13 +148,80 @@ bool Sprite3D::loadFromObj(const std::string& path)
genGLProgramState();
//add to cache
Sprite3DDataCache::getInstance()->addSprite3D(fullPath, _mesh, matnames.size() > 0 ? matnames[0] : "");
if (_texture)
{
Sprite3DMaterialCache::getInstance()->addSprite3DMaterial(key, _texture);
}
MeshCache::getInstance()->addMesh(key, _mesh);
return true;
}
bool Sprite3D::loadFromC3x(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)
{
_mesh = mesh;
_mesh->retain();
auto tex = Sprite3DMaterialCache::getInstance()->getSprite3DMaterial(key);
setTexture(tex);
_skin = MeshSkin::create(fullPath, "");
CC_SAFE_RETAIN(_skin);
genGLProgramState();
return true;
}
//load from .c3b or .c3t
auto bundle = Bundle3D::getInstance();
if (!bundle->load(fullPath))
return false;
MeshData meshdata;
bool ret = bundle->loadMeshData("", &meshdata);
if (!ret)
{
return false;
}
_mesh = Mesh::create(meshdata.vertex, meshdata.vertexSizeInFloat, meshdata.indices, meshdata.numIndex, meshdata.attribs, meshdata.attribCount);
CC_SAFE_RETAIN(_mesh);
_skin = MeshSkin::create(fullPath, "");
CC_SAFE_RETAIN(_skin);
MaterialData materialdata;
ret = bundle->loadMaterialData("", &materialdata);
if (ret)
{
setTexture(materialdata.texturePath);
}
genGLProgramState();
//add to cache
auto cache = Director::getInstance()->getTextureCache();
auto tex = cache->addImage(materialdata.texturePath);
if (tex)
Sprite3DMaterialCache::getInstance()->addSprite3DMaterial(key, tex);
MeshCache::getInstance()->addMesh(key, _mesh);
return true;
}
Sprite3D::Sprite3D()
: _mesh(nullptr)
, _skin(nullptr)
, _texture(nullptr)
, _blend(BlendFunc::ALPHA_NON_PREMULTIPLIED)
{
@ -146,38 +231,29 @@ Sprite3D::~Sprite3D()
{
CC_SAFE_RELEASE_NULL(_texture);
CC_SAFE_RELEASE_NULL(_mesh);
CC_SAFE_RELEASE_NULL(_skin);
}
bool Sprite3D::initWithFile(const std::string &path)
{
CC_SAFE_RELEASE_NULL(_mesh);
CC_SAFE_RELEASE_NULL(_skin);
CC_SAFE_RELEASE_NULL(_texture);
//find from the cache
Mesh* mesh = Sprite3DDataCache::getInstance()->getSprite3DMesh(path);
if (mesh)
//load from file
std::string ext = path.substr(path.length() - 4, 4);
std::transform(ext.begin(), ext.end(), ext.begin(), tolower);
if (ext == ".obj")
{
_mesh = mesh;
_mesh->retain();
auto tex = Sprite3DDataCache::getInstance()->getSprite3DTexture(path);
setTexture(tex);
genGLProgramState();
return true;
return loadFromObj(path);
}
else
else if (ext == ".c3b" || ext == ".c3t")
{
//load from file
std::string ext = path.substr(path.length() - 4, 4);
if (ext != ".obj" || !loadFromObj(path))
{
return false;
}
return true;
return loadFromC3x(path);
}
return false;
}
void Sprite3D::genGLProgramState()
@ -201,8 +277,14 @@ void Sprite3D::genGLProgramState()
GLProgram* Sprite3D::getDefaultGLProgram(bool textured)
{
bool hasSkin = _skin && _mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_INDEX)
&& _mesh->hasVertexAttrib(GLProgram::VERTEX_ATTRIB_BLEND_WEIGHT);
if(textured)
{
if (hasSkin)
return GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_SKINPOSITION_TEXTURE);
return GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_POSITION_TEXTURE);
}
else
@ -250,6 +332,11 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
_meshCommand.setCullFaceEnabled(true);
_meshCommand.setDepthTestEnabled(true);
if (_skin)
{
_meshCommand.setMatrixPaletteSize(_skin->getMatrixPaletteSize());
_meshCommand.setMatrixPalette(_skin->getMatrixPalette());
}
//support tint and fade
_meshCommand.setDisplayColor(Vec4(color.r, color.g, color.b, color.a));
Director::getInstance()->getRenderer()->addCommand(&_meshCommand);

View File

@ -38,6 +38,7 @@ NS_CC_BEGIN
class GLProgramState;
class Mesh;
class Texture2D;
class MeshSkin;
/** Sprite3D: TODO add description */
class Sprite3D : public Node, public BlendProtocol
@ -54,18 +55,24 @@ public:
void setTexture(Texture2D* texture);
Mesh* getMesh() const { return _mesh; }
MeshSkin* getSkin() const { return _skin; }
// overrides
virtual void setBlendFunc(const BlendFunc &blendFunc) override;
virtual const BlendFunc &getBlendFunc() const override;
protected:
CC_CONSTRUCTOR_ACCESS:
Sprite3D();
virtual ~Sprite3D();
bool initWithFile(const std::string &path);
//.mtl file should at the same directory with the same name if exist
bool loadFromObj(const std::string& path);
//load from .c3b or .c3t
bool loadFromC3x(const std::string& path);
virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
@ -73,7 +80,10 @@ protected:
void genGLProgramState();
protected:
Mesh *_mesh;
MeshSkin *_skin;
MeshCommand _meshCommand;
Texture2D* _texture;
BlendFunc _blend;

View File

@ -1,145 +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 "3d/CCSprite3DDataCache.h"
#include "3d/CCMesh.h"
#include "platform/CCFileUtils.h"
#include "renderer/CCTextureCache.h"
#include "base/CCEventCustom.h"
#include "base/CCEventListenerCustom.h"
#include "base/CCEventDispatcher.h"
#include "base/CCEventType.h"
#include "base/CCDirector.h"
NS_CC_BEGIN
Sprite3DDataCache* Sprite3DDataCache::_cacheInstance = nullptr;
Sprite3DDataCache::Sprite3DDataCache()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// listen the event when app go to foreground
_backToForegroundlistener = EventListenerCustom::create(EVENT_COME_TO_FOREGROUND, CC_CALLBACK_1(Sprite3DDataCache::listenBackToForeground, this));
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundlistener, -1);
#endif
}
Sprite3DDataCache::~Sprite3DDataCache()
{
removeAllSprite3DData();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
Director::getInstance()->getEventDispatcher()->removeEventListener(_backToForegroundlistener);
#endif
}
Sprite3DDataCache* Sprite3DDataCache::getInstance()
{
if (! _cacheInstance)
{
_cacheInstance = new Sprite3DDataCache();
}
return _cacheInstance;
}
void Sprite3DDataCache::purgeMeshCache()
{
if (_cacheInstance)
{
CC_SAFE_DELETE(_cacheInstance);
}
}
bool Sprite3DDataCache::addSprite3D(const std::string& fileName, Mesh* mesh, const std::string& texture)
{
const std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
auto itr = _sprite3DDatas.find(fullPath);
if (itr == _sprite3DDatas.end())
{
Sprite3DData data;
data.mesh = mesh;
CC_SAFE_RETAIN(mesh);
data.texture = texture;
_sprite3DDatas[fullPath] = data;
return true;
}
return false;
}
Mesh* Sprite3DDataCache::getSprite3DMesh(const std::string& fileName)
{
const std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
auto itr = _sprite3DDatas.find(fullPath);
if (itr != _sprite3DDatas.end())
return itr->second.mesh;
return nullptr;
}
Texture2D* Sprite3DDataCache::getSprite3DTexture(const std::string& fileName)
{
const std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
auto itr = _sprite3DDatas.find(fullPath);
if (itr != _sprite3DDatas.end())
{
auto cache = Director::getInstance()->getTextureCache();
return cache->addImage(itr->second.texture);
}
return nullptr;
}
void Sprite3DDataCache::removeAllSprite3DData()
{
for (auto itr = _sprite3DDatas.begin(); itr != _sprite3DDatas.end(); itr++) {
CC_SAFE_RELEASE_NULL(itr->second.mesh);
}
_sprite3DDatas.clear();
}
void Sprite3DDataCache::removeUnusedSprite3DData()
{
for( auto it=_sprite3DDatas.cbegin(); it!=_sprite3DDatas.cend(); /* nothing */) {
auto value = it->second;
if( value.mesh->getReferenceCount() == 1 ) {
CCLOG("cocos2d: GLProgramStateCache: removing unused GLProgramState");
value.mesh->release();
_sprite3DDatas.erase(it++);
} else {
++it;
}
}
}
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
void Sprite3DDataCache::listenBackToForeground(EventCustom* event)
{
for (auto iter = _sprite3DDatas.begin(); iter != _sprite3DDatas.end(); ++iter)
{
auto mesh = iter->second.mesh;
mesh->restore();
}
}
#endif
NS_CC_END

View File

@ -0,0 +1,111 @@
/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "3d/CCSprite3DMaterial.h"
#include "platform/CCFileUtils.h"
#include "renderer/CCTextureCache.h"
#include "base/CCEventCustom.h"
#include "base/CCEventListenerCustom.h"
#include "base/CCEventDispatcher.h"
#include "base/CCEventType.h"
#include "base/CCDirector.h"
NS_CC_BEGIN
Sprite3DMaterialCache* Sprite3DMaterialCache::_cacheInstance = nullptr;
Sprite3DMaterialCache::Sprite3DMaterialCache()
{
}
Sprite3DMaterialCache::~Sprite3DMaterialCache()
{
removeAllSprite3DMaterial();
}
Sprite3DMaterialCache* Sprite3DMaterialCache::getInstance()
{
if (! _cacheInstance)
{
_cacheInstance = new Sprite3DMaterialCache();
}
return _cacheInstance;
}
void Sprite3DMaterialCache::destroyInstance()
{
if (_cacheInstance)
{
CC_SAFE_DELETE(_cacheInstance);
}
}
bool Sprite3DMaterialCache::addSprite3DMaterial(const std::string& key, Texture2D* texture)
{
auto itr = _materials.find(key);
if (itr == _materials.end())
{
CC_SAFE_RETAIN(texture);
_materials[key] = texture;
return true;
}
return false;
}
Texture2D* Sprite3DMaterialCache::getSprite3DMaterial(const std::string& key)
{
auto itr = _materials.find(key);
if (itr != _materials.end())
{
return itr->second;
}
return nullptr;
}
void Sprite3DMaterialCache::removeAllSprite3DMaterial()
{
for (auto itr = _materials.begin(); itr != _materials.end(); itr++) {
CC_SAFE_RELEASE_NULL(itr->second);
}
_materials.clear();
}
void Sprite3DMaterialCache::removeUnusedSprite3DMaterial()
{
for( auto it=_materials.cbegin(); it!=_materials.cend(); /* nothing */) {
auto value = it->second;
if( value->getReferenceCount() == 1 ) {
CCLOG("cocos2d: GLProgramStateCache: removing unused GLProgramState");
value->release();
_materials.erase(it++);
} else {
++it;
}
}
}
NS_CC_END

View File

@ -22,8 +22,8 @@
THE SOFTWARE.
****************************************************************************/
#ifndef __CCSPRIT3DDATA_CACHE_H__
#define __CCSPRIT3DDATA_CACHE_H__
#ifndef __CCSPRIT3DMATERIAL_H__
#define __CCSPRIT3DMATERIAL_H__
#include <string>
#include <unordered_map>
@ -38,46 +38,34 @@ class EventListenerCustom;
class EventCustom;
class Texture2D;
class Sprite3DDataCache
/**
* the sprite3D material is only texture for now
*/
class Sprite3DMaterialCache
{
public:
struct Sprite3DData
{
Mesh* mesh;
std::string texture;
};
static Sprite3DDataCache* getInstance();
static void purgeMeshCache();
static Sprite3DMaterialCache* getInstance();
static void destroyInstance();
bool addSprite3D(const std::string& fileName, Mesh* mesh, const std::string& texture);
bool addSprite3DMaterial(const std::string& key, Texture2D* tex);
Mesh* getSprite3DMesh(const std::string& fileName);
Texture2D* getSprite3DMaterial(const std::string& key);
Texture2D* getSprite3DTexture(const std::string& fileName);
void removeAllSprite3DMaterial();
void removeUnusedSprite3DMaterial();
void removeAllSprite3DData();
void removeUnusedSprite3DData();
CC_CONSTRUCTOR_ACCESS:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
void listenBackToForeground(EventCustom* event);
#endif
Sprite3DMaterialCache();
~Sprite3DMaterialCache();
protected:
Sprite3DDataCache();
static Sprite3DMaterialCache* _cacheInstance;
std::unordered_map<std::string, Texture2D*> _materials; //
~Sprite3DDataCache();
static Sprite3DDataCache* _cacheInstance;
std::unordered_map<std::string, Sprite3DData> _sprite3DDatas; //sprites
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
EventListenerCustom* _backToForegroundlistener;
#endif
};
NS_CC_END
#endif // __CCSPRIT3DDATA_CACHE_H__
#endif // __CCSPRIT3DMATERIAL_H__

View File

@ -2,6 +2,10 @@ set(COCOS_3D_SRC
3d/CCMesh.cpp
3d/CCObjLoader.cpp
3d/CCSprite3D.cpp
3d/CCSprite3DDataCache.cpp
3d/CCSprite3DMaterial.cpp
3d/CCAnimate3D.cpp
3d/CCAnimation3D.cpp
3d/CCBundle3D.cpp
3d/CCMeshSkin.cpp
)

View File

@ -71,8 +71,12 @@ cocos2d.cpp \
2d/CCTransitionPageTurn.cpp \
2d/CCTransitionProgress.cpp \
2d/CCTweenFunction.cpp \
3d/CCAnimate3D.cpp \
3d/CCAnimation3D.cpp \
3d/CCBundle3D.cpp \
3d/CCMesh.cpp \
3d/CCSprite3DDataCache.cpp \
3d/CCMeshSkin.cpp \
3d/CCSprite3DMaterial.cpp \
3d/CCObjLoader.cpp \
3d/CCSprite3D.cpp \
platform/CCGLViewProtocol.cpp \
@ -185,12 +189,13 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) \
LOCAL_C_INCLUDES := $(LOCAL_PATH) \
$(LOCAL_PATH)/. \
$(LOCAL_PATH)/platform/android \
$(LOCAL_PATH)/../external \
$(LOCAL_PATH)/../external/tinyxml2 \
$(LOCAL_PATH)/../external/unzip \
$(LOCAL_PATH)/../external/chipmunk/include/chipmunk \
$(LOCAL_PATH)/../external/edtaa3func \
$(LOCAL_PATH)/../external/xxhash \
$(LOCAL_PATH)/../external/ConvertUTF
$(LOCAL_PATH)/../external/ConvertUTF
LOCAL_LDLIBS := -lGLESv2 \

View File

@ -134,8 +134,8 @@
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v120_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v120_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@ -144,8 +144,8 @@
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v120_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v120_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -206,4 +206,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -73,6 +73,7 @@ const char* GLProgram::SHADER_NAME_LABEL_OUTLINE = "ShaderLabelOutline";
const char* GLProgram::SHADER_3D_POSITION = "Shader3DPosition";
const char* GLProgram::SHADER_3D_POSITION_TEXTURE = "Shader3DPositionTexture";
const char* GLProgram::SHADER_3D_SKINPOSITION_TEXTURE = "Shader3DSkinPositionTexture";
// uniform names
@ -94,7 +95,8 @@ 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_NORMAL = "a_normal";
const char* GLProgram::ATTRIBUTE_NAME_BLEND_WEIGHT = "a_blendWeight";
const char* GLProgram::ATTRIBUTE_NAME_BLEND_INDEX = "a_blendIndex";
GLProgram* GLProgram::createWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{
@ -359,6 +361,12 @@ void GLProgram::parseUniforms()
}
uniform.name = std::string(uniformName);
uniform.location = glGetUniformLocation(_program, uniformName);
GLenum __gl_error_code = glGetError();
if (__gl_error_code != GL_NO_ERROR)
{
CCLOG("error: 0x%x", (int)__gl_error_code);
}
assert(__gl_error_code == GL_NO_ERROR);
_userUniforms[uniform.name] = uniform;
}

View File

@ -85,6 +85,8 @@ public:
VERTEX_ATTRIB_COLOR,
VERTEX_ATTRIB_TEX_COORD,
VERTEX_ATTRIB_NORMAL,
VERTEX_ATTRIB_BLEND_WEIGHT,
VERTEX_ATTRIB_BLEND_INDEX,
VERTEX_ATTRIB_MAX,
@ -130,6 +132,7 @@ public:
//3D
static const char* SHADER_3D_POSITION;
static const char* SHADER_3D_POSITION_TEXTURE;
static const char* SHADER_3D_SKINPOSITION_TEXTURE;
// uniform names
static const char* UNIFORM_NAME_P_MATRIX;
@ -150,6 +153,8 @@ public:
static const char* ATTRIBUTE_NAME_POSITION;
static const char* ATTRIBUTE_NAME_TEX_COORD;
static const char* ATTRIBUTE_NAME_NORMAL;
static const char* ATTRIBUTE_NAME_BLEND_WEIGHT;
static const char* ATTRIBUTE_NAME_BLEND_INDEX;
GLProgram();
virtual ~GLProgram();

View File

@ -51,6 +51,7 @@ enum {
kShaderType_LabelOutline,
kShaderType_3DPosition,
kShaderType_3DPositionTex,
kShaderType_3DSkinPositionTex,
kShaderType_MAX,
};
@ -200,6 +201,9 @@ void GLProgramCache::loadDefaultGLPrograms()
loadDefaultGLProgram(p, kShaderType_3DPositionTex);
_programs.insert( std::make_pair(GLProgram::SHADER_3D_POSITION_TEXTURE, p) );
p = new GLProgram();
loadDefaultGLProgram(p, kShaderType_3DSkinPositionTex);
_programs.insert(std::make_pair(GLProgram::SHADER_3D_SKINPOSITION_TEXTURE, p));
}
void GLProgramCache::reloadDefaultGLPrograms()
@ -297,6 +301,9 @@ void GLProgramCache::reloadDefaultGLPrograms()
p->reset();
loadDefaultGLProgram(p, kShaderType_3DPositionTex);
p = getGLProgram(GLProgram::SHADER_3D_SKINPOSITION_TEXTURE);
p->reset();
loadDefaultGLProgram(p, kShaderType_3DSkinPositionTex);
}
void GLProgramCache::loadDefaultGLProgram(GLProgram *p, int type)
@ -356,6 +363,9 @@ void GLProgramCache::loadDefaultGLProgram(GLProgram *p, int type)
case kShaderType_3DPositionTex:
p->initWithByteArrays(cc3D_PositionTex_vert, cc3D_ColorTex_frag);
break;
case kShaderType_3DSkinPositionTex:
p->initWithByteArrays(cc3D_SkinPositionTex_vert, cc3D_ColorTex_frag);
break;
default:
CCLOG("cocos2d: %s:%d, error shader type", __FUNCTION__, __LINE__);
return;

View File

@ -69,7 +69,7 @@ UniformValue::~UniformValue()
void UniformValue::apply()
{
if(_useCallback) {
(*_value.callback)(_uniform);
(*_value.callback)(_glprogram, _uniform);
}
else
{
@ -110,7 +110,7 @@ void UniformValue::apply()
}
}
void UniformValue::setCallback(const std::function<void(Uniform*)> &callback)
void UniformValue::setCallback(const std::function<void(GLProgram*, Uniform*)> &callback)
{
// delete previously set callback
// XXX TODO: memory will leak if the user does:
@ -119,7 +119,7 @@ void UniformValue::setCallback(const std::function<void(Uniform*)> &callback)
if (_useCallback)
delete _value.callback;
_value.callback = new std::function<void(Uniform*)>();
_value.callback = new std::function<void(GLProgram*, Uniform*)>();
*_value.callback = callback;
_useCallback = true;
@ -422,7 +422,7 @@ void GLProgramState::setVertexAttribPointer(const std::string &name, GLint size,
// Uniform Setters
void GLProgramState::setUniformCallback(const std::string &uniformName, const std::function<void(Uniform*)> &callback)
void GLProgramState::setUniformCallback(const std::string &uniformName, const std::function<void(GLProgram*, Uniform*)> &callback)
{
auto v = getUniformValue(uniformName);
if (v)

View File

@ -62,7 +62,7 @@ public:
void setVec3(const Vec3& value);
void setVec4(const Vec4& value);
void setMat4(const Mat4& value);
void setCallback(const std::function<void(Uniform*)> &callback);
void setCallback(const std::function<void(GLProgram*, Uniform*)> &callback);
void setTexture(GLuint textureId, GLuint activeTexture);
void apply();
@ -83,7 +83,7 @@ protected:
GLuint textureId;
GLuint textureUnit;
} tex;
std::function<void(Uniform*)> *callback;
std::function<void(GLProgram*, Uniform*)> *callback;
U() { memset( this, 0, sizeof(*this) ); }
~U(){}
@ -176,7 +176,7 @@ public:
void setUniformVec3(const std::string &uniformName, const Vec3& value);
void setUniformVec4(const std::string &uniformName, const Vec4& value);
void setUniformMat4(const std::string &uniformName, const Mat4& value);
void setUniformCallback(const std::string &uniformName, const std::function<void(Uniform*)> &callback);
void setUniformCallback(const std::string &uniformName, const std::function<void(GLProgram*, Uniform*)> &callback);
void setUniformTexture(const std::string &uniformName, Texture2D *texture);
void setUniformTexture(const std::string &uniformName, GLuint textureId);

View File

@ -26,10 +26,12 @@
#include "base/CCDirector.h"
#include "renderer/CCMeshCommand.h"
#include "renderer/ccGLStateCache.h"
#include "renderer/CCGLProgram.h"
#include "renderer/CCGLProgramState.h"
#include "renderer/CCRenderer.h"
#include "renderer/CCTextureAtlas.h"
#include "renderer/CCTexture2D.h"
#include "renderer/ccGLStateCache.h"
NS_CC_BEGIN
@ -42,6 +44,8 @@ MeshCommand::MeshCommand()
, _depthTestEnabled(false)
, _depthWriteEnabled(false)
, _displayColor(1.0f, 1.0f, 1.0f, 1.0f)
, _matrixPalette(nullptr)
, _matrixPaletteSize(0)
{
_type = RenderCommand::Type::MESH_COMMAND;
}
@ -134,6 +138,11 @@ void MeshCommand::restoreRenderState()
}
}
void MeshCommand::MatrixPalleteCallBack( GLProgram* glProgram, Uniform* uniform)
{
glProgram->setUniformLocationWith4fv(uniform->location, (const float*)_matrixPalette, _matrixPaletteSize);
}
void MeshCommand::execute()
{
// set render state
@ -145,6 +154,13 @@ void MeshCommand::execute()
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
_glProgramState->setUniformVec4("u_color", _displayColor);
if (_matrixPaletteSize && _matrixPalette)
{
_glProgramState->setUniformCallback("u_matrixPalette", CC_CALLBACK_2(MeshCommand::MatrixPalleteCallBack, this));
}
_glProgramState->apply(_mv);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);

View File

@ -33,6 +33,8 @@
NS_CC_BEGIN
class GLProgramState;
class GLProgram;
class Uniform;
//it is a common mesh
class MeshCommand : public RenderCommand
@ -53,6 +55,10 @@ public:
void setDepthWriteEnabled(bool enable);
void setDisplayColor(const Vec4& color);
void setMatrixPalette(const Vec4* matrixPalette) { _matrixPalette = matrixPalette; }
void setMatrixPaletteSize(int size) { _matrixPaletteSize = size; }
void execute();
@ -62,6 +68,8 @@ protected:
//restore to all false
void restoreRenderState();
void MatrixPalleteCallBack( GLProgram* glProgram, Uniform* uniform);
GLuint _textureID;
GLProgramState* _glProgramState;
@ -71,6 +79,10 @@ protected:
Vec4 _displayColor; // in order to support tint and fade in fade out
// used for skin
const Vec4* _matrixPalette;
int _matrixPaletteSize;
GLuint _vertexBuffer;
GLuint _indexBuffer;
GLenum _primitive;

View File

@ -13,3 +13,69 @@ void main(void)
TextureCoordOut.y = 1.0 - TextureCoordOut.y;
}
);
const char* cc3D_SkinPositionTex_vert = STRINGIFY(
attribute vec4 a_position;
attribute vec4 a_blendWeight;
attribute vec4 a_blendIndex;
attribute vec2 a_texCoord;
const int SKINNING_JOINT_COUNT = 60;
// Uniforms
uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3];
// Varyings
varying vec2 TextureCoordOut;
vec4 _skinnedPosition;
vec4 getPosition()
{
vec4 matrixPalette1 = vec4(0.0);
vec4 matrixPalette2 = vec4(0.0);
vec4 matrixPalette3 = vec4(0.0);
float blendWeight = a_blendWeight[0];
int matrixIndex = int (a_blendIndex[0]) * 3;
matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight;
matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight;
matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight;
blendWeight = a_blendWeight[1];
matrixIndex = int(a_blendIndex[1]) * 3;
matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight;
matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight;
matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight;
blendWeight = a_blendWeight[2];
matrixIndex = int(a_blendIndex[2]) * 3;
matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight;
matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight;
matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight;
blendWeight = a_blendWeight[3];
matrixIndex = int(a_blendIndex[3]) * 3;
matrixPalette1 += u_matrixPalette[matrixIndex] * blendWeight;
matrixPalette2 += u_matrixPalette[matrixIndex + 1] * blendWeight;
matrixPalette3 += u_matrixPalette[matrixIndex + 2] * blendWeight;
_skinnedPosition.x = dot(a_position, matrixPalette1);
_skinnedPosition.y = dot(a_position, matrixPalette2);
_skinnedPosition.z = dot(a_position, matrixPalette3);
_skinnedPosition.w = a_position.w;
return _skinnedPosition;
}
void main()
{
vec4 position = getPosition();
gl_Position = CC_MVPMatrix * position;
TextureCoordOut = a_texCoord;
TextureCoordOut.y = 1.0 - TextureCoordOut.y;
}
);

View File

@ -70,6 +70,7 @@ extern CC_DLL const GLchar * ccLabelOutline_frag;
extern CC_DLL const GLchar * ccLabel_vert;
extern CC_DLL const GLchar * cc3D_PositionTex_vert;
extern CC_DLL const GLchar * cc3D_SkinPositionTex_vert;
extern CC_DLL const GLchar * cc3D_ColorTex_frag;
extern CC_DLL const GLchar * cc3D_Color_frag;
// end of shaders group

View File

@ -22,8 +22,8 @@
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v120_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@ -31,8 +31,8 @@
<PlatformToolset Condition="'$(VisualStudioVersion)' == '10.0'">v100</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0'">v110</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '11.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v110_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v120_xp</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '12.0' and exists('$(MSBuildProgramFiles32)\Microsoft SDKs\Windows\v7.1A')">v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">

View File

@ -192,8 +192,19 @@
"cocos/3d/CCObjLoader.h",
"cocos/3d/CCSprite3D.cpp",
"cocos/3d/CCSprite3D.h",
"cocos/3d/CCSprite3DDataCache.cpp",
"cocos/3d/CCSprite3DDataCache.h",
"cocos/3d/CCSprite3DMaterial.cpp",
"cocos/3d/CCSprite3DMaterial.h",
"cocos/3d/CCMeshSkin.h",
"cocos/3d/CCMeshSkin.cpp",
"cocos/3d/CCBundle3DData.h",
"cocos/3d/CCBundle3D.h",
"cocos/3d/CCBundle3D.cpp",
"cocos/3d/CCAnimationCurve.inl",
"cocos/3d/CCAnimationCurve.h",
"cocos/3d/CCAnimation3D.h",
"cocos/3d/CCAnimation3D.cpp",
"cocos/3d/CCAnimate3D.h",
"cocos/3d/CCAnimate3D.cpp",
"cocos/3d/CMakeLists.txt",
"cocos/Android.mk",
"cocos/CMakeLists.txt",

View File

@ -24,6 +24,8 @@
****************************************************************************/
#include "Sprite3DTest.h"
#include "3d/CCAnimation3D.h"
#include "3d/CCAnimate3D.h"
#include <algorithm>
#include "../testResource.h"
@ -41,7 +43,8 @@ static int sceneIdx = -1;
static std::function<Layer*()> createFunctions[] =
{
CL(Sprite3DBasicTest),
CL(Sprite3DEffectTest)
CL(Sprite3DEffectTest),
CL(Sprite3DWithSkinTest)
};
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
@ -517,3 +520,61 @@ void Sprite3DEffectTest::onTouchesEnded(const std::vector<Touch*>& touches, Even
addNewSpriteWithCoords( location );
}
}
Sprite3DWithSkinTest::Sprite3DWithSkinTest()
{
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesEnded = CC_CALLBACK_2(Sprite3DWithSkinTest::onTouchesEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
auto s = Director::getInstance()->getWinSize();
addNewSpriteWithCoords( Vec2(s.width/2, s.height/2) );
}
std::string Sprite3DWithSkinTest::title() const
{
return "Testing Sprite3D for animation from c3t";
}
std::string Sprite3DWithSkinTest::subtitle() const
{
return "Tap screen to add more sprite3D";
}
void Sprite3DWithSkinTest::addNewSpriteWithCoords(Vec2 p)
{
auto sprite = Sprite3D::create("Sprite3DTest/girl.c3t");
addChild(sprite);
sprite->setRotation3D(Vec3(-90.f, 0.f, 0.f));
sprite->setPosition( Vec2( p.x, p.y) );
auto animation = Animation3D::getOrCreate("Sprite3DTest/girl.c3t");
if (animation)
{
auto animate = Animate3D::create(animation);
if(std::rand() %3 == 0)
{
animate->setPlayBack(true);
}
int rand2 = std::rand();
if(rand2 % 3 == 1)
{
animate->setSpeed(animate->getSpeed() + CCRANDOM_0_1());
}
else if(rand2 % 3 == 2)
{
animate->setSpeed(animate->getSpeed() - 0.5 * CCRANDOM_0_1());
}
sprite->runAction(RepeatForever::create(animate));
}
}
void Sprite3DWithSkinTest::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
{
for (auto touch: touches)
{
auto location = touch->getLocation();
addNewSpriteWithCoords( location );
}
}

View File

@ -138,6 +138,19 @@ public:
void onTouchesEnded(const std::vector<Touch*>& touches, Event* event);
};
class Sprite3DWithSkinTest : public Sprite3DTestDemo
{
public:
CREATE_FUNC(Sprite3DWithSkinTest);
Sprite3DWithSkinTest();
virtual std::string title() const override;
virtual std::string subtitle() const override;
void addNewSpriteWithCoords(Vec2 p);
void onTouchesEnded(const std::vector<Touch*>& touches, Event* event);
};
class Sprite3DTestScene : public TestScene
{
public:

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@ -0,0 +1,162 @@
{
"version": "1.2",
"file_type": "c3t",
"mesh_data": [
{
"version": "1.2",
"mesh_vertex_attribute": [
{
"size":3,
"type":"GL_FLOAT",
"vertex_attribute":"VERTEX_ATTRIB_POSITION"
},
{
"size":3,
"type":"GL_FLOAT",
"vertex_attribute":"VERTEX_ATTRIB_NORMAL"
},
{
"size":2,
"type":"GL_FLOAT",
"vertex_attribute":"VERTEX_ATTRIB_TEX_COORD"
},
{
"size":4,
"type":"GL_FLOAT",
"vertex_attribute":"VERTEX_ATTRIB_BLEND_WEIGHT"
},
{
"size":4,
"type":"GL_FLOAT",
"vertex_attribute":"VERTEX_ATTRIB_BLEND_INDEX"
}
],
"body":[
{
"vertices": [
0.000000, -2.259414, -2.259414, 0.000000, 0.000000, -1.000000, 0.582997, 0.456003, 0.500033, 0.499967, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
-5.314565, -2.259414, -2.259414, 0.000000, 0.000000, -1.000000, 0.582997, 0.168971, 0.933581, 0.066419, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 2.259414, -2.259414, 0.000000, 0.000000, -1.000000, 0.827052, 0.456003, 0.500111, 0.499889, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
-5.314565, 2.259414, -2.259414, 0.000000, 0.000000, -1.000000, 0.827052, 0.168971, 0.932199, 0.067801, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
0.000000, -2.259414, 2.259414, 0.000000, -1.000000, 0.000000, 0.253258, 0.705932, 0.500033, 0.499967, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
-5.314565, -2.259414, 2.259414, 0.000000, -1.000000, 0.000000, 0.253258, 0.418900, 0.933581, 0.066419, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
-5.314565, -2.259414, -2.259414, 0.000000, -1.000000, 0.000000, 0.497313, 0.418900, 0.933581, 0.066419, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
0.000000, -2.259414, -2.259414, 0.000000, -1.000000, 0.000000, 0.497313, 0.705932, 0.500033, 0.499967, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
-5.314565, 2.259414, 2.259414, -1.000000, 0.000000, 0.000000, 0.753117, 0.748774, 0.932199, 0.067801, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
-5.314565, -2.259414, -2.259414, -1.000000, 0.000000, 0.000000, 0.997172, 0.992829, 0.933581, 0.066419, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
-5.314565, -2.259414, 2.259414, -1.000000, 0.000000, 0.000000, 0.753117, 0.992829, 0.933581, 0.066419, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
-5.314565, 2.259414, -2.259414, -1.000000, 0.000000, 0.000000, 0.997172, 0.748774, 0.932199, 0.067801, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
5.314565, -2.259414, -2.259414, 0.000000, 0.000000, -1.000000, 0.582997, 0.743034, 0.932057, 0.067943, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, 2.259414, -2.259414, 0.000000, 0.000000, -1.000000, 0.827052, 0.743034, 0.938571, 0.061429, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, -2.259414, 2.259414, 0.000000, -1.000000, 0.000000, 0.253258, 0.992964, 0.932057, 0.067943, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, -2.259414, -2.259414, 0.000000, -1.000000, 0.000000, 0.497313, 0.992964, 0.932057, 0.067943, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, 2.259414, 2.259414, 1.000000, 0.000000, 0.000000, 0.503187, 0.992829, 0.938571, 0.061429, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, -2.259414, 2.259414, 1.000000, 0.000000, 0.000000, 0.503187, 0.748774, 0.932057, 0.067943, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, -2.259414, -2.259414, 1.000000, 0.000000, 0.000000, 0.747243, 0.748774, 0.932057, 0.067943, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, 2.259414, -2.259414, 1.000000, 0.000000, 0.000000, 0.747243, 0.992829, 0.938571, 0.061429, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 2.259414, 2.259414, 0.000000, 1.000000, 0.000000, 0.003328, 0.705932, 0.500111, 0.499889, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
-5.314565, 2.259414, -2.259414, 0.000000, 1.000000, 0.000000, 0.247384, 0.992964, 0.932199, 0.067801, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
-5.314565, 2.259414, 2.259414, 0.000000, 1.000000, 0.000000, 0.003328, 0.992964, 0.932199, 0.067801, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 2.259414, -2.259414, 0.000000, 1.000000, 0.000000, 0.247384, 0.705932, 0.500111, 0.499889, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, 2.259414, 2.259414, 0.000000, 1.000000, 0.000000, 0.003328, 0.418900, 0.938571, 0.061429, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, 2.259414, -2.259414, 0.000000, 1.000000, 0.000000, 0.247384, 0.418900, 0.938571, 0.061429, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
0.000000, 2.259414, 2.259414, 0.000000, 0.000000, 1.000000, 0.290226, 0.413161, 0.500111, 0.499889, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
-5.314565, 2.259414, 2.259414, 0.000000, 0.000000, 1.000000, 0.003194, 0.413161, 0.932199, 0.067801, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
-5.314565, -2.259414, 2.259414, 0.000000, 0.000000, 1.000000, 0.003194, 0.169105, 0.933581, 0.066419, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000,
0.000000, -2.259414, 2.259414, 0.000000, 0.000000, 1.000000, 0.290226, 0.169105, 0.500033, 0.499967, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, 2.259414, 2.259414, 0.000000, 0.000000, 1.000000, 0.577257, 0.413161, 0.938571, 0.061429, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000,
5.314565, -2.259414, 2.259414, 0.000000, 0.000000, 1.000000, 0.577257, 0.169105, 0.932057, 0.067943, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000
],
"vertex_size": 512,
"indices": [
0, 1, 2, 1, 3, 2, 4, 5, 6, 4, 6, 7,
8, 9, 10, 9, 8, 11, 12, 0, 13, 0, 2, 13,
14, 4, 7, 14, 7, 15, 16, 17, 18, 16, 18, 19,
20, 21, 22, 21, 20, 23, 24, 23, 20, 23, 24, 25,
26, 27, 28, 26, 28, 29, 30, 26, 29, 30, 29, 31
],
"index_number": 60
}
]
}
],
"material_data": [
{
"file_name": "Sprite3DTest/checkboard.png"
}
],
"skin_data": [
{
"id": "cubeanim:cube",
"bind_shape": [ 0.393701, 0.000000, 0.000000, 0.000000, 0.000000, 0.393701, 0.000000, 0.000000, 0.000000, -0.000000, 0.393701, 0.000000, 0.100748, 0.000000, -0.457948, 1.000000],
"bones": [
{
"node": "bone1",
"bind_pos": [ 0.999989, 0.004613, 0.000000, 0.000000, -0.004613, 0.999989, 0.000000, 0.000000, -0.000000, -0.000000, 1.000000, 0.000000, -0.036861, 0.049203, 0.000000, 1.000000]
},
{
"node": "bone",
"bind_pos": [ 0.999958, 0.009184, 0.000000, 0.000000, -0.009184, 0.999958, 0.000000, 0.000000, -0.000000, -0.000000, 1.000000, 0.000000, -5.393930, -0.000000, -0.000000, 1.000000]
}
]
},
{
"id": "root",
"children": [
{
"id": "bone",
"children": [
{
"id": "bone1",
"children": [
{
"id": "eff"
}
]
}
]
}
]
}
],
"animation_data": [
{
"id": "Take 001",
"bones": [
{
"id": "bone1",
"keyframes": [
{
"rotation":[
{
"keytime": 0.000000,
"value": [ 0.000000, -0.000000, -0.002285, 0.999997]
},
{
"keytime": 0.333332,
"value": [ 0.000000, -0.000000, -0.002285, 0.999997]
},
{
"keytime": 0.666664,
"value": [ 0.000000, -0.000000, 0.089457, 0.995991]
},
{
"keytime": 0.800000,
"value": [ 0.000000, -0.000000, 0.184131, 0.982902]
},
{
"keytime": 0.933328,
"value": [ 0.000000, -0.000000, 0.274421, 0.961610]
},
{
"keytime": 1.000000,
"value": [ 0.000000, -0.000000, 0.362349, 0.932043]
}
]
}
]
}
]
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff