diff --git a/node.h b/node.h index a3cdfa3..fea21bc 100755 --- a/node.h +++ b/node.h @@ -68,6 +68,7 @@ namespace vb01{ inline std::string getName(){return name;} inline void setVisible(bool v){this->visible = v;} inline void addDriver(Driver *d){drivers.push_back(d);} + inline AnimationController* getAnimationController(){return controller;} private: void adjustUp(Vector3); void adjustDir(Vector3); diff --git a/script.py b/script.py index a498a3e..f334add 100644 --- a/script.py +++ b/script.py @@ -104,7 +104,7 @@ def exportData(ob): for vert in shape_key.data: pos = vert.co file.write(str(pos.x) + ' ' + str(pos.y) + ' ' + str(pos.z) + ' \n') - channels.extend(mesh.shape_keys.animation_data.drivers) + channels.extend(mesh.shape_keys.animation_data.drivers) file.write('animations: ' + str(numAnims) + '\n') @@ -146,10 +146,12 @@ def getChannelType(channel): return channelType -def readChannel(channel): +def readChannel(animatableName, channel): channelType = getChannelType(channel) - numKeyframes = len(channel.keyframe_points) + + file.write(animatableName + ' ' + channelType + ' ' + str(numKeyframes) + ' \n') + for i in range(numKeyframes): keyframe = channel.keyframe_points[i] keyframeId = keyframe.co[0] @@ -191,34 +193,22 @@ def readDriver(channel, driverName): numKeyframes = len(channel.keyframe_points) channelType = getChannelType(channel) - file.write(driverName + ' 1 ' + channelType + ' ' + str(numKeyframes) + ' \n') + #file.write(driverName + ' 1 ' + channelType + ' ' + str(numKeyframes) + ' \n') - readChannel(channel) + readChannel(driverName, channel) def readAnimations(ob, 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('animation: ' + animName) - file.write('\ngroups: ' + str(numAnimBones)) + file.write('animation: ' + animName + ' ' + str(len(action.fcurves)) + ' \n') print('Exporting animation ' + animName + '...\n') - file.write('\n') - - for group in action.groups: - file.write((ob.name if group.name == 'Object Transforms' else group.name) + ' ' + str(len(group.channels)) + ' ') - - for channel in group.channels: - numKeyframes = len(channel.keyframe_points) - channelType = getChannelType(channel) - file.write(channelType + ' ' + str(numKeyframes) + ' ') - - file.write('\n') - - for channel in group.channels: - readChannel(channel) + for channel in action.fcurves: + group = channel.group + readChannel((ob.name if group is None or group.name == 'Object Transforms' else group.name), channel) fl = bpy.data.filepath dotId = 0 diff --git a/vbModelReader.cpp b/vbModelReader.cpp index cea2e15..250f0f2 100644 --- a/vbModelReader.cpp +++ b/vbModelReader.cpp @@ -228,35 +228,23 @@ namespace vb01{ } } - vector VbModelReader::readKeyframeChannels(Animatable *animatable, vector &animationData, int &keyframeGroupStartLine){ - string dataLine[2]; - getLineData(animationData[keyframeGroupStartLine], dataLine, 2); + KeyframeChannel VbModelReader::readKeyframeChannel(Animatable *animatable, vector &animationData, int &keyframeChannelStartLine){ + string channelData[3]; + getLineData(animationData[keyframeChannelStartLine], channelData, 3); - int numKeyframeChannels = atoi(dataLine[1].c_str()); - string channelData[2 * numKeyframeChannels]; - getLineData(animationData[keyframeGroupStartLine], channelData, 2 * numKeyframeChannels, 2); + string animatableName = channelData[0], typeStr = channelData[1]; + int numKeyframes = atoi(channelData[2].c_str()); + int keyframeStartLine = keyframeChannelStartLine + 1; - vector keyframeChannels; - int numTypeKeyframes[numKeyframeChannels]; - int numKeyframes = 0; - for(int k = 0; k < numKeyframeChannels; k++){ - KeyframeChannel keyframeChannel; + KeyframeChannel keyframeChannel; + keyframeChannel.animatable = (animatable || !currentSkeleton ? animatable : currentSkeleton->getBone(animatableName)); + keyframeChannel.type = KeyframeChannel::getKeyframeChannelType(typeStr); - keyframeChannel.type = KeyframeChannel::getKeyframeChannelType(channelData[2 * k]); - numTypeKeyframes[k] = atoi(channelData[2 * k + 1].c_str()); - numKeyframes += numTypeKeyframes[k]; - keyframeChannel.animatable = (animatable || !currentSkeleton ? animatable : currentSkeleton->getBone(dataLine[0])); - - keyframeChannels.push_back(keyframeChannel); - } - - int keyframeStartLine = keyframeGroupStartLine + 1; - int currentChannel = 0, numCurrentTypeKeyframes = 0; for(int k = 0; k < numKeyframes; k++){ string keyframeLine = animationData[keyframeStartLine + k]; string keyframeData[7]; getLineData(keyframeLine, keyframeData, 7); - + Keyframe keyframe; keyframe.value = atof(keyframeData[0].c_str()); keyframe.frame = atof(keyframeData[1].c_str()); @@ -265,44 +253,34 @@ namespace vb01{ keyframe.leftHandleFrame = atof(keyframeData[4].c_str()); keyframe.rightHandleValue = atof(keyframeData[5].c_str()); keyframe.rightHandleFrame = atof(keyframeData[6].c_str()); - keyframeChannels[currentChannel].keyframes.push_back(keyframe); - numCurrentTypeKeyframes++; - if(numCurrentTypeKeyframes == numTypeKeyframes[currentChannel]){ - currentChannel++; - numCurrentTypeKeyframes = 0; - } + keyframeChannel.keyframes.push_back(keyframe); } - return keyframeChannels; + keyframeChannelStartLine += numKeyframes + 1; + + return keyframeChannel; } void VbModelReader::readAnimations(Animatable *animatable, AnimationController *controller, vector &animationData){ - int numAnimations = atoi(animationData[0].substr(animationData[0].find_first_of(':') + 1).c_str()); + int numAnimations = atoi(animationData[0].substr(animationData[0].find_first_of(':') + 2).c_str()); int animStartLine = 1; for(int i = 0; i < numAnimations; i++){ string animLine = animationData[animStartLine]; - currentAnim = animLine.substr(animLine.find_first_of(':') + 2); - string groupsLine = animationData[animStartLine + 1]; + string data[2]; + getLineData(animLine.substr(animLine.find_first_of(':') + 2), data, 2); + currentAnim = data[0]; Animation *animation = new Animation(currentAnim); controller->addAnimation(animation); - int numKeyframeGroups = atoi(groupsLine.substr(groupsLine.find_first_of(':') + 2).c_str()); - int keyframeGroupStartLine = animStartLine + 2; - for(int j = 0; j < numKeyframeGroups; j++){ - vector keyframeChannels = readKeyframeChannels(animatable, animationData, keyframeGroupStartLine); - int numKeyframes = 0; - for(KeyframeChannel channel : keyframeChannels){ - animation->addKeyframeChannel(channel); - numKeyframes += channel.keyframes.size(); - } - - keyframeGroupStartLine += numKeyframes + 1; - } - - animStartLine = keyframeGroupStartLine; + int numKeyframeChannels = atoi(data[1].c_str()); + int keyframeChannelStartLine = animStartLine + 1; + for(int j = 0; j < numKeyframeChannels; j++) + animation->addKeyframeChannel(readKeyframeChannel(animatable, animationData, keyframeChannelStartLine)); + + animStartLine = keyframeChannelStartLine; } } @@ -317,22 +295,22 @@ namespace vb01{ bool driverIsBone = (data[numData - 1] != ""); Driver::VariableType type = Driver::getDriverVariableType(driverIsBone ? data[numData - 1] : data[numData - 2]); - int keyframeGroupStartLine = driverStartLine + 1; - vector keyframeChannels = readKeyframeChannels(nullptr, meshData, keyframeGroupStartLine); - + int keyframeChannelStartLine = driverStartLine + 1; string drivingNode = data[0]; string drivingBone = (driverIsBone ? data[1] : ""); string drivenAnimatable = objectName; string channelData[1]; - getLineData(meshData[keyframeGroupStartLine], channelData, 1); + getLineData(meshData[keyframeChannelStartLine], channelData, 1); string drivenSubAnimatable = channelData[0]; string *driverSetup = new string[4]{drivingNode, drivingBone, drivenAnimatable, drivenSubAnimatable}; driverSetups.push_back(driverSetup); - drivers.push_back(new Driver(keyframeChannels[0], type)); + KeyframeChannel keyframeChannel = readKeyframeChannel(nullptr, meshData, keyframeChannelStartLine); - driverStartLine += 2 + keyframeChannels[0].keyframes.size(); + drivers.push_back(new Driver(keyframeChannel, type)); + + driverStartLine += 2 + keyframeChannel.keyframes.size(); } } diff --git a/vbModelReader.h b/vbModelReader.h index 238ceb2..f34d140 100644 --- a/vbModelReader.h +++ b/vbModelReader.h @@ -25,7 +25,7 @@ namespace vb01{ void connectNodes(); void setupDrivers(); void createBones(Skeleton*, std::vector&); - std::vector readKeyframeChannels(Animatable*, std::vector&, int&); + KeyframeChannel readKeyframeChannel(Animatable*, std::vector&, int&); void readAnimations(Animatable*, AnimationController*, std::vector&); Skeleton* readSkeleton(std::vector&); void readVertices(std::vector&, std::vector&, std::vector&, std::vector&, int); diff --git a/vbModelReaderTest.cpp b/vbModelReaderTest.cpp index 2d8ce81..5f391eb 100644 --- a/vbModelReaderTest.cpp +++ b/vbModelReaderTest.cpp @@ -49,41 +49,51 @@ namespace vb01{ skeletonData.push_back(b.name + ": " + b.parent + " " + headStr + xAxisStr + yAxisStr + b.ikTarget + " " + to_string(b.ikChainLength) + " "); } skeletonData.push_back("animations: 2"); - skeletonData.push_back("animation: Action"); - skeletonData.push_back("groups: 2 "); - skeletonData.push_back("bipod.L 7 pos_x 2 pos_y 2 pos_z 2 rot_w 2 rot_x 2 rot_y 2 rot_z 2 "); + skeletonData.push_back("animation: Action 13 "); + skeletonData.push_back("bipod.L pos_x 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("0 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.L pos_y 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("0 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.L pos_z 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("0 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.L rot_w 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("0 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.L rot_x 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("0 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.L rot_y 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("0 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.L rot_z 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("0 10 2 1 1 1 1 "); - skeletonData.push_back("bipod.R 6 pos_x 2 pos_y 2 pos_z 2 rot_w 2 rot_x 2 rot_y 2 "); + skeletonData.push_back("bipod.R pos_x 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("10 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.R pos_y 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("10 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.R pos_z 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("10 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.R rot_w 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("10 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.R rot_x 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("10 10 2 1 1 1 1 "); + skeletonData.push_back("bipod.R rot_y 2 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("10 10 2 1 1 1 1 "); - skeletonData.push_back("animation: open"); - skeletonData.push_back("groups: 1 "); - skeletonData.push_back("opening 1 rot_w 2 rot_x 1"); + skeletonData.push_back("animation: open 2 "); + skeletonData.push_back("opening rot_w 2 "); skeletonData.push_back("1 1 2 1 1 1 1 "); skeletonData.push_back("0 10 2 1 1 1 1 "); + skeletonData.push_back("opening rot_x 1 "); skeletonData.push_back("0 1 2 1 1 1 1 "); skeletonData.push_back("drivers: 0"); }