Torque3D Documentation / _generateds / colladaLights.cpp

colladaLights.cpp

Engine/source/ts/collada/colladaLights.cpp

More...

Public Functions

DefineEngineFunction(loadColladaLights , bool , (const char *filename, const char *parentGroup, const char *baseObject) , ("", "") , "(string filename, <a href="/coding/class/classsimgroup/">SimGroup</a> parentGroup=<a href="/coding/class/classscene/">Scene</a>, <a href="/coding/class/classsimobject/">SimObject</a> baseObject=-1)" "Load all light instances from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> COLLADA (.dae) <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> and add <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n</a>" "@param filename COLLADA filename <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> load lights <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from\n</a>" "@param parentGroup (optional) name of an existing simgroup <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> " "lights <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> (defaults <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> root <a href="/coding/class/classscene/">Scene</a>)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param baseObject (optional) name of an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use as the origin (useful " "<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> you are loading the lights <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> collada scene and have moved or rotated " "the geometry)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@return true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">otherwise\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//load the lights in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">room.dae\n</a>" "loadColladaLights(\"art/shapes/collada/room.dae\" );\n\n" "// load the lights in room.dae and add them <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the RoomLights <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">group\n</a>" "loadColladaLights( \"art/shapes/collada/room.dae\", \"RoomLights\" );\n\n" "// load the lights in room.dae and use the transform of the \"Room\"\n" "object as the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">origin\n</a>" "loadColladaLights( \"art/shapes/collada/room.dae\", \"\", \"Room\" );\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@note Currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" "@internal" )
processNodeLights(AppNode * appNode, const MatrixF & offset, SimGroup * group)
resolveLightAttenuation(T * light, Point3F & attenuationRatio)

Detailed Description

Public Functions

DefineEngineFunction(loadColladaLights , bool , (const char *filename, const char *parentGroup, const char *baseObject) , ("", "") , "(string filename, <a href="/coding/class/classsimgroup/">SimGroup</a> parentGroup=<a href="/coding/class/classscene/">Scene</a>, <a href="/coding/class/classsimobject/">SimObject</a> baseObject=-1)" "Load all light instances from <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> COLLADA (.dae) <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> and add <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">scene.\n</a>" "@param filename COLLADA filename <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> load lights <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">from\n</a>" "@param parentGroup (optional) name of an existing simgroup <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> add the <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> " "lights <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> (defaults <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> root <a href="/coding/class/classscene/">Scene</a>)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@param baseObject (optional) name of an object <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> use as the origin (useful " "<a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> you are loading the lights <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> collada scene and have moved or rotated " "the geometry)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@return true <a href="/coding/file/tsmeshintrinsics_8cpp/#tsmeshintrinsics_8cpp_1a4e4fa7e3399708e0777b5308db01278c">if</a> successful, false <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">otherwise\n\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "//load the lights in <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">room.dae\n</a>" "loadColladaLights(\"art/shapes/collada/room.dae\" );\n\n" "// load the lights in room.dae and add them <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the RoomLights <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">group\n</a>" "loadColladaLights( \"art/shapes/collada/room.dae\", \"RoomLights\" );\n\n" "// load the lights in room.dae and use the transform of the \"Room\"\n" "object as the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">origin\n</a>" "loadColladaLights( \"art/shapes/collada/room.dae\", \"\", \"Room\" );\n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@note Currently <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Editors\n</a>" "@internal" )

processNodeLights(AppNode * appNode, const MatrixF & offset, SimGroup * group)

resolveLightAttenuation(T * light, Point3F & attenuationRatio)

resolveLightColor(T * light, LinearColorF & color)

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "console/engineAPI.h"
 25#include "platform/platform.h"
 26
 27#include "ts/collada/colladaUtils.h"
 28#include "ts/collada/colladaAppNode.h"
 29#include "ts/collada/colladaShapeLoader.h"
 30
 31#include "T3D/pointLight.h"
 32#include "T3D/spotLight.h"
 33
 34#include "T3D/Scene.h"
 35
 36//-----------------------------------------------------------------------------
 37// Collada <light> elements are very similar, but are arranged as separate, unrelated
 38// classes. These template functions are used to provide a simple way to access the
 39// common elements.
 40template<class T> static void resolveLightColor(T* light, LinearColorF& color)
 41{
 42   if (light->getColor())
 43   {
 44      color.red = light->getColor()->getValue()[0];
 45      color.green = light->getColor()->getValue()[1];
 46      color.blue = light->getColor()->getValue()[2];
 47   }
 48}
 49
 50template<class T> static void resolveLightAttenuation(T* light, Point3F& attenuationRatio)
 51{
 52   if (light->getConstant_attenuation())
 53      attenuationRatio.x = light->getConstant_attenuation()->getValue();
 54   if (light->getLinear_attenuation())
 55      attenuationRatio.y = light->getLinear_attenuation()->getValue();
 56   if (light->getQuadratic_attenuation())
 57      attenuationRatio.z = light->getQuadratic_attenuation()->getValue();
 58}
 59
 60//-----------------------------------------------------------------------------
 61// Recurse through the collada scene to add <light>s to the Torque scene
 62static void processNodeLights(AppNode* appNode, const MatrixF& offset, SimGroup* group)
 63{
 64   const domNode* node = dynamic_cast<ColladaAppNode*>(appNode)->getDomNode();
 65
 66   for (S32 iLight = 0; iLight < node->getInstance_light_array().getCount(); iLight++) {
 67
 68      domInstance_light* instLight = node->getInstance_light_array()[iLight];
 69      domLight* p_domLight = daeSafeCast<domLight>(instLight->getUrl().getElement());
 70      if (!p_domLight) {
 71         Con::warnf("Failed to find light for URL \"%s\"", instLight->getUrl().getOriginalURI());
 72         continue;
 73      }
 74
 75      String lightName = Sim::getUniqueName(_GetNameOrId(node));
 76      const char* lightType = "";
 77
 78      domLight::domTechnique_common* technique = p_domLight->getTechnique_common();
 79      if (!technique) {
 80         Con::warnf("No <technique_common> for light \"%s\"", lightName.c_str());
 81         continue;
 82      }
 83
 84      LightBase* pLight = 0;
 85      LinearColorF color(LinearColorF::WHITE);
 86      Point3F attenuation(0, 1, 1);
 87
 88      if (technique->getAmbient()) {
 89         domLight::domTechnique_common::domAmbient* ambient = technique->getAmbient();
 90         // No explicit support for ambient lights, so use a PointLight instead
 91         lightType = "ambient";
 92         pLight = new PointLight;
 93         resolveLightColor(ambient, color);
 94      }
 95      else if (technique->getDirectional()) {
 96         domLight::domTechnique_common::domDirectional* directional = technique->getDirectional();
 97         // No explicit support for directional lights, so use a SpotLight instead
 98         lightType = "directional";
 99         pLight = new SpotLight;
100         resolveLightColor(directional, color);
101      }
102      else if (technique->getPoint()) {
103         domLight::domTechnique_common::domPoint* point = technique->getPoint();
104         lightType = "point";
105         pLight = new PointLight;
106         resolveLightColor(point, color);
107         resolveLightAttenuation(point, attenuation);
108      }
109      else if (technique->getSpot()) {
110         domLight::domTechnique_common::domSpot* spot = technique->getSpot();
111         lightType = "spot";
112         pLight = new SpotLight;
113         resolveLightColor(spot, color);
114         resolveLightAttenuation(spot, attenuation);
115      }
116      else
117         continue;
118
119      Con::printf("Adding <%s> light \"%s\" as a %s", lightType, lightName.c_str(), pLight->getClassName());
120
121      MatrixF mat(offset);
122      mat.mul(appNode->getNodeTransform(TSShapeLoader::DefaultTime));
123
124      pLight->setDataField(StringTable->insert("color"), 0,
125         avar("%f %f %f %f", color.red, color.green, color.blue, color.alpha));
126      pLight->setDataField(StringTable->insert("attenuationRatio"), 0,
127         avar("%f %f %f", attenuation.x, attenuation.y, attenuation.z));
128      pLight->setTransform(mat);
129
130      if (!pLight->registerObject(lightName)) {
131         Con::errorf(ConsoleLogEntry::General, "Failed to register light for \"%s\"", lightName.c_str());
132         delete pLight;
133      }
134      else if (group)
135         group->addObject(pLight);
136   }
137
138   // Recurse child nodes
139   for (S32 iChild = 0; iChild < appNode->getNumChildNodes(); iChild++)
140      processNodeLights(appNode->getChildNode(iChild), offset, group);
141}
142
143// Load lights from a collada file and add to the scene.
144DefineEngineFunction( loadColladaLights, bool, (const char * filename, const char * parentGroup, const char * baseObject), ("", ""),
145   "(string filename, SimGroup parentGroup=Scene, SimObject baseObject=-1)"
146   "Load all light instances from a COLLADA (.dae) file and add to the scene.\n"
147   "@param filename COLLADA filename to load lights from\n"
148   "@param parentGroup (optional) name of an existing simgroup to add the new "
149   "lights to (defaults to root Scene)\n"
150   "@param baseObject (optional) name of an object to use as the origin (useful "
151   "if you are loading the lights for a collada scene and have moved or rotated "
152   "the geometry)\n"
153   "@return true if successful, false otherwise\n\n"
154   "@tsexample\n"
155   "// load the lights in room.dae\n"
156   "loadColladaLights( \"art/shapes/collada/room.dae\" );\n\n"
157   "// load the lights in room.dae and add them to the RoomLights group\n"
158   "loadColladaLights( \"art/shapes/collada/room.dae\", \"RoomLights\" );\n\n"
159   "// load the lights in room.dae and use the transform of the \"Room\"\n"
160   "object as the origin\n"
161   "loadColladaLights( \"art/shapes/collada/room.dae\", \"\", \"Room\" );\n"
162   "@endtsexample\n\n"
163   "@note Currently for editor use only\n"
164   "@ingroup Editors\n"
165   "@internal")
166{
167   Torque::Path path(filename);
168
169   // Optional group to add the lights to. Create if it does not exist, and use
170   // the root Scene if not specified.
171   Scene* scene = Scene::getRootScene();
172   SimGroup* group = 0;
173   if (!String::isEmpty(parentGroup)){
174      if (!Sim::findObject(parentGroup, group)) {
175         // Create the group if it could not be found
176         group = new SimGroup;
177         if (group->registerObject(parentGroup)) {
178            if (scene)
179               scene->addObject(group);
180         }
181         else {
182            delete group;
183            group = 0;
184         }
185      }
186   }
187   if (!group)
188      group = scene;
189
190   // Optional object to provide the base transform
191   MatrixF offset(true);
192   if (!String::isEmpty(baseObject)){
193      SceneObject *obj;
194      if (Sim::findObject(baseObject, obj))
195         offset = obj->getTransform();
196   }
197
198   // Load the Collada file into memory
199   domCOLLADA* root = ColladaShapeLoader::getDomCOLLADA(path);
200   if (!root) {
201      TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Load complete");
202      return false;
203   }
204
205   // Extract the global scale and up_axis from the top level <asset> element,
206   F32 unit = 1.0f;
207   domUpAxisType upAxis = UPAXISTYPE_Z_UP;
208   if (root->getAsset()) {
209      if (root->getAsset()->getUnit())
210         unit = root->getAsset()->getUnit()->getMeter();
211      if (root->getAsset()->getUp_axis())
212         upAxis = root->getAsset()->getUp_axis()->getValue();
213   }
214
215   ColladaUtils::getOptions().unit = unit;
216   ColladaUtils::getOptions().upAxis = upAxis;
217
218   // First grab all of the top-level nodes
219   Vector<ColladaAppNode*> sceneNodes;
220   for (S32 iSceneLib = 0; iSceneLib < root->getLibrary_visual_scenes_array().getCount(); iSceneLib++) {
221      const domLibrary_visual_scenes* libScenes = root->getLibrary_visual_scenes_array()[iSceneLib];
222      for (S32 iScene = 0; iScene < libScenes->getVisual_scene_array().getCount(); iScene++) {
223         const domVisual_scene* visualScene = libScenes->getVisual_scene_array()[iScene];
224         for (S32 iNode = 0; iNode < visualScene->getNode_array().getCount(); iNode++)
225            sceneNodes.push_back(new ColladaAppNode(visualScene->getNode_array()[iNode]));
226      }
227   }
228
229   // Recurse the scene tree looking for <instance_light>s
230   for (S32 iNode = 0; iNode < sceneNodes.size(); iNode++) {
231      processNodeLights(sceneNodes[iNode], offset, group);
232      delete sceneNodes[iNode];
233   }
234
235   TSShapeLoader::updateProgress(TSShapeLoader::Load_Complete, "Load complete");
236
237   return true;
238}
239