void LodConfigSerializer::readLodConfig() { pushInnerChunk(mStream); while(!mStream->eof()) { unsigned short streamID = readChunk(mStream); switch(streamID) { case LCCID_BASIC_INFO: readLodBasicInfo(); break; case LCCID_LOD_LEVELS: readLodLevels(); break; case LCCID_ADVANCED_INFO: readLodAdvancedInfo(); break; case LCCID_PROFILE: readLodProfile(); break; default: // Backpedal back to start of stream backpedalChunkHeader(mStream); popInnerChunk(mStream); return; } } popInnerChunk(mStream); }
void LodConfigSerializer::importLodConfig(Ogre::LodConfig* config, DataStreamPtr& stream) { mStream = stream; mLodConfig = config; // Determine endianness (must be the first thing we do!) determineEndianness(mStream); // Check header readFileHeader(mStream); pushInnerChunk(mStream); while (!mStream->eof()) { unsigned short streamID = readChunk(mStream); switch (streamID) { case LCCID_LOD_CONFIG: readLodConfig(); break; default: backpedalChunkHeader(mStream); popInnerChunk(mStream); return; } } popInnerChunk(mStream); }
void LodConfigSerializer::exportLodConfig(Ogre::LodConfig& config, Ogre::DataStreamPtr stream, Endian endianMode /*= ENDIAN_NATIVE*/ ) { Ogre::LogManager::getSingleton().logMessage("MeshSerializer writing mesh data to stream " + stream->getName() + "..."); // Decide on endian mode determineEndianness(endianMode); mLodConfig = &config; mStream = stream; if (!stream->isWriteable()) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Unable to use stream " + stream->getName() + " for writing", "LodConfigSerializer::export"); } writeFileHeader(); LogManager::getSingleton().logMessage("File header written."); LogManager::getSingleton().logMessage("Writing Lod Config..."); pushInnerChunk(mStream); writeLodConfig(); popInnerChunk(mStream); LogManager::getSingleton().logMessage("LodConfigSerializer export successful."); }
void LodConfigSerializer::writeLodConfig() { writeChunkHeader(LCCID_LOD_CONFIG, calcLodConfigSize()); pushInnerChunk(mStream); writeLodBasicInfo(); writeLodLevels(); writeLodAdvancedInfo(); writeLodProfile(); popInnerChunk(mStream); }
//--------------------------------------------------------------------- void SkeletonSerializer::readAnimation(DataStreamPtr& stream, Skeleton* pSkel) { // char* name : Name of the animation String name; name = readString(stream); // float length : Length of the animation in seconds float len; readFloats(stream, &len, 1); Animation *pAnim = pSkel->createAnimation(name, len); // Read all tracks if (!stream->eof()) { pushInnerChunk(stream); unsigned short streamID = readChunk(stream); // Optional base info is possible if (streamID == SKELETON_ANIMATION_BASEINFO) { // char baseAnimationName String baseAnimName = readString(stream); // float baseKeyFrameTime float baseKeyTime; readFloats(stream, &baseKeyTime, 1); pAnim->setUseBaseKeyFrame(true, baseKeyTime, baseAnimName); if (!stream->eof()) { // Get next stream streamID = readChunk(stream); } } while(streamID == SKELETON_ANIMATION_TRACK && !stream->eof()) { readAnimationTrack(stream, pAnim, pSkel); if (!stream->eof()) { // Get next stream streamID = readChunk(stream); } } if (!stream->eof()) { // Backpedal back to start of this stream if we've found a non-track backpedalChunkHeader(stream); } popInnerChunk(stream); } }
//--------------------------------------------------------------------- void SkeletonSerializer::exportSkeleton(const Skeleton* pSkeleton, DataStreamPtr stream, SkeletonVersion ver, Endian endianMode) { setWorkingVersion(ver); // Decide on endian mode determineEndianness(endianMode); mStream = stream; if (!stream->isWriteable()) { OGRE_EXCEPT(Exception::ERR_CANNOT_WRITE_TO_FILE, "Unable to write to stream " + stream->getName(), "SkeletonSerializer::exportSkeleton"); } writeFileHeader(); pushInnerChunk(mStream); // Write main skeleton data LogManager::getSingleton().logMessage("Exporting bones.."); writeSkeleton(pSkeleton, ver); LogManager::getSingleton().logMessage("Bones exported."); // Write all animations unsigned short numAnims = pSkeleton->getNumAnimations(); LogManager::getSingleton().stream() << "Exporting animations, count=" << numAnims; for (unsigned short i = 0; i < numAnims; ++i) { Animation* pAnim = pSkeleton->getAnimation(i); LogManager::getSingleton().stream() << "Exporting animation: " << pAnim->getName(); writeAnimation(pSkeleton, pAnim, ver); LogManager::getSingleton().logMessage("Animation exported."); } // Write links Skeleton::LinkedSkeletonAnimSourceIterator linkIt = pSkeleton->getLinkedSkeletonAnimationSourceIterator(); while(linkIt.hasMoreElements()) { const LinkedSkeletonAnimationSource& link = linkIt.getNext(); writeSkeletonAnimationLink(pSkeleton, link); } popInnerChunk(stream); }
//--------------------------------------------------------------------- void SkeletonSerializer::writeAnimationTrack(const Skeleton* pSkel, const NodeAnimationTrack* track) { writeChunkHeader(SKELETON_ANIMATION_TRACK, calcAnimationTrackSize(pSkel, track)); // unsigned short boneIndex : Index of bone to apply to Bone* bone = static_cast<Bone*>(track->getAssociatedNode()); unsigned short boneid = bone->getHandle(); writeShorts(&boneid, 1); pushInnerChunk(mStream); // Write all keyframes for (unsigned short i = 0; i < track->getNumKeyFrames(); ++i) { writeKeyFrame(pSkel, track->getNodeKeyFrame(i)); } popInnerChunk(mStream); }
//--------------------------------------------------------------------- void SkeletonSerializer::importSkeleton(DataStreamPtr& stream, Skeleton* pSkel) { // Determine endianness (must be the first thing we do!) determineEndianness(stream); // Check header readFileHeader(stream); pushInnerChunk(stream); unsigned short streamID = readChunk(stream); while(!stream->eof()) { switch (streamID) { case SKELETON_BLENDMODE: { // Optional blend mode uint16 blendMode; readShorts(stream, &blendMode, 1); pSkel->setBlendMode(static_cast<SkeletonAnimationBlendMode>(blendMode)); break; } case SKELETON_BONE: readBone(stream, pSkel); break; case SKELETON_BONE_PARENT: readBoneParent(stream, pSkel); break; case SKELETON_ANIMATION: readAnimation(stream, pSkel); break; case SKELETON_ANIMATION_LINK: readSkeletonAnimationLink(stream, pSkel); break; default: break; } streamID = readChunk(stream); } // Assume bones are stored in the binding pose pSkel->setBindingPose(); popInnerChunk(stream); }
//--------------------------------------------------------------------- void SkeletonSerializer::writeAnimation(const Skeleton* pSkel, const Animation* anim, SkeletonVersion ver) { writeChunkHeader(SKELETON_ANIMATION, calcAnimationSize(pSkel, anim, ver)); // char* name : Name of the animation writeString(anim->getName()); // float length : Length of the animation in seconds float len = anim->getLength(); writeFloats(&len, 1); pushInnerChunk(mStream); { if ((int)ver > (int)SKELETON_VERSION_1_0) { if (anim->getUseBaseKeyFrame()) { size_t size = SSTREAM_OVERHEAD_SIZE; // char* baseAnimationName (including terminator) size += calcStringSize(anim->getBaseKeyFrameAnimationName()); // float baseKeyFrameTime size += sizeof(float); writeChunkHeader(SKELETON_ANIMATION_BASEINFO, size); // char* baseAnimationName (blank for self) writeString(anim->getBaseKeyFrameAnimationName()); // float baseKeyFrameTime float t = (float)anim->getBaseKeyFrameTime(); writeFloats(&t, 1); } } // Write all tracks Animation::NodeTrackIterator trackIt = anim->getNodeTrackIterator(); while(trackIt.hasMoreElements()) { writeAnimationTrack(pSkel, trackIt.getNext()); } } popInnerChunk(mStream); }
//--------------------------------------------------------------------- void SkeletonSerializer::readAnimationTrack(DataStreamPtr& stream, Animation* anim, Skeleton* pSkel) { // unsigned short boneIndex : Index of bone to apply to unsigned short boneHandle; readShorts(stream, &boneHandle, 1); // Find bone Bone *targetBone = pSkel->getBone(boneHandle); // Create track NodeAnimationTrack* pTrack = anim->createNodeTrack(boneHandle, targetBone); // Keep looking for nested keyframes if (!stream->eof()) { pushInnerChunk(stream); unsigned short streamID = readChunk(stream); while(streamID == SKELETON_ANIMATION_TRACK_KEYFRAME && !stream->eof()) { readKeyFrame(stream, pTrack, pSkel); if (!stream->eof()) { // Get next stream streamID = readChunk(stream); } } if (!stream->eof()) { // Backpedal back to start of this stream if we've found a non-keyframe backpedalChunkHeader(stream); } popInnerChunk(stream); } }