void CModelConverter::ReadDAESceneTree(FCDSceneNode* pNode, CConversionSceneNode* pScene) { size_t iTransforms = pNode->GetTransformCount(); Matrix4x4 mTransformations; for (size_t t = 0; t < iTransforms; t++) { FCDTransform* pTransform = pNode->GetTransform(t); FMMatrix44 m = pTransform->ToMatrix(); mTransformations *= Matrix4x4(m); } pScene->SetTransformations(mTransformations); size_t iInstances = pNode->GetInstanceCount(); for (size_t i = 0; i < iInstances; i++) { FCDEntityInstance* pInstance = pNode->GetInstance(i); switch (pInstance->GetType()) { case FCDEntityInstance::GEOMETRY: { FCDGeometryInstance* pGeometryInstance = dynamic_cast<FCDGeometryInstance*>(pInstance); FCDEntity* pEntity = pGeometryInstance->GetEntity(); size_t iMesh = pScene->m_pScene->FindMesh(convert_from_fstring(pEntity->GetName())); size_t iMeshInstance = pScene->AddMeshInstance(iMesh); size_t iMaterialInstances = pGeometryInstance->GetMaterialInstanceCount(); for (size_t m = 0; m < iMaterialInstances; m++) { FCDMaterialInstance* pMaterialInstance = pGeometryInstance->GetMaterialInstance(m); FCDMaterial* pMaterial = pMaterialInstance->GetMaterial(); tstring sMaterial = pMaterial?convert_from_fstring(pMaterialInstance->GetMaterial()->GetName()):""; tstring sMaterialStub = convert_from_fstring(pMaterialInstance->GetSemantic()); size_t iMaterial = pScene->m_pScene->FindMaterial(sMaterial); size_t iMaterialStub = pScene->m_pScene->GetMesh(iMesh)->FindMaterialStub(sMaterialStub); pScene->GetMeshInstance(iMeshInstance)->AddMappedMaterial(iMaterialStub, iMaterial); } } } } size_t iChildren = pNode->GetChildrenCount(); for (size_t j = 0; j < iChildren; j++) { FCDSceneNode* pChildNode = pNode->GetChild(j); size_t iNode = pScene->AddChild(convert_from_fstring(pChildNode->GetName())); ReadDAESceneTree(pChildNode, pScene->GetChild(iNode)); } }
bool FArchiveXML::LoadEntityInstance(FCDObject* object, xmlNode* instanceNode) { FCDEntityInstance* entityInstance = (FCDEntityInstance*)object; bool status = true; FUUri uri = ReadNodeUrl(instanceNode); entityInstance->GetEntityReference()->SetUri(uri); if (!entityInstance->IsExternalReference() && entityInstance->GetEntity() == NULL) { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_INST_ENTITY_MISSING, instanceNode->line); } entityInstance->SetWantedSubId(TO_STRING(ReadNodeSid(instanceNode))); entityInstance->SetName(TO_FSTRING(ReadNodeName(instanceNode))); // Read in the extra nodes xmlNodeList extraNodes; FindChildrenByType(instanceNode, DAE_EXTRA_ELEMENT, extraNodes); for (xmlNodeList::iterator it = extraNodes.begin(); it != extraNodes.end(); ++it) { xmlNode* extraNode = (*it); FArchiveXML::LoadExtra(entityInstance->GetExtra(), extraNode); } entityInstance->SetDirtyFlag(); return status; }
bool FArchiveXML::LoadAnimationClip(FCDObject* object, xmlNode* clipNode) { FCDAnimationClip* animationClip = (FCDAnimationClip*)object; bool status = FArchiveXML::LoadEntity(animationClip, clipNode); if (!status) return status; if (!IsEquivalent(clipNode->name, DAE_ANIMCLIP_ELEMENT)) { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_UNKNOWN_ANIM_LIB_ELEMENT, clipNode->line); return status; } // Read in and verify the clip's time/input bounds animationClip->SetStart(FUStringConversion::ToFloat(ReadNodeProperty(clipNode, DAE_START_ATTRIBUTE))); animationClip->SetEnd(FUStringConversion::ToFloat(ReadNodeProperty(clipNode, DAE_END_ATTRIBUTE))); if (animationClip->GetEnd() - animationClip->GetStart() < FLT_TOLERANCE) { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_INVALID_SE_PAIR, clipNode->line); } // Read in the <input> elements and segment the corresponding animation curves xmlNodeList inputNodes; FindChildrenByType(clipNode, DAE_INSTANCE_ANIMATION_ELEMENT, inputNodes); for (xmlNodeList::iterator itI = inputNodes.begin(); itI != inputNodes.end(); ++itI) { FCDEntityInstance* animationInstance = animationClip->AddInstanceAnimation(); if (!LoadSwitch(animationInstance, &animationInstance->GetObjectType(), *itI)) { SAFE_DELETE(animationInstance); continue; } fm::string name = ReadNodeProperty(*itI, DAE_NAME_ATTRIBUTE); animationClip->SetAnimationName(name, animationClip->GetAnimationCount() - 1); } // Check for an empty clip if (animationClip->GetClipCurves().empty()) { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_EMPTY_ANIM_CLIP, clipNode->line); } animationClip->SetDirtyFlag(); return status; }
void ColladaScene::ExportScene(FCDSceneNode * fcdNode /* = 0 */, ColladaSceneNode * node /* = 0 */) { exportSceneLevel++; if (fcdNode == 0)fcdNode = rootFCDNode; if (node == 0)node = rootNode; node->UpdateTransforms(0); for (int i = 0; i < (int)fcdNode->GetInstanceCount(); ++i) { FCDEntityInstance* instance = fcdNode->GetInstance(i); FCDEntity * entity = instance->GetEntity(); if (!entity) continue; fm::string name = entity->GetDaeId(); for (int space = 0; space < exportSceneLevel; ++space) printf(" "); printf(" - instance: %s\n", name.c_str()); ColladaMesh * mesh = FindMeshWithName(name); if (mesh) { ColladaMeshInstance * meshInstance = CreateMeshInstance(mesh, dynamic_cast<FCDGeometryInstance*>(instance), false); //for (int space = 0; space < exportSceneLevel; ++space) // printf(" "); //printf(" - mesh: %s\n", name.c_str()); node->AddMeshInstance(meshInstance); } ColladaLight * light = FindLightWithName(name); if (light) { //for (int space = 0; space < exportSceneLevel; ++space) // printf(" "); //printf(" - light: %s\n", name.c_str()); node->AddLight(light); } ColladaAnimatedMesh * aMesh = FindAnimatedMeshWithName(name); if (aMesh) { FCDControllerInstance * controllerInstance = dynamic_cast<FCDControllerInstance*>(instance); //for (int space = 0; space < exportSceneLevel; ++space) // printf(" "); //printf("- controller instance: %s\n", name.c_str()); if (aMesh->mesh) { ColladaMeshInstance * meshInstance = CreateMeshInstance(aMesh->mesh, dynamic_cast<FCDGeometryInstance*>(instance), true); node->AddMeshInstance(meshInstance); } } ColladaCamera * aCam = FindCameraWithName(name); if (aCam) { node->AddCamera(aCam); } } for (int i = 0; i < (int)fcdNode->GetChildrenCount(); i++) { FCDSceneNode * fcdChildNode = fcdNode->GetChild(i); ColladaSceneNode * childNode = new ColladaSceneNode(this, fcdChildNode); ExportScene(fcdChildNode, childNode); node->AddNode(childNode); } exportSceneLevel--; }
bool FArchiveXML::LoadPhysicsRigidBodyParameters(FCDPhysicsRigidBodyParameters* parameters, xmlNode* techniqueNode, FCDPhysicsRigidBodyParameters* defaultParameters) { bool status = true; xmlNode* param = FindChildByType(techniqueNode, DAE_DYNAMIC_ELEMENT); if (param) { parameters->SetDynamic(FUStringConversion::ToBoolean(ReadNodeContentDirect(param))); FArchiveXML::LoadAnimatable(¶meters->GetDynamic(), param); } else if (defaultParameters != NULL) { parameters->SetDynamic(defaultParameters->GetDynamic() > 0.5f); if (defaultParameters->GetDynamic().IsAnimated()) { defaultParameters->GetDynamic().GetAnimated()->Clone(parameters->GetDynamic().GetAnimated()); } } xmlNode* massFrame; massFrame = FindChildByType(techniqueNode, DAE_MASS_FRAME_ELEMENT); if (massFrame) { param = FindChildByType(massFrame, DAE_TRANSLATE_ELEMENT); if (param) { parameters->SetMassFrameTranslate(FUStringConversion::ToVector3(ReadNodeContentDirect(param))); FArchiveXML::LoadAnimatable(¶meters->GetMassFrameTranslate(), param); } else if (defaultParameters != NULL) { parameters->SetMassFrameTranslate(defaultParameters->GetMassFrameTranslate()); if (defaultParameters->GetMassFrameTranslate().IsAnimated()) { defaultParameters->GetMassFrameTranslate().GetAnimated()->Clone(parameters->GetMassFrameTranslate().GetAnimated()); } } else { // no movement parameters->SetMassFrameTranslate(FMVector3::Zero); } param = FindChildByType(massFrame, DAE_ROTATE_ELEMENT); if (param) { FMVector4 temp = FUStringConversion::ToVector4(ReadNodeContentDirect(param)); parameters->SetMassFrameOrientation(FMAngleAxis(FMVector3(temp.x, temp.y, temp.z), temp.w)); LoadAnimatable(¶meters->GetMassFrameOrientation(), param); } else if (defaultParameters != NULL) { parameters->SetMassFrameOrientation(defaultParameters->GetMassFrameOrientation()); if (defaultParameters->GetMassFrameOrientation().IsAnimated()) { defaultParameters->GetMassFrameOrientation().GetAnimated()->Clone(parameters->GetMassFrameOrientation().GetAnimated()); } } else { // no movement parameters->SetMassFrameOrientation(FMAngleAxis(FMVector3::XAxis, 0.0f)); } } else if (defaultParameters != NULL) { parameters->SetMassFrameTranslate(defaultParameters->GetMassFrameTranslate()); parameters->SetMassFrameOrientation(defaultParameters->GetMassFrameOrientation()); if (defaultParameters->GetMassFrameTranslate().IsAnimated()) { defaultParameters->GetMassFrameTranslate().GetAnimated()->Clone(parameters->GetMassFrameTranslate().GetAnimated()); } if (defaultParameters->GetMassFrameOrientation().IsAnimated()) { defaultParameters->GetMassFrameOrientation().GetAnimated()->Clone(parameters->GetMassFrameOrientation().GetAnimated()); } } else { // no movement parameters->SetMassFrameTranslate(FMVector3::Zero); parameters->SetMassFrameOrientation(FMAngleAxis(FMVector3::XAxis, 0.0f)); } xmlNodeList shapeNodes; FindChildrenByType(techniqueNode, DAE_SHAPE_ELEMENT, shapeNodes); if (shapeNodes.empty()) { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_SHAPE_NODE_MISSING, techniqueNode->line); } for (xmlNodeList::iterator itS = shapeNodes.begin(); itS != shapeNodes.end(); ++itS) { FCDPhysicsShape* shape = parameters->AddPhysicsShape(); status &= (FArchiveXML::LoadPhysicsShape(shape, *itS)); } // shapes are not taken from the default parameters param = FindChildByType(techniqueNode, DAE_PHYSICS_MATERIAL_ELEMENT); if (param != NULL) { FCDPhysicsMaterial* material = parameters->AddOwnPhysicsMaterial(); FArchiveXML::LoadPhysicsMaterial(material, param); } else { param = FindChildByType(techniqueNode, DAE_INSTANCE_PHYSICS_MATERIAL_ELEMENT); if (param != NULL) { FCDEntityInstance* physicsMaterialInstance = FCDEntityInstanceFactory::CreateInstance(parameters->GetDocument(), NULL, FCDEntity::PHYSICS_MATERIAL); parameters->SetInstanceMaterial(physicsMaterialInstance); FArchiveXML::LoadSwitch(physicsMaterialInstance, &physicsMaterialInstance->GetObjectType(), param); FCDPhysicsMaterial* material = (FCDPhysicsMaterial*) physicsMaterialInstance->GetEntity(); if (material == NULL) { FUError::Error(FUError::ERROR_LEVEL, FUError::WARNING_MISSING_URI_TARGET, param->line); } parameters->SetPhysicsMaterial(material); } else { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_PHYS_MAT_DEF_MISSING, techniqueNode->line); } } // material is not taken fromt he default parameters param = FindChildByType(techniqueNode, DAE_MASS_ELEMENT); if (param) { parameters->SetMass(FUStringConversion::ToFloat(ReadNodeContentDirect(param))); parameters->SetDensityMoreAccurate(false); parameters->SetDensity(0.0f); FArchiveXML::LoadAnimatable(¶meters->GetMass(), param); } else if (defaultParameters != NULL) { parameters->SetMass(defaultParameters->GetMass()); parameters->SetDensity(defaultParameters->GetDensity()); parameters->SetDensityMoreAccurate(defaultParameters->IsDensityMoreAccurate()); if (defaultParameters->GetMass().IsAnimated()) { defaultParameters->GetMass().GetAnimated()->Clone(parameters->GetMass().GetAnimated()); } } else { /* Default value for mass is density x total shape volume, but since our shape's mass is already calculated with respect to the volume, we can just read it from there. If the user specified a mass, then this overrides the calculation of density x volume, as expected. */ parameters->SetMass(0.0f); float totalDensity = 0.0f; parameters->SetDensityMoreAccurate(false); for (size_t i = 0; i < parameters->GetPhysicsShapeCount(); ++i) { FCDPhysicsShape* shape = parameters->GetPhysicsShape(i); parameters->SetMass(parameters->GetMass() + shape->GetMass()); totalDensity += shape->GetDensity(); parameters->SetDensityMoreAccurate(parameters->IsDensityMoreAccurate() || shape->IsDensityMoreAccurate()); // common case: 1 shape, density = 1.0f } parameters->SetDensity(totalDensity / parameters->GetPhysicsShapeCount()); } param = FindChildByType(techniqueNode, DAE_INERTIA_ELEMENT); if (param) { parameters->SetInertia(FUStringConversion::ToVector3(ReadNodeContentDirect(param))); parameters->SetInertiaAccurate(true); FArchiveXML::LoadAnimatable(¶meters->GetInertia(), param); } else if (defaultParameters != NULL) { parameters->SetInertia(defaultParameters->GetInertia()); parameters->SetInertiaAccurate(defaultParameters->IsInertiaAccurate()); if (defaultParameters->GetInertia().IsAnimated()) { defaultParameters->GetInertia().GetAnimated()->Clone(parameters->GetInertia().GetAnimated()); } } else { /* FIXME: Approximation: sphere shape, with mass distributed equally across the volume and center of mass is at the center of the sphere. Real moments of inertia call for complex integration. Sphere it is simply I = k * m * r^2 on all axes. */ float volume = 0.0f; for (size_t i = 0; i < parameters->GetPhysicsShapeCount(); ++i) { volume += parameters->GetPhysicsShape(i)->CalculateVolume(); } float radiusCubed = 0.75f * volume / (float)FMath::Pi; float I = 0.4f * parameters->GetMass() * pow(radiusCubed, 2.0f / 3.0f); parameters->SetInertia(FMVector3(I, I, I)); parameters->SetInertiaAccurate(false); } return status; }
bool FArchiveXML::LoadFromExtraSceneNode(FCDSceneNode* sceneNode) { bool status = true; FCDENodeList parameterNodes; StringList parameterNames; // Retrieve the extra information from the base entity class FCDExtra* extra = sceneNode->GetExtra(); // List all the parameters size_t techniqueCount = extra->GetDefaultType()->GetTechniqueCount(); for (size_t i = 0; i < techniqueCount; ++i) { FCDETechnique* technique = extra->GetDefaultType()->GetTechnique(i); technique->FindParameters(parameterNodes, parameterNames); } // Process the known parameters size_t parameterCount = parameterNodes.size(); for (size_t i = 0; i < parameterCount; ++i) { FCDENode* parameterNode = parameterNodes[i]; const fm::string& parameterName = parameterNames[i]; FCDEAttribute* parameterType = parameterNode->FindAttribute(DAE_TYPE_ATTRIBUTE); if (parameterName == DAEMAYA_STARTTIME_PARAMETER) { sceneNode->GetDocument()->SetStartTime(FUStringConversion::ToFloat(parameterNode->GetContent())); } else if (parameterName == DAEMAYA_ENDTIME_PARAMETER) { sceneNode->GetDocument()->SetEndTime(FUStringConversion::ToFloat(parameterNode->GetContent())); } else if (parameterName == DAEFC_VISIBILITY_PARAMETER) { sceneNode->SetVisibility(FUStringConversion::ToBoolean(parameterNode->GetContent())); if (parameterNode->GetAnimated()->HasCurve()) { parameterNode->GetAnimated()->Clone(sceneNode->GetVisibility().GetAnimated()); } } else if (parameterName == DAEMAYA_LAYER_PARAMETER || (parameterType != NULL && FUStringConversion::ToString(parameterType->GetValue()) == DAEMAYA_LAYER_PARAMETER)) { FCDEAttribute* nameAttribute = parameterNode->FindAttribute(DAE_NAME_ATTRIBUTE); if (nameAttribute == NULL) continue; // Create a new layer object list FCDLayerList& layers = sceneNode->GetDocument()->GetLayers(); FCDLayer* layer = new FCDLayer(); layers.push_back(layer); // Parse in the layer layer->name = FUStringConversion::ToString(nameAttribute->GetValue()); FUStringConversion::ToStringList(parameterNode->GetContent(), layer->objects); } else continue; SAFE_RELEASE(parameterNode); } // Read in the extra instances from the typed extra. FCDEType* instancesExtra = extra->FindType(DAEFC_INSTANCES_TYPE); if (instancesExtra != NULL) { FCDETechnique* fcolladaTechnique = instancesExtra->FindTechnique(DAE_FCOLLADA_PROFILE); if (fcolladaTechnique != NULL) { FCDENodeList nodesToRelease; size_t childNodeCount = fcolladaTechnique->GetChildNodeCount(); for (size_t c = 0; c < childNodeCount; ++c) { FCDENode* node = fcolladaTechnique->GetChildNode(c); xmlNode* baseNode = FUXmlWriter::CreateNode("_temp_"); xmlNode* instanceNode = FArchiveXML::LetWriteObject(node, baseNode); uint32 instanceType = FArchiveXML::GetEntityInstanceType(instanceNode); if (instanceType == (uint32) ~0) { status = false; } else { FCDEntityInstance* instance = sceneNode->AddInstance((FCDEntity::Type) instanceType); status &= (FArchiveXML::LoadSwitch(instance, &instance->GetObjectType(), instanceNode)); nodesToRelease.push_back(node); } xmlFreeNodeList(baseNode); } CLEAR_POINTER_VECTOR(nodesToRelease); } } sceneNode->SetDirtyFlag(); return status; }
bool FArchiveXML::LoadSceneNode(FCDObject* object, xmlNode* node) { if (!FArchiveXML::LoadEntity(object, node)) return false; bool status = true; FCDSceneNode* sceneNode = (FCDSceneNode*)object; if (!IsEquivalent(node->name, DAE_VSCENE_ELEMENT) && !IsEquivalent(node->name, DAE_NODE_ELEMENT)) { FUError::Error(FUError::ERROR_LEVEL, FUError::ERROR_UNKNOWN_ELEMENT, node->line); } // Read a subid if we gots one fm::string nodeSubId = ReadNodeProperty(node, DAE_SID_ATTRIBUTE); sceneNode->SetSubId(nodeSubId); // Read in the <node> element's type fm::string nodeType = ReadNodeProperty(node, DAE_TYPE_ATTRIBUTE); if (nodeType == DAE_JOINT_NODE_TYPE) sceneNode->SetJointFlag(true); else if (nodeType.length() == 0 || nodeType == DAE_NODE_NODE_TYPE) {} // No special consideration else { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_UNKNOW_NODE_ELEMENT_TYPE, node->line); } // The scene node has ordered elements, so process them directly and in order. for (xmlNode* child = node->children; child != NULL; child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; if (IsEquivalent(child->name, DAE_NODE_ELEMENT)) { // Load the child scene node FCDSceneNode* node = sceneNode->AddChildNode(); status = FArchiveXML::LoadSceneNode(node, child); if (!status) break; } // Although this case can be handled by FCDEntityInstanceFactory, // we can do some special case handling here. else if (IsEquivalent(child->name, DAE_INSTANCE_NODE_ELEMENT)) { FUUri url = ReadNodeUrl(child); if (!url.IsFile()) { // cannot find the node FCDSceneNode* node = sceneNode->GetDocument()->FindSceneNode(TO_STRING(url.GetFragment())); if (node != NULL) { if (!sceneNode->AddChildNode(node)) { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_CYCLE_DETECTED, child->line); } } else { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_INVALID_NODE_INST, child->line); } } else { FCDEntityInstance* reference = sceneNode->AddInstance(FCDEntity::SCENE_NODE); FArchiveXML::LoadEntityInstance(reference, child); } } else if (IsEquivalent(child->name, DAE_EXTRA_ELEMENT)) {} // Handled by FCDEntity. else if (IsEquivalent(child->name, DAE_ASSET_ELEMENT)) {} // Handled by FCDEntity. else { uint32 transformType = FArchiveXML::GetTransformType(child); if (transformType != (uint32) ~0) { FCDTransform* transform = sceneNode->AddTransform((FCDTransform::Type) transformType); fm::string childSubId = ReadNodeProperty(child, DAE_SID_ATTRIBUTE); transform->SetSubId(childSubId); status &= (FArchiveXML::LoadSwitch(transform, &transform->GetObjectType(), child)); } else { uint32 instanceType = FArchiveXML::GetEntityInstanceType(child); if (instanceType != (uint32) ~0) { FCDEntityInstance* instance = sceneNode->AddInstance((FCDEntity::Type) instanceType); status &= (FArchiveXML::LoadSwitch(instance, &instance->GetObjectType(), child)); } else { FUError::Error(FUError::WARNING_LEVEL, FUError::WARNING_INVALID_TRANSFORM, child->line); } } } } status &= FArchiveXML::LoadFromExtraSceneNode(sceneNode); sceneNode->SetTransformsDirtyFlag(); sceneNode->SetDirtyFlag(); return status; }