void Serializer::backpedalChunkHeader(DataStreamPtr& stream) { if (!stream->eof()){ stream->skip(-(int)calcChunkHeaderSize()); } #if OGRE_SERIALIZER_VALIDATE_CHUNKSIZE mChunkSizeStack.back() = stream->tell(); #endif }
//--------------------------------------------------------------------- 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()) { 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 stream->skip(-SSTREAM_OVERHEAD_SIZE); } } }
//--------------------------------------------------------------------- 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()) { 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 stream->skip(-STREAM_OVERHEAD_SIZE); } } }
//--------------------------------------------------------------------- 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()) { unsigned short 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 stream->skip(-STREAM_OVERHEAD_SIZE); } } }
//--------------------------------------------------------------------- bool ETCCodec::decodeKTX(DataStreamPtr& stream, DecodeResult& result) const { KTXHeader header; // Read the ETC1 header stream->read(&header, sizeof(KTXHeader)); const uint8 KTXFileIdentifier[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; if (memcmp(KTXFileIdentifier, &header.identifier, sizeof(KTXFileIdentifier)) != 0 ) return false; if (header.endianness == KTX_ENDIAN_REF_REV) flipEndian(&header.glType, sizeof(uint32), 1); ImageData *imgData = OGRE_NEW ImageData(); imgData->depth = 1; imgData->width = header.pixelWidth; imgData->height = header.pixelHeight; imgData->num_mipmaps = static_cast<ushort>(header.numberOfMipmapLevels - 1); switch(header.glInternalFormat) { case 37492: // GL_COMPRESSED_RGB8_ETC2 imgData->format = PF_ETC2_RGB8; break; case 37496:// GL_COMPRESSED_RGBA8_ETC2_EAC imgData->format = PF_ETC2_RGBA8; break; case 37494: // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 imgData->format = PF_ETC2_RGB8A1; break; case 35986: // ATC_RGB imgData->format = PF_ATC_RGB; break; case 35987: // ATC_RGB_Explicit imgData->format = PF_ATC_RGBA_EXPLICIT_ALPHA; break; case 34798: // ATC_RGB_Interpolated imgData->format = PF_ATC_RGBA_INTERPOLATED_ALPHA; break; case 33777: // DXT 1 imgData->format = PF_DXT1; break; case 33778: // DXT 3 imgData->format = PF_DXT3; break; case 33779: // DXT 5 imgData->format = PF_DXT5; break; default: imgData->format = PF_ETC1_RGB8; break; } imgData->flags = 0; if (header.glType == 0 || header.glFormat == 0) imgData->flags |= IF_COMPRESSED; size_t numFaces = 1; // Assume one face until we know otherwise // Calculate total size from number of mipmaps, faces and size imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, imgData->width, imgData->height, imgData->depth, imgData->format); stream->skip(header.bytesOfKeyValueData); // Bind output buffer MemoryDataStreamPtr output; output.bind(OGRE_NEW MemoryDataStream(imgData->size)); // Now deal with the data uchar* destPtr = output->getPtr(); for (uint32 level = 0; level < header.numberOfMipmapLevels; ++level) { uint32 imageSize = 0; stream->read(&imageSize, sizeof(uint32)); stream->read(destPtr, imageSize); destPtr += imageSize; } result.first = output; result.second = CodecDataPtr(imgData); return true; }