void Model_KotOR::readAnim(ParserContext &ctx, uint32 offset) { ctx.mdl->seek(offset); ctx.mdl->skip(8); // Function pointers ctx.state->name = Common::readStringFixed(*ctx.mdl, Common::kEncodingASCII, 32); uint32 nodeHeadPointer = ctx.mdl->readUint32LE(); uint32 nodeCount = ctx.mdl->readUint32LE(); ctx.mdl->skip(24 + 4); // Unknown + Reference count uint8 type = ctx.mdl->readByte(); ctx.mdl->skip(3); // Padding + Unknown float animLength = ctx.mdl->readIEEEFloatLE(); float transTime = ctx.mdl->readIEEEFloatLE(); const Common::UString animRoot = Common::readStringFixed(*ctx.mdl, Common::kEncodingASCII, 32); uint32 eventOffset, eventCount; readArrayDef(*ctx.mdl, eventOffset, eventCount); ctx.mdl->skip(4); // Padding + Unknown ModelNode_KotOR *rootNode = new ModelNode_KotOR(*this); ctx.nodes.push_back(rootNode); ctx.mdl->seek(ctx.offModelData + nodeHeadPointer); rootNode->load(ctx); Animation *anim = new Animation(); anim->setName(ctx.state->name); anim->setLength(animLength); anim->setTransTime(transTime); _animationMap.insert(std::make_pair(ctx.state->name, anim)); for (std::list<ModelNode_KotOR *>::iterator n = ctx.nodes.begin(); n != ctx.nodes.end(); ++n) { AnimNode *animnode = new AnimNode(*n); anim->addAnimNode(animnode); } }
void ModelNode_KotOR::load(Model_KotOR::ParserContext &ctx) { uint16 flags = ctx.mdl->readUint16LE(); uint16 superNode = ctx.mdl->readUint16LE(); uint16 nodeNumber = ctx.mdl->readUint16LE(); if (nodeNumber < ctx.names.size()) _name = ctx.names[nodeNumber]; ctx.mdl->skip(6 + 4); // Unknown + parent pointer _position [0] = ctx.mdl->readIEEEFloatLE(); _position [1] = ctx.mdl->readIEEEFloatLE(); _position [2] = ctx.mdl->readIEEEFloatLE(); _orientation[3] = Common::rad2deg(acos(ctx.mdl->readIEEEFloatLE()) * 2.0); _orientation[0] = ctx.mdl->readIEEEFloatLE(); _orientation[1] = ctx.mdl->readIEEEFloatLE(); _orientation[2] = ctx.mdl->readIEEEFloatLE(); uint32 childrenOffset, childrenCount; Model::readArrayDef(*ctx.mdl, childrenOffset, childrenCount); std::vector<uint32> children; Model::readArray(*ctx.mdl, ctx.offModelData + childrenOffset, childrenCount, children); uint32 controllerKeyOffset, controllerKeyCount; Model::readArrayDef(*ctx.mdl, controllerKeyOffset, controllerKeyCount); uint32 controllerDataOffset, controllerDataCount; Model::readArrayDef(*ctx.mdl, controllerDataOffset, controllerDataCount); std::vector<float> controllerData; Model::readArray(*ctx.mdl, ctx.offModelData + controllerDataOffset, controllerDataCount, controllerData); readNodeControllers(ctx, ctx.offModelData + controllerKeyOffset, controllerKeyCount, controllerData); if ((flags & 0xFC00) != 0) throw Common::Exception("Unknown node flags %04X", flags); if (flags & kNodeFlagHasLight) { // TODO: Light ctx.mdl->skip(0x5C); } if (flags & kNodeFlagHasEmitter) { // TODO: Emitter ctx.mdl->skip(0xD8); } if (flags & kNodeFlagHasReference) { // TODO: Reference ctx.mdl->skip(0x44); } if (flags & kNodeFlagHasMesh) { readMesh(ctx); } if (flags & kNodeFlagHasSkin) { // TODO: Skin ctx.mdl->skip(0x64); } if (flags & kNodeFlagHasAnim) { // TODO: Anim ctx.mdl->skip(0x38); } if (flags & kNodeFlagHasDangly) { // TODO: Dangly ctx.mdl->skip(0x18); } if (flags & kNodeFlagHasAABB) { // TODO: AABB ctx.mdl->skip(0x4); } for (std::vector<uint32>::const_iterator child = children.begin(); child != children.end(); ++child) { ModelNode_KotOR *childNode = new ModelNode_KotOR(*_model); ctx.nodes.push_back(childNode); childNode->setParent(this); ctx.mdl->seek(ctx.offModelData + *child); childNode->load(ctx); } }
void Model_KotOR::load(ParserContext &ctx) { if (ctx.mdl->readUint32LE() != 0) throw Common::Exception("Unsupported KotOR ASCII MDL"); uint32 sizeModelData = ctx.mdl->readUint32LE(); uint32 sizeRawData = ctx.mdl->readUint32LE(); ctx.offModelData = 12; ctx.offRawData = ctx.offModelData + sizeModelData; ctx.mdl->skip(8); // Function pointers _name = Common::readStringFixed(*ctx.mdl, Common::kEncodingASCII, 32); uint32 nodeHeadPointer = ctx.mdl->readUint32LE(); uint32 nodeCount = ctx.mdl->readUint32LE(); ctx.mdl->skip(24 + 4); // Unknown + Reference count uint8 type = ctx.mdl->readByte(); ctx.mdl->skip(3 + 2); // Padding + Unknown uint8 classification = ctx.mdl->readByte(); uint8 fogged = ctx.mdl->readByte(); ctx.mdl->skip(4); // Unknown ctx.mdl->skip(12); // TODO: Animation Header Pointer Array ctx.mdl->skip(4); // Parent model pointer float boundingMin[3], boundingMax[3]; boundingMin[0] = ctx.mdl->readIEEEFloatLE(); boundingMin[1] = ctx.mdl->readIEEEFloatLE(); boundingMin[2] = ctx.mdl->readIEEEFloatLE(); boundingMax[0] = ctx.mdl->readIEEEFloatLE(); boundingMax[1] = ctx.mdl->readIEEEFloatLE(); boundingMax[2] = ctx.mdl->readIEEEFloatLE(); float radius = ctx.mdl->readIEEEFloatLE(); float scale = ctx.mdl->readIEEEFloatLE(); Common::UString superModelName = Common::readStringFixed(*ctx.mdl, Common::kEncodingASCII, 32); ctx.mdl->skip(4); // Root node pointer again ctx.mdl->skip(12); // Unknown uint32 nameOffset, nameCount; readArrayDef(*ctx.mdl, nameOffset, nameCount); std::vector<uint32> nameOffsets; readArray(*ctx.mdl, ctx.offModelData + nameOffset, nameCount, nameOffsets); readStrings(*ctx.mdl, nameOffsets, ctx.offModelData, ctx.names); newState(ctx); ModelNode_KotOR *rootNode = new ModelNode_KotOR(*this); ctx.nodes.push_back(rootNode); ctx.mdl->seek(ctx.offModelData + nodeHeadPointer); rootNode->load(ctx); addState(ctx); }