コード例 #1
0
ファイル: colladaAppNode.cpp プロジェクト: 03050903/Torque3D
ColladaAppNode::ColladaAppNode(const domNode* node, ColladaAppNode* parent)
      : p_domNode(node), appParent(parent), nodeExt(new ColladaExtension_node(node)),
      lastTransformTime(TSShapeLoader::DefaultTime-1), defaultTransformValid(false),
      invertMeshes(false)
{
   mName = dStrdup(_GetNameOrId(node));
   mParentName = dStrdup(parent ? parent->getName() : "ROOT");

   // Extract user properties from the <node> extension as whitespace separated
   // "name=value" pairs
   char* properties = dStrdup(nodeExt->user_properties);
   char* pos = properties;
   char* end = properties + dStrlen( properties );
   while ( pos < end )
   {
      // Find the '=' character to separate the name and value pair
      char* split = dStrchr( pos, '=' );
      if ( !split )
         break;

      // Get the name (whitespace trimmed string up to the '=')
      // and value (whitespace trimmed string after the '=')
      *split = '\0';
      char* name = TrimFirstWord( pos );
      char* value = TrimFirstWord( split + 1 );

      mProps.insert(StringTable->insert(name), dAtof(value));

      pos = value + dStrlen( value ) + 1;
   }

   dFree( properties );

   // Create vector of transform elements
   for (S32 iChild = 0; iChild < node->getContents().getCount(); iChild++) {
      switch (node->getContents()[iChild]->getElementType()) {
         case COLLADA_TYPE::TRANSLATE:
         case COLLADA_TYPE::ROTATE:
         case COLLADA_TYPE::SCALE:
         case COLLADA_TYPE::SKEW:
         case COLLADA_TYPE::MATRIX:
         case COLLADA_TYPE::LOOKAT:
            nodeTransforms.increment();
            nodeTransforms.last().element = node->getContents()[iChild];
            break;
      }
   }
}
コード例 #2
0
void ColladaShapeLoader::enumerateScene()
{
   // Get animation clips
   Vector<const domAnimation_clip*> animationClips;
   for (S32 iClipLib = 0; iClipLib < root->getLibrary_animation_clips_array().getCount(); iClipLib++) {
      const domLibrary_animation_clips* libraryClips = root->getLibrary_animation_clips_array()[iClipLib];
      for (S32 iClip = 0; iClip < libraryClips->getAnimation_clip_array().getCount(); iClip++)
         appSequences.push_back(new ColladaAppSequence(libraryClips->getAnimation_clip_array()[iClip]));
   }

   // Process all animations => this attaches animation channels to the targeted
   // Collada elements, and determines the length of the sequence if it is not
   // already specified in the Collada <animation_clip> element
   for (S32 iSeq = 0; iSeq < appSequences.size(); iSeq++) {
      ColladaAppSequence* appSeq = dynamic_cast<ColladaAppSequence*>(appSequences[iSeq]);
      F32 maxEndTime = 0;
      F32 minFrameTime = 1000.0f;
      for (S32 iAnim = 0; iAnim < appSeq->getClip()->getInstance_animation_array().getCount(); iAnim++) {
         domAnimation* anim = daeSafeCast<domAnimation>(appSeq->getClip()->getInstance_animation_array()[iAnim]->getUrl().getElement());
         if (anim)
            processAnimation(anim, maxEndTime, minFrameTime);
      }
      if (appSeq->getEnd() == 0)
         appSeq->setEnd(maxEndTime);

      // Collada animations can be stored as sampled frames or true keyframes. For
      // sampled frames, use the same frame rate as the DAE file. For true keyframes,
      // resample at a fixed frame rate.
      appSeq->fps = mClamp(1.0f / minFrameTime + 0.5f, TSShapeLoader::MinFrameRate, TSShapeLoader::MaxFrameRate);
   }

   // First grab all of the top-level nodes
   Vector<domNode*> sceneNodes;
   for (S32 iSceneLib = 0; iSceneLib < root->getLibrary_visual_scenes_array().getCount(); iSceneLib++) {
      const domLibrary_visual_scenes* libScenes = root->getLibrary_visual_scenes_array()[iSceneLib];
      for (S32 iScene = 0; iScene < libScenes->getVisual_scene_array().getCount(); iScene++) {
         const domVisual_scene* visualScene = libScenes->getVisual_scene_array()[iScene];
         for (S32 iNode = 0; iNode < visualScene->getNode_array().getCount(); iNode++)
            sceneNodes.push_back(visualScene->getNode_array()[iNode]);
      }
   }

   // Set LOD option
   bool singleDetail = true;
   switch (ColladaUtils::getOptions().lodType)
   {
      case ColladaUtils::ImportOptions::DetectDTS:
         // Check for a baseXX->startXX hierarchy at the top-level, if we find
         // one, use trailing numbers for LOD, otherwise use a single size
         for (S32 iNode = 0; singleDetail && (iNode < sceneNodes.size()); iNode++) {
            domNode* node = sceneNodes[iNode];
            if (dStrStartsWith(_GetNameOrId(node), "base")) {
               for (S32 iChild = 0; iChild < node->getNode_array().getCount(); iChild++) {
                  domNode* child = node->getNode_array()[iChild];
                  if (dStrStartsWith(_GetNameOrId(child), "start")) {
                     singleDetail = false;
                     break;
                  }
               }
            }
         }
         break;

      case ColladaUtils::ImportOptions::SingleSize:
         singleDetail = true;
         break;

      case ColladaUtils::ImportOptions::TrailingNumber:
         singleDetail = false;
         break;
         
      default:
         break;
   }

   ColladaAppMesh::fixDetailSize( singleDetail, ColladaUtils::getOptions().singleDetailSize );

   // Process the top level nodes
   for (S32 iNode = 0; iNode < sceneNodes.size(); iNode++) {
      ColladaAppNode* node = new ColladaAppNode(sceneNodes[iNode], 0);
      if (!processNode(node))
         delete node;
   }

   // Make sure that the scene has a bounds node (for getting the root scene transform)
   if (!boundsNode)
   {
      domVisual_scene* visualScene = root->getLibrary_visual_scenes_array()[0]->getVisual_scene_array()[0];
      domNode* dombounds = daeSafeCast<domNode>( visualScene->createAndPlace( "node" ) );
      dombounds->setName( "bounds" );
      ColladaAppNode *appBounds = new ColladaAppNode(dombounds, 0);
      if (!processNode(appBounds))
         delete appBounds;
   }
}
コード例 #3
0
ファイル: colladaLights.cpp プロジェクト: jamesu/libDTShape
//-----------------------------------------------------------------------------
// Recurse through the collada scene to add <light>s to the Torque scene
static void processNodeLights(AppNode* appNode, const MatrixF& offset, SimGroup* group)
{
   const domNode* node = dynamic_cast<ColladaAppNode*>(appNode)->getDomNode();

   for (S32 iLight = 0; iLight < node->getInstance_light_array().getCount(); iLight++) {

      domInstance_light* instLight = node->getInstance_light_array()[iLight];
      domLight* p_domLight = daeSafeCast<domLight>(instLight->getUrl().getElement());
      if (!p_domLight) {
         Log::warnf("Failed to find light for URL \"%s\"", instLight->getUrl().getOriginalURI());
         continue;
      }

      String lightName = Sim::getUniqueName(_GetNameOrId(node));
      const char* lightType = "";

      domLight::domTechnique_common* technique = p_domLight->getTechnique_common();
      if (!technique) {
         Log::warnf("No <technique_common> for light \"%s\"", lightName.c_str());
         continue;
      }

      LightBase* pLight = 0;
      ColorF color(ColorF::WHITE);
      Point3F attenuation(0, 1, 1);

      if (technique->getAmbient()) {
         domLight::domTechnique_common::domAmbient* ambient = technique->getAmbient();
         // No explicit support for ambient lights, so use a PointLight instead
         lightType = "ambient";
         pLight = new PointLight;
         resolveLightColor(ambient, color);
      }
      else if (technique->getDirectional()) {
         domLight::domTechnique_common::domDirectional* directional = technique->getDirectional();
         // No explicit support for directional lights, so use a SpotLight instead
         lightType = "directional";
         pLight = new SpotLight;
         resolveLightColor(directional, color);
      }
      else if (technique->getPoint()) {
         domLight::domTechnique_common::domPoint* point = technique->getPoint();
         lightType = "point";
         pLight = new PointLight;
         resolveLightColor(point, color);
         resolveLightAttenuation(point, attenuation);
      }
      else if (technique->getSpot()) {
         domLight::domTechnique_common::domSpot* spot = technique->getSpot();
         lightType = "spot";
         pLight = new SpotLight;
         resolveLightColor(spot, color);
         resolveLightAttenuation(spot, attenuation);
      }
      else
         continue;

      Log::printf("Adding <%s> light \"%s\" as a %s", lightType, lightName.c_str(), pLight->getClassName());

      MatrixF mat(offset);
      mat.mul(appNode->getNodeTransform(TSShapeLoader::DefaultTime));

      pLight->setDataField("color", 0,
         avar("%f %f %f %f", color.red, color.green, color.blue, color.alpha));
      pLight->setDataField("attenuationRatio", 0,
         avar("%f %f %f", attenuation.x, attenuation.y, attenuation.z));
      pLight->setTransform(mat);

      if (!pLight->registerObject(lightName)) {
         Log::errorf(LogEntry::General, "Failed to register light for \"%s\"", lightName.c_str());
         delete pLight;
      }

      if (group)
         group->addObject(pLight);
   }

   // Recurse child nodes
   for (S32 iChild = 0; iChild < appNode->getNumChildNodes(); iChild++)
      processNodeLights(appNode->getChildNode(iChild), offset, group);
}
コード例 #4
0
// Recurse through the <visual_scene> adding nodes and geometry to the GuiTreeView control
static void processNode(GuiTreeViewCtrl* tree, domNode* node, S32 parentID, SceneStats& stats)
{
   stats.numNodes++;
   S32 nodeID = tree->insertItem(parentID, _GetNameOrId(node), "node", "", 0, 0);

   // Update mesh and poly counts
   for (int i = 0; i < node->getContents().getCount(); i++)
   {
      domGeometry* geom = 0;
      const char* elemName = "";

      daeElement* child = node->getContents()[i];
      switch (child->getElementType())
      {
         case COLLADA_TYPE::INSTANCE_GEOMETRY:
         {
            domInstance_geometry* instgeom = daeSafeCast<domInstance_geometry>(child);
            if (instgeom)
            {
               geom = daeSafeCast<domGeometry>(instgeom->getUrl().getElement());
               elemName = _GetNameOrId(geom);
            }
            break;
         }

         case COLLADA_TYPE::INSTANCE_CONTROLLER:
         {
            domInstance_controller* instctrl = daeSafeCast<domInstance_controller>(child);
            if (instctrl)
            {
               domController* ctrl = daeSafeCast<domController>(instctrl->getUrl().getElement());
               elemName = _GetNameOrId(ctrl);
               if (ctrl && ctrl->getSkin())
                  geom = daeSafeCast<domGeometry>(ctrl->getSkin()->getSource().getElement());
               else if (ctrl && ctrl->getMorph())
                  geom = daeSafeCast<domGeometry>(ctrl->getMorph()->getSource().getElement());
            }
            break;
         }

         case COLLADA_TYPE::INSTANCE_LIGHT:
            stats.numLights++;
            tree->insertItem(nodeID, _GetNameOrId(node), "light", "", 0, 0);
            break;
      }

      if (geom && geom->getMesh())
      {
         const char* name = _GetNameOrId(node);
         if ( dStrEqual( name, "null" ) || dStrEndsWith( name, "PIVOT" ) )
            name = _GetNameOrId( daeSafeCast<domNode>(node->getParent()) );

         stats.numMeshes++;
         tree->insertItem(nodeID, name, "mesh", "", 0, 0);

         for (S32 j = 0; j < geom->getMesh()->getTriangles_array().getCount(); j++)
            stats.numPolygons += geom->getMesh()->getTriangles_array()[j]->getCount();
         for (S32 j = 0; j < geom->getMesh()->getTristrips_array().getCount(); j++)
            stats.numPolygons += geom->getMesh()->getTristrips_array()[j]->getCount();
         for (S32 j = 0; j < geom->getMesh()->getTrifans_array().getCount(); j++)
            stats.numPolygons += geom->getMesh()->getTrifans_array()[j]->getCount();
         for (S32 j = 0; j < geom->getMesh()->getPolygons_array().getCount(); j++)
            stats.numPolygons += geom->getMesh()->getPolygons_array()[j]->getCount();
         for (S32 j = 0; j < geom->getMesh()->getPolylist_array().getCount(); j++)
            stats.numPolygons += geom->getMesh()->getPolylist_array()[j]->getCount();
      }
   }

   // Recurse into child nodes
   for (S32 i = 0; i < node->getNode_array().getCount(); i++)
      processNode(tree, node->getNode_array()[i], nodeID, stats);

   for (S32 i = 0; i < node->getInstance_node_array().getCount(); i++)
   {
      domInstance_node* instnode = node->getInstance_node_array()[i];
      domNode* node = daeSafeCast<domNode>(instnode->getUrl().getElement());
      if (node)
         processNode(tree, node, nodeID, stats);
   }
}