diff --git a/CMakeLists.txt b/CMakeLists.txt index 60b45b2..6f2189f 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ set(utils util.cpp) set(math quaternion.cpp vector.cpp matrix.cpp ray.cpp) set(render particleEmitter.cpp camera.cpp light.cpp material.cpp mesh.cpp model.cpp node.cpp quad.cpp box.cpp root.cpp shader.cpp texture.cpp) set(model modelReader.cpp assimpModelReader.cpp vbModelReader.cpp) -set(anim animationController.cpp animationChannel.cpp animation.cpp) +set(anim animationController.cpp animationChannel.cpp animation.cpp) set(armature skeleton.cpp bone.cpp) add_library(vb01 SHARED main.cpp ${render} ${math} ${model} ${utils} ${gui} ${armature} ${anim}) diff --git a/animation.cpp b/animation.cpp index cddadcd..f2f355a 100644 --- a/animation.cpp +++ b/animation.cpp @@ -22,4 +22,28 @@ namespace vb01{ } return id > -1 ? &(keyframeGroups[id]) : nullptr; } + + KeyframeChannelType Animation::getKeyframeChannelType(string &typeString){ + KeyframeChannelType type; + if(typeString == "pos_x") + type = KeyframeChannelType::POS_X; + else if(typeString == "pos_y") + type = KeyframeChannelType::POS_Y; + else if(typeString == "pos_z") + type = KeyframeChannelType::POS_Z; + else if(typeString == "rot_w") + type = KeyframeChannelType::ROT_W; + else if(typeString == "rot_x") + type = KeyframeChannelType::ROT_X; + else if(typeString == "rot_y") + type = KeyframeChannelType::ROT_Y; + else if(typeString == "rot_z") + type = KeyframeChannelType::ROT_Z; + return type; + } + + KeyframeChannel Animation::getKeyframeChannel(Bone *bone, KeyframeChannelType type){ + KeyframeChannel k; + return k; + } } diff --git a/animation.h b/animation.h index fa58044..c122d9d 100644 --- a/animation.h +++ b/animation.h @@ -44,6 +44,8 @@ namespace vb01{ ~Animation(); void update(); KeyframeGroup* getKeyframeGroup(Bone *b); + KeyframeGroup::KeyframeChannel getKeyframeChannel(Bone *b, KeyframeGroup::KeyframeChannel::Type); + static KeyframeGroup::KeyframeChannel::Type getKeyframeChannelType(std::string&); inline std::string getName(){return name;} inline void addKeyframeGroup(KeyframeGroup k){keyframeGroups.push_back(k);} private: diff --git a/script.py b/script.py index 0a85800..650af6b 100644 --- a/script.py +++ b/script.py @@ -86,12 +86,8 @@ def exportData(ob): elif coordType=="scale": file.write("scale_"+coords[arrInd+1]) file.write(' ') - file.write('\n') - for group in action.groups: - bone=ob.data.bones[group.name] - start=nlaStrip.frame_start - end=nlaStrip.frame_end + file.write('\n') for channel in group.channels: numKeyframes=len(channel.keyframe_points) @@ -115,7 +111,6 @@ def exportData(ob): file.write("scale_"+coords[arrInd+1]) file.write(': '+str(numKeyframes)+'\n') ''' - for keyframe in channel.keyframe_points: keyframeId=keyframe.co[0] interp=keyframe.interpolation @@ -143,6 +138,13 @@ def exportData(ob): file.write(" "+str(keyframe.handle_left_type)+" "+str(keyframe.handle_left.x)+" "+str(keyframe.handle_left.y)+" ") file.write(str(keyframe.handle_right_type)+" "+str(keyframe.handle_right.x)+" "+str(keyframe.handle_right.y)) file.write("\n") + + for group in action.groups: + bone=ob.data.bones[group.name] + start=nlaStrip.frame_start + end=nlaStrip.frame_end + + elif(ob.type=="MESH"): skeletonName = '-' skeleton = ob.modifiers['Armature'].object diff --git a/tags b/tags index 51d2ade..45dfc72 100755 --- a/tags +++ b/tags @@ -472,6 +472,8 @@ getIkTarget bone.h /^ inline Bone* getIkTarget(){return ikTarget;}$/;" f class getIndices mesh.h /^ inline unsigned int* getIndices(){return indices;}$/;" f class:vb01::Mesh typeref:typename:unsigned int * getInitAxis bone.h /^ inline Vector3 getInitAxis(int i){return initAxis[i];}$/;" f class:vb01::Bone typeref:typename:Vector3 getInnerAngle light.h /^ inline float getInnerAngle(){return innerAngle;}$/;" f class:vb01::Light typeref:typename:float +getKeyframeChannel animation.cpp /^ KeyframeChannel Animation::getKeyframeChannel(Bone *bone, KeyframeChannelType type){$/;" f class:vb01::Animation typeref:typename:KeyframeChannel +getKeyframeChannelType animation.cpp /^ KeyframeChannelType Animation::getKeyframeChannelType(string &typeString){$/;" f class:vb01::Animation typeref:typename:KeyframeChannelType getKeyframeGroup animation.cpp /^ Animation::KeyframeGroup* Animation::getKeyframeGroup(Bone *b){$/;" f class:vb01::Animation typeref:typename:Animation::KeyframeGroup * getLeft camera.h /^ inline Vector3 getLeft(){return left;}$/;" f class:vb01::Camera typeref:typename:Vector3 getLength bone.h /^ inline float getLength(){return length;}$/;" f class:vb01::Bone typeref:typename:float @@ -757,6 +759,8 @@ read stb_image.h /^ int (*read) (void *user,char *data,int size); \/\/ readAnimations vbModelReader.cpp /^ void VbModelReader::readAnimations(Skeleton *skeleton, vector &meshData){$/;" f class:vb01::VbModelReader typeref:typename:void readFaces vbModelReader.cpp /^ void VbModelReader::readFaces($/;" f class:vb01::VbModelReader typeref:typename:void readFile util.cpp /^ void readFile(string path, vector &lines, int firstLine, int lastLine){$/;" f namespace:vb01 typeref:typename:void +readKeyframes vbModelReader.cpp /^ void VbModelReader::readKeyframes(Skeleton *skeleton, vector &meshData){$/;" f class:vb01::VbModelReader typeref:typename:void +readKeyframesGroups vbModelReader.cpp /^ void VbModelReader::readKeyframesGroups(Skeleton *skeleton, vector &meshData){$/;" f class:vb01::VbModelReader typeref:typename:void readLights vbModelReader.cpp /^ void VbModelReader::readLights(int startLine, int endLine){$/;" f class:vb01::VbModelReader typeref:typename:void readMeshes vbModelReader.cpp /^ void VbModelReader::readMeshes(int startLine, int endLine){$/;" f class:vb01::VbModelReader typeref:typename:void readShapeKeys vbModelReader.cpp /^ void VbModelReader::readShapeKeys(int shapeKeyStartLine, int numShapes){$/;" f class:vb01::VbModelReader typeref:typename:void diff --git a/vbModelReader.cpp b/vbModelReader.cpp index 7a5bc3e..eed2c5b 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -144,77 +144,62 @@ namespace vb01{ void VbModelReader::readAnimations(Skeleton *skeleton, vector &meshData){ AnimationController *controller = skeleton->getAnimationController(); - string animName = ""; - Bone *animBone = nullptr; - Animation::KeyframeGroup::KeyframeChannel::Type type; - for(string line : meshData){ - int colonId = getCharId(line, ':'); - string preColon = line.substr(0, colonId); - if(preColon == "animationName"){ - string postColon = line.substr(colonId + 2, string::npos); - animName = postColon; + int colonId = line.find_first_of(':'); + if(colonId != -1){ + string data[2]; + string postCol = line.substr(colonId + 1); + getLineData(postCol, data, 2); + string animName = data[0]; + int numBones = atoi(data[1].c_str()); controller->addAnimation(new Animation(animName)); - continue; } - Bone *b = skeleton->getBone(preColon); - if(b){ - animBone = b; - Animation *anim = controller->getAnimation(animName); - Animation::KeyframeGroup *group = anim->getKeyframeGroup(animBone); + } + } - if(!group){ - Animation::KeyframeGroup kg; - kg.bone = animBone; - anim->addKeyframeGroup(kg); + void VbModelReader::readKeyframesGroups(Skeleton *skeleton, vector &meshData){ + AnimationController *controller = skeleton->getAnimationController(); + for(string line : meshData){ + string data[17]; + getLineData(line, data, 3); + + Animation *anim = controller->getAnimation(data[0]); + Bone *animBone = skeleton->getBone(data[1]); + int numChannelTypes = atoi(data[2].c_str()); + + getLineData(line, data, numChannelTypes * 2, 3); + KeyframeGroup keyframeGroup; + for(int i = 0; i < numChannelTypes * 2; i++){ + string typeString = data[i * 2]; + int numChannels = atoi(data[i * 2 + 1].c_str()); + KeyframeChannelType type = anim->getKeyframeChannelType(typeString); + + for(int j = 0; j < numChannels; j++){ + KeyframeChannel keyframeChannel; + keyframeChannel.type = type; + keyframeGroup.keyframeChannels.push_back(keyframeChannel); } } - else{ - KeyframeGroup *keyframeGroup = controller->getAnimation(animName)->getKeyframeGroup(animBone); - KeyframeInterpolation interp; - KeyframeChannel channel; + anim->addKeyframeGroup(keyframeGroup); + } + } - if(line == "}") - break; - else if(preColon == "pos_x" || preColon == "pos_y" || preColon == "pos_z" || preColon == "rot_w" || preColon == "rot_x" || preColon == "rot_y" || preColon == "rot_z"){ - if(preColon == "pos_x") - type = KeyframeChannelType::POS_X; - else if(preColon == "pos_y") - type = KeyframeChannelType::POS_Y; - else if(preColon == "pos_z") - type = KeyframeChannelType::POS_Z; - else if(preColon == "rot_w") - type = KeyframeChannelType::ROT_W; - else if(preColon == "rot_x") - type = KeyframeChannelType::ROT_X; - else if(preColon == "rot_y") - type = KeyframeChannelType::ROT_Y; - else if(preColon == "rot_z") - type = KeyframeChannelType::ROT_Z; + void VbModelReader::readKeyframes(Skeleton *skeleton, vector &meshData){ + AnimationController *controller = skeleton->getAnimationController(); + for(string line : meshData){ + int numData = 6; + string data[numData]; + getLineData(line, data, numData); + Animation *anim = controller->getAnimation(data[0]); + Bone *animBone = skeleton->getBone(data[1]); + KeyframeChannelType type = anim->getKeyframeChannelType(data[2]); + KeyframeChannel channel = anim->getKeyframeChannel(animBone, type); - channel.type = type; - keyframeGroup->keyframeChannels.push_back(channel); - } - else{ - int numData = 3; - string data[numData]; - - getLineData(line, data, numData); - - float value = atof(data[0].c_str()), frame = atoi(data[1].c_str()); - interp = (KeyframeInterpolation)atoi(data[2].c_str()); - - Animation::KeyframeGroup::KeyframeChannel::Keyframe keyframe; - //keyframe.type = type; - keyframe.interpolation = interp; - keyframe.value = value; - keyframe.frame = frame; - for(KeyframeChannel &channel : keyframeGroup->keyframeChannels) - if(channel.type == type) - channel.keyframes.push_back(keyframe); - //skeleton->getAnimationController()->getAnimation(animName)->getKeyframeGroup(animBone)->keyframes.push_back(keyframe); - } - } + Keyframe keyframe; + keyframe.value = atof(data[3].c_str()); + keyframe.frame = atoi(data[4].c_str()); + keyframe.interpolation = (KeyframeInterpolation)atoi(data[5].c_str()); + channel.keyframes.push_back(keyframe); } } @@ -227,9 +212,13 @@ namespace vb01{ getLineData(line, data, 3); int numBones = atoi(data[1].c_str()); + int numKeyframeGroups = -2; int numAnimations = atoi(data[2].c_str()); + int boneStartLine = startLine + 7; int animationStartLine = boneStartLine + numBones + 1; + int keyframeGroupStartLine = animationStartLine + numKeyframeGroups + 1; + int keyframeStartLine = animationStartLine + numAnimations + 1; Skeleton *skeleton = new Skeleton(name); skeletons.push_back(skeleton); @@ -239,9 +228,16 @@ namespace vb01{ createBones(skeleton, meshData); meshData.clear(); - readFile(path, meshData, animationStartLine, endLine + 1); + readFile(path, meshData, animationStartLine, animationStartLine + numAnimations); readAnimations(skeleton, meshData); + meshData.clear(); + readFile(path, meshData, keyframeGroupStartLine, keyframeGroupStartLine + numKeyframeGroups); + readKeyframesGroups(skeleton, meshData); + + meshData.clear(); + readFile(path, meshData, keyframeStartLine); + readKeyframes(skeleton, meshData); } void VbModelReader::readVertices( diff --git a/vbModelReader.h b/vbModelReader.h index 91622dc..f24e91d 100644 --- a/vbModelReader.h +++ b/vbModelReader.h @@ -24,6 +24,8 @@ namespace vb01{ void createBones(Skeleton*, std::vector&); void readAnimations(Skeleton*, std::vector&); + void readKeyframesGroups(Skeleton*, std::vector&); + void readKeyframes(Skeleton*, std::vector&); void readSkeleton(int, int); void readVertices(std::vector&, std::vector&, std::vector&, std::vector&, int); void readFaces(std::vector&, std::vector&, std::vector&, std::vector&, int, Mesh::Vertex*, u32*);