diff --git a/animation.cpp b/animation.cpp index f2f355a..e8f1221 100644 --- a/animation.cpp +++ b/animation.cpp @@ -42,8 +42,17 @@ namespace vb01{ return type; } - KeyframeChannel Animation::getKeyframeChannel(Bone *bone, KeyframeChannelType type){ - KeyframeChannel k; + KeyframeChannel* Animation::getKeyframeChannel(Bone *bone, KeyframeChannelType type){ + KeyframeChannel *k = nullptr; + + KeyframeGroup *group = getKeyframeGroup(bone); + for(KeyframeChannel &channel : group->keyframeChannels){ + if(channel.type == type){ + k = &channel; + break; + } + } + return k; } } diff --git a/animation.h b/animation.h index c122d9d..af3c450 100644 --- a/animation.h +++ b/animation.h @@ -44,8 +44,9 @@ namespace vb01{ ~Animation(); void update(); KeyframeGroup* getKeyframeGroup(Bone *b); - KeyframeGroup::KeyframeChannel getKeyframeChannel(Bone *b, KeyframeGroup::KeyframeChannel::Type); + KeyframeGroup::KeyframeChannel* getKeyframeChannel(Bone *b, KeyframeGroup::KeyframeChannel::Type); static KeyframeGroup::KeyframeChannel::Type getKeyframeChannelType(std::string&); + inline int getNumKeyframeGroups(){return keyframeGroups.size();} inline std::string getName(){return name;} inline void addKeyframeGroup(KeyframeGroup k){keyframeGroups.push_back(k);} private: diff --git a/animationController.h b/animationController.h index 237dba5..a7868e4 100644 --- a/animationController.h +++ b/animationController.h @@ -17,6 +17,7 @@ namespace vb01{ ~AnimationController(); void update(); Animation* getAnimation(std::string); + inline std::vector getAnimations(){return animations;} inline void addAnimation(Animation *anim){animations.push_back(anim);} inline void addAnimationChannel(AnimationChannel *channel){channels.push_back(channel);} private: diff --git a/model.h b/model.h index b322f2f..fc94306 100755 --- a/model.h +++ b/model.h @@ -17,6 +17,7 @@ namespace vb01{ class Model : public Node{ public: + Model(){} Model(std::string); ~Model(); void update(); diff --git a/script.py b/script.py index 650af6b..c2862b4 100644 --- a/script.py +++ b/script.py @@ -11,15 +11,15 @@ def exportData(ob): file.write('rot: ' + str(ob.rotation_quaternion.w) + ' ' + str(ob.rotation_quaternion.x) + ' ' + str(ob.rotation_quaternion.y) + ' ' + str(-ob.rotation_quaternion.z) + '\n') file.write('scale: ' + str(ob.scale.x) + ' ' + str(ob.scale.y) + ' ' + str(ob.scale.z) + '\n') file.write('parent: ' + ('-' if par is None else par.name) + '\n') - if(ob.type=="ARMATURE"): - numAnims=len(ob.animation_data.nla_tracks[0].strips) + if(ob.type == "ARMATURE"): + numAnims = len(ob.animation_data.nla_tracks[0].strips) file.write("bones: "+str(len(ob.data.bones)) + ' ' + str(numAnims) + ' ') for bone in ob.data.bones: - head=bone.head - tail=bone.tail - xAxis=bone.x_axis - yAxis=bone.y_axis + head = bone.head + tail = bone.tail + xAxis = bone.x_axis + yAxis = bone.y_axis ikTarget = '-' chainLength = -1 @@ -38,111 +38,75 @@ def exportData(ob): else: chainLength = ikConstraint.chain_count - file.write('\n'+bone.name+': '+('None' if bone.parent is None else bone.parent.name)+" "+str(bone.length)+" "+str(head.x)+" "+str(head.y)+" "+str(head.z)+" "+str(xAxis.x)+" "+str(xAxis.y)+" "+str(xAxis.z)+" "+str(yAxis.x)+" "+str(yAxis.y)+" "+str(yAxis.z)+ " " + ikTarget + ' ' + str(chainLength) + ' ') + file.write('\n' + bone.name + ': ' + ('None' if bone.parent is None else bone.parent.name) + " " + str(bone.length) + " " + str(head.x) + " " + str(head.y) + " " + str(head.z) + " " + str(xAxis.x) + " " + str(xAxis.y) + " " + str(xAxis.z) + " " + str(yAxis.x) + " " + str(yAxis.y) + " " + str(yAxis.z) + " " + ikTarget + ' ' + str(chainLength) + ' ') - if numAnims>0: - file.write("\nanimations: "+str(numAnims)) + if numAnims > 0: + file.write("\nanimations: " + str(numAnims)) for nlaStrip in ob.animation_data.nla_tracks[0].strips: - animName=nlaStrip.name - action=bpy.data.actions[animName] - numAnimBones=len(action.groups) - file.write('\nanimation: ' + animName + ' ') + animName = nlaStrip.name + action = bpy.data.actions[animName] + numAnimBones = len(action.groups) + file.write('\nanimation: ' + animName + ' ' + str(numAnimBones) + ' ') print('Exporting animation '+animName+'...\n') - file.write(str(len(action.groups)) + ' ') - for group in action.groups: - file.write(group.name + ' ') file.write('\n') for group in action.groups: - bone=ob.data.bones[group.name] - start=nlaStrip.frame_start - end=nlaStrip.frame_end + bone = ob.data.bones[group.name] + start = nlaStrip.frame_start + end = nlaStrip.frame_end - file.write(group.name + ': ') + file.write(animName + ' ' + group.name + ' ') for channel in group.channels: - numKeyframes=len(channel.keyframe_points) - file.write(str(numKeyframes) + ' ') - - dotId=-1 - typeLen=len(channel.data_path)-1 - i=typeLen - while(i>=0): - if channel.data_path[i]=='.': - dotId=i - break - i=i-1 - - coordType=channel.data_path[dotId+1:typeLen+1] - arrInd=channel.array_index - coords="wxyz" - - if coordType=="location": - file.write("pos_"+coords[arrInd+1]) - elif coordType=="rotation_quaternion": - file.write("rot_"+coords[arrInd]) - elif coordType=="scale": - file.write("scale_"+coords[arrInd+1]) - file.write(' ') + numKeyframes = len(channel.keyframe_points) + channelType = getChannelType(channel) + file.write(str(numKeyframes) + ' ' + channelType + ' ') file.write('\n') - for channel in group.channels: - numKeyframes=len(channel.keyframe_points) - dotId=-1 - typeLen=len(channel.data_path)-1 - i=typeLen - while(i>=0): - if channel.data_path[i]=='.': - dotId=i - break - i=i-1 - coordType=channel.data_path[dotId+1:typeLen+1] - arrInd=channel.array_index - coords="wxyz" - ''' - if coordType=="location": - file.write("pos_"+coords[arrInd+1]) - elif coordType=="rotation_quaternion": - file.write("rot_"+coords[arrInd]) - elif coordType=="scale": - file.write("scale_"+coords[arrInd+1]) - file.write(': '+str(numKeyframes)+'\n') - ''' - for keyframe in channel.keyframe_points: - keyframeId=keyframe.co[0] - interp=keyframe.interpolation - bpy.context.scene.frame_set(int(start)+int(keyframeId)) - poseBone=ob.pose.bones[group.name] - interpInt=-1 - - if interp=='CONSTANT': - interpInt=0 - elif interp=='LINEAR': - interpInt=1 - elif interp=='BEZIER': - interpInt=2 - - if bpy.context.scene.frame_current>end: - bpy.context.scene.frame_current=bpy.context.scene.frame_current-1 - if coordType=="location": - file.write(str(poseBone.location[arrInd])) - elif coordType=="rotation_quaternion": - file.write(str(poseBone.rotation_quaternion[arrInd])) - elif coordType=="scale": - file.write(str(poseBone.scale[arrInd])) - file.write(" "+str(keyframeId)+" "+str(interpInt)) - if interp=='BEZIER': - 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 + bone = ob.data.bones[group.name] + start = nlaStrip.frame_start + end = nlaStrip.frame_end + for channel in group.channels: + channelType = getChannelType(channel) + + dotId = channel.data_path.rfind('.') + 1 + arrInd = channel.array_index + coordType = channel.data_path[dotId :] + + for keyframe in channel.keyframe_points: + keyframeId = keyframe.co[0] + interp = keyframe.interpolation + bpy.context.scene.frame_set(int(start) + int(keyframeId)) + poseBone = ob.pose.bones[group.name] + interpInt = - 1 + + if interp == 'CONSTANT': + interpInt = 0 + elif interp == 'LINEAR': + interpInt = 1 + elif interp == 'BEZIER': + interpInt = 2 + + file.write(animName + ' ' + bone.name + ' ' + channelType + ' ') + + if bpy.context.scene.frame_current > end: + bpy.context.scene.frame_current = bpy.context.scene.frame_current - 1 + if coordType == "location": + file.write(str(poseBone.location[arrInd])) + elif coordType == "rotation_quaternion": + file.write(str(poseBone.rotation_quaternion[arrInd])) + elif coordType == "scale": + file.write(str(poseBone.scale[arrInd])) + file.write(" " + str(keyframeId) + " " + str(interpInt)) + if interp == 'BEZIER': + 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") elif(ob.type=="MESH"): @@ -151,34 +115,34 @@ def exportData(ob): if(skeleton): skeletonName = skeleton.name file.write('skeleton: ' + skeletonName + '\n') - mesh=ob.data + mesh = ob.data - numFaces=len(mesh.polygons) - numVerts=len(mesh.vertices) - numGroups=len(ob.vertex_groups) - numShapeKeys=0 + numFaces = len(mesh.polygons) + numVerts = len(mesh.vertices) + numGroups = len(ob.vertex_groups) + numShapeKeys = 0 #if mesh.shape_keys is not NoneType: #numShapeKeys=len(mesh.shape_keys[0].key_blocks)-1 - file.write("numElements: "+str(numVerts)+" "+str(numFaces)+" "+str(numGroups)+" "+str(numShapeKeys)+" \n") + file.write("numElements: " + str(numVerts) + " " + str(numFaces) + " " + str(numGroups) + " " + str(numShapeKeys) + " \n") - if numGroups>0: + if numGroups > 0: file.write('groups:\n') for group in ob.vertex_groups: - file.write(group.name+'\n') + file.write(group.name + '\n') file.write("vertices:\n") print('Exporting vertices...\n') for vert in mesh.vertices: - pos=vert.co - norm=vert.normal - weights=[] - for i in range(0,numGroups): + pos = vert.co + norm = vert.normal + weights = [] + for i in range(0, numGroups): weights.append(0.0) for g in vert.groups: - weights[g.group]=g.weight - file.write(str(pos.x)+" "+str(pos.y)+" "+str(pos.z)+" "+str(norm.x)+" "+str(norm.y)+" "+str(norm.z)+" ") + weights[g.group] = g.weight + file.write(str(pos.x) + " " + str(pos.y) + " " + str(pos.z) + " " + str(norm.x) + " " + str(norm.y) + " " + str(norm.z) + " ") for w in weights: file.write(str(w)+" ") file.write('\n') @@ -187,21 +151,21 @@ def exportData(ob): print('Exporting faces...\n') mesh.calc_tangents() for face in mesh.polygons: - for vert,loopInd in zip(face.vertices,face.loop_indices): - uv=mesh.uv_layers[0].data[loopInd].uv - loop=mesh.loops[loopInd] - tan=loop.tangent - bitan=loop.bitangent - file.write(str(vert)+" "+str(uv.x)+" "+str(uv.y)+" "+str(tan.x)+" "+str(tan.y)+" "+str(tan.z)+" "+str(bitan.x)+" "+str(bitan.y)+" "+str(bitan.z)+" \n") + for vert, loopInd in zip(face.vertices, face.loop_indices): + uv = mesh.uv_layers[0].data[loopInd].uv + loop = mesh.loops[loopInd] + tan = loop.tangent + bitan = loop.bitangent + file.write(str(vert) + " " + str(uv.x) + " " + str(uv.y) + " " + str(tan.x) + " " + str(tan.y) + " " + str(tan.z) + " " + str(bitan.x) + " " + str(bitan.y) + " " + str(bitan.z) + ' \n') mesh.free_tangents() - if numShapeKeys>0: + if numShapeKeys > 0: file.write('shapeKeys:\n') for shape_key in mesh.shape_keys.key_blocks: - if shape_key.name=='Basis': + if shape_key.name == 'Basis': continue - file.write(shape_key.name+'\n') + file.write(shape_key.name + '\n') ''' for face in mesh.polygons: for vert,loop in zip(face.vertices,mesh.loops): @@ -243,30 +207,46 @@ def exportData(ob): file.write('\n'+str(i)+" "+str(newPos.x)+' '+str(newPos.y)+' '+str(newPos.z)) ''' -fl=bpy.data.filepath -dotId=0 -for i in range(len(fl)): - if(fl[i]=='.'): - dotId=i - break -fl=fl[0:dotId]+".vb" +def getChannelType(channel): + channelType = '' -objects=[] -selectedObjects=bpy.context.selected_objects + dotId = channel.data_path.rfind('.') + 1; + coordType = channel.data_path[dotId :] + arrInd = channel.array_index + coords = 'wxyz' + + if coordType == "location": + channelType = "pos_" + coords[arrInd + 1] + elif coordType == "rotation_quaternion": + channelType = "rot_" + coords[arrInd] + elif coordType == "scale": + channelType = "scale_" + coords[arrInd + 1] + return channelType + +fl = bpy.data.filepath +dotId = 0 +for i in range(len(fl)): + if(fl[i] == '.'): + dotId = i + break +fl = fl[0 : dotId] + ".vb" + +objects = [] +selectedObjects = bpy.context.selected_objects for s in selectedObjects: - sPar=s + sPar = s while(sPar): - sPar=sPar.parent - inObjects=False + sPar = sPar.parent + inObjects = False for so in objects: - if(so==sPar): - inObjects=True + if(so == sPar): + inObjects = True break - if inObjects==False: + if inObjects == False: objects.append(sPar) -file=open(fl,"w") +file=open(fl, "w") for ob in selectedObjects: exportData(ob) file.write("}\n") diff --git a/vbModelReader.cpp b/vbModelReader.cpp index 2cfd66e..c9d2e53 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -162,11 +162,12 @@ namespace vb01{ int colonId = line.find_first_of(':'); if(colonId != -1){ string data[2]; - string postCol = line.substr(colonId + 1); + string postCol = line.substr(colonId + 2); getLineData(postCol, data, 2); string animName = data[0]; - int numBones = atoi(data[1].c_str()); - controller->addAnimation(new Animation(animName)); + + Animation *animation = new Animation(animName); + controller->addAnimation(animation); } } } @@ -181,18 +182,15 @@ namespace vb01{ Bone *animBone = skeleton->getBone(data[1]); int numChannelTypes = atoi(data[2].c_str()); - getLineData(line, data, numChannelTypes * 2, 3); + getLineData(line, data, numChannelTypes, 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()); + keyframeGroup.bone = animBone; + for(int i = 0; i < numChannelTypes; i++){ + string typeString = data[i]; KeyframeChannelType type = anim->getKeyframeChannelType(typeString); - - for(int j = 0; j < numChannels; j++){ - KeyframeChannel keyframeChannel; - keyframeChannel.type = type; - keyframeGroup.keyframeChannels.push_back(keyframeChannel); - } + KeyframeChannel keyframeChannel; + keyframeChannel.type = type; + keyframeGroup.keyframeChannels.push_back(keyframeChannel); } anim->addKeyframeGroup(keyframeGroup); } @@ -205,40 +203,42 @@ namespace vb01{ string data[numData]; getLineData(line, data, numData); Animation *anim = controller->getAnimation(data[0]); - Bone *animBone = skeleton->getBone(data[1]); + Bone *animBone = skeleton->getBone(data[1]); KeyframeChannelType type = anim->getKeyframeChannelType(data[2]); - KeyframeChannel channel = anim->getKeyframeChannel(animBone, type); + KeyframeChannel *channel = anim->getKeyframeChannel(animBone, type); 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); + + channel->keyframes.push_back(keyframe); } } Skeleton* VbModelReader::readSkeleton(vector &skeletonData){ - //vector skeletonMetaData(skeletonData.begin() + 1, skeletonData.begin() + 7); - string name = skeletonData[0].substr(getCharId(skeletonData[0], ':') + 2, string::npos); + string name = skeletonData[0].substr(getCharId(skeletonData[0], ':') + 2); string line = skeletonData[5]; string data[3]; getLineData(line, data, 3); int numBones = atoi(data[1].c_str()); - int numKeyframeGroups = -2; - int numAnimations = atoi(data[2].c_str()); + line = skeletonData[6 + numBones].substr(getCharId(skeletonData[6 + numBones], ':') + 2); + int numAnimations = atoi(line.c_str()); + line = skeletonData[7 + numBones].substr(getCharId(skeletonData[7 + numBones], ':') + 2); + int numKeyframeGroups = atoi(line.c_str()); - int boneStartLine = 7; - int animationStartLine = boneStartLine + numBones + 1; - int keyframeGroupStartLine = animationStartLine + numKeyframeGroups + 1; - int keyframeStartLine = animationStartLine + numAnimations + 1; + int boneStartLine = 6; + int animationStartLine = boneStartLine + numBones + 2; + int keyframeGroupStartLine = animationStartLine + numAnimations; + int keyframeStartLine = keyframeGroupStartLine + numKeyframeGroups; Skeleton *skeleton = new Skeleton(name); vector skeletonSubData = vector(skeletonData.begin() + boneStartLine, skeletonData.begin() + boneStartLine + numBones); createBones(skeleton, skeletonSubData); skeletonSubData.clear(); - + skeletonSubData = vector(skeletonData.begin() + animationStartLine, skeletonData.begin() + animationStartLine + numAnimations); readAnimations(skeleton, skeletonSubData); skeletonSubData.clear(); @@ -247,7 +247,7 @@ namespace vb01{ readKeyframesGroups(skeleton, skeletonSubData); skeletonSubData.clear(); - skeletonSubData = vector(skeletonData.begin() + keyframeGroupStartLine, skeletonData.end()); + skeletonSubData = vector(skeletonData.begin() + keyframeStartLine, skeletonData.end()); readKeyframes(skeleton, skeletonSubData); skeletonSubData.clear(); diff --git a/vbModelReaderTest.cpp b/vbModelReaderTest.cpp index 72c2df5..dcb9b7f 100644 --- a/vbModelReaderTest.cpp +++ b/vbModelReaderTest.cpp @@ -1,6 +1,7 @@ #include "vbModelReaderTest.h" #include "vbModelReader.h" #include "skeleton.h" +#include "animationController.h" using namespace std; @@ -10,6 +11,7 @@ namespace vb01{ VbModelReaderTest::~VbModelReaderTest(){} void VbModelReaderTest::setUp(){ + rootNode = Root::getSingleton()->getRootNode(); modelReader = new VbModelReader(); setupSkeleton(); setupMesh(); @@ -20,14 +22,17 @@ namespace vb01{ } void VbModelReaderTest::setupSkeleton(){ + model = new Model(); + rootNode->attachChild(model); + modelReader->model = model; + bones = vector({ - Bone("", "", Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(0, 0, 0), "", 0) + Bone("bipod", "-", Vector3(0, 0, 0), Vector3(1, 0, 0), Vector3(0, 1, 0), "", 0), + Bone("bipod.L", "bipod", Vector3(1, 0, 2), Vector3(1, 0, 0), Vector3(0, 0, -1), "", 0), + Bone("bipod.R", "bipod", Vector3(-1, 0, 2), Vector3(-1, 0, 0), Vector3(0, 0, -1), "", 0) }); skeletonParent = "-"; - animations = vector({ - }); - int numBones = bones.size(); skeletonData.push_back("ARMATURE: MG42"); @@ -35,16 +40,44 @@ namespace vb01{ skeletonData.push_back("rot: 1.0 0.0 0.0 -0.0"); skeletonData.push_back("scale: 1.0 1.0 1.0"); skeletonData.push_back("parent: " + skeletonParent); - skeletonData.push_back("bones: " + to_string(numBones) + " 1 "); + skeletonData.push_back("bones: " + to_string(numBones) + " "); for(vbReader::Bone b : bones){ string headStr = to_string(b.head.x) + " " + to_string(b.head.y) + " " + to_string(b.head.z) + " "; string xAxisStr = to_string(b.xAxis.x) + " " + to_string(b.xAxis.y) + " " + to_string(b.xAxis.z) + " "; string yAxisStr = to_string(b.yAxis.x) + " " + to_string(b.yAxis.y) + " " + to_string(b.yAxis.z) + " "; - skeletonData.push_back(b.name + ": " + " " + b.parent + " " + headStr + xAxisStr + yAxisStr + b.ikTarget + " " + to_string(b.ikChainLength) + " "); + skeletonData.push_back(b.name + ": " + b.parent + " " + headStr + xAxisStr + yAxisStr + b.ikTarget + " " + to_string(b.ikChainLength) + " "); } - skeletonData.push_back("animations: 1"); - skeletonData.push_back("animation: Action 3 bipod bipod.R bipod.L "); - skeletonData.push_back("bipod: 3 pos_x 3 pos_y 3 pos_z 3 rot_w 3 rot_x 3 rot_y 3 rot_z "); + skeletonData.push_back("animations: 1 "); + skeletonData.push_back("channels: 2 "); + skeletonData.push_back("animation: Action "); + skeletonData.push_back("Action bipod.L 7 pos_x pos_y pos_z rot_w rot_x rot_y rot_z "); + skeletonData.push_back("Action bipod.R 6 pos_x pos_y pos_z rot_w rot_x rot_y "); + skeletonData.push_back("Action bipod.L pos_x 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L pos_x 0 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L pos_y 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L pos_y 0 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L pos_z 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L pos_z 0 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L rot_w 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L rot_w 0 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L rot_x 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L rot_x 0 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L rot_y 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L rot_y 0 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L rot_z 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.L rot_z 0 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R pos_x 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R pos_x 10 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R pos_y 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R pos_y 10 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R pos_z 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R pos_z 10 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R rot_w 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R rot_w 10 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R rot_x 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R rot_x 10 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R rot_y 0 1 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); + skeletonData.push_back("Action bipod.R rot_y 10 10 2 AUTO_CLAMPED 1 1 AUTO_CLAMPED 1 1 "); } void VbModelReaderTest::setupMesh(){ @@ -105,7 +138,36 @@ namespace vb01{ } void VbModelReaderTest::testReadSkeletons(){ - //Skeleton *skeleton = modelReader->readSkeleton(skeletonData); + Skeleton *skeleton = modelReader->readSkeleton(skeletonData); + int numBones = skeleton->getNumBones(); + for(int i = 0; i < numBones; i++){ + CPPUNIT_ASSERT(skeleton->getBone(i)->getName() == bones[i].name); + + vb01::Bone *parent = (vb01::Bone*)skeleton->getBone(i)->getParent(); + /* + if(parent->getName() != "") + CPPUNIT_ASSERT(parent->getName() == bones[i].parent); + else + CPPUNIT_ASSERT(bones[i].parent == "-"); + */ + } + AnimationController *controller = skeleton->getAnimationController(); + Animation *animation = controller->getAnimation("Action"); + CPPUNIT_ASSERT(animation); + + KeyframeGroup *leftBipodGroup = animation->getKeyframeGroup(skeleton->getBone("bipod.L")); + KeyframeGroup *rightBipodGroup = animation->getKeyframeGroup(skeleton->getBone("bipod.R")); + CPPUNIT_ASSERT(leftBipodGroup); + CPPUNIT_ASSERT(rightBipodGroup); + for(KeyframeChannel keyframeChannel : leftBipodGroup->keyframeChannels) + CPPUNIT_ASSERT(keyframeChannel.keyframes.size() == 2); + for(KeyframeChannel keyframeChannel : rightBipodGroup->keyframeChannels) + CPPUNIT_ASSERT(keyframeChannel.keyframes.size() == 2); + + Keyframe lastRightBipodKeyframe = animation->getKeyframeChannel(skeleton->getBone("bipod.R"), KeyframeChannelType::ROT_Y)->keyframes[1]; + CPPUNIT_ASSERT(lastRightBipodKeyframe.value == 10); + CPPUNIT_ASSERT(lastRightBipodKeyframe.frame == 10); + CPPUNIT_ASSERT(lastRightBipodKeyframe.interpolation == KeyframeInterpolation::BEZIER); } void VbModelReaderTest::testReadMeshes(){ diff --git a/vbModelReaderTest.h b/vbModelReaderTest.h index 4d53209..0db0413 100644 --- a/vbModelReaderTest.h +++ b/vbModelReaderTest.h @@ -8,6 +8,7 @@ #include "vector.h" #include "animation.h" +#include "model.h" namespace vb01{ class VbModelReader; @@ -49,7 +50,9 @@ namespace vb01{ int ikChainLength; }; + Node *rootNode = nullptr; VbModelReader *modelReader = nullptr; + Model *model = nullptr; std::string meshName, skeletonName, meshParent, skeletonParent; std::vector vertexGroups; std::vector vertPos, vertNorm, vertTan, vertBiTan;