Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogreode/loader/src/OgreOdeDotLoader.cpp @ 21

Last change on this file since 21 was 21, checked in by nicolasc, 16 years ago

added ogreode and Colladaplugin

File size: 20.6 KB
Line 
1#include "OgreOde_Core.h"
2#include "OgreOde_Prefab.h"
3#include "OgreOde_Loader.h"
4
5#include "tinyxml.h"
6
7using namespace Ogre;
8using namespace OgreOde;
9using namespace OgreOde_Prefab;
10using namespace OgreOde_Loader;
11
12//------------------------------------------------------------------------------------------------
13static const TiXmlElement *getFirstOgreOde(const TiXmlElement *root);
14static const TiXmlElement *getFirstOgreOde(const TiXmlElement *root)                       
15{
16    // should have some recursive algo
17    if (!strcmp(root->Value(), "ogreode"))
18    {
19        return root;
20    }
21    for (const TiXmlNode *child = root->FirstChild(); child; child = child->NextSibling())
22    {
23        if (child->Type() == TiXmlNode::ELEMENT)
24        {
25            const TiXmlElement *res = getFirstOgreOde(child->ToElement ());
26            if (res)
27                return res;
28        }
29    }
30    return 0;
31}
32
33//------------------------------------------------------------------------------------------------
34DotLoader::DotLoader(OgreOde::World * world, OgreOde::Space * space) :
35    _world(world),
36    _space (space)
37{
38
39}
40//------------------------------------------------------------------------------------------------
41void DotLoader::saveObject(const String &filename, const String &object_name, Object  *object)
42{
43
44}
45//------------------------------------------------------------------------------------------------
46void DotLoader::serializeObject(const String &filename, const String &object_name, Object  *)
47{
48
49}
50//------------------------------------------------------------------------------------------------
51void DotLoader::serializeVehicle(const String &filename, const String &vehicle_name, Vehicle *)
52{
53
54}
55//------------------------------------------------------------------------------------------------
56void DotLoader::serializeRagdoll(const String &filename, const String &ragdoll_name, Ragdoll *)
57{
58
59}
60//------------------------------------------------------------------------------------------------
61void DotLoader::save(const String &filename, const StringVector &objects_names, ObjectList  *)
62{
63
64}
65//------------------------------------------------------------------------------------------------
66ObjectList  *DotLoader::load(const String &filename, const StringVector &objects_names, const StringVector &instance_names)
67{
68    ObjectList* objectList = new ObjectList();
69
70    //
71
72    return  objectList;
73
74}
75
76
77//------------------------------------------------------------------------------------------------
78Object* DotLoader::loadObject(const String &filename, const String &object_name, const String &instance_name)
79{
80   // load and check file
81   TiXmlDocument *doc = loadFile (filename);
82   const TiXmlElement *root = getFirstOgreOde(doc->RootElement());
83   // search for any element
84   Object* objLoading = 0;
85
86   for (const TiXmlNode *child = root->FirstChild(); child; child = child->NextSibling() )
87   {
88       if (child->Type() == TiXmlNode::ELEMENT)
89       {
90           objLoading = parseObject (child, object_name, instance_name);
91           if (objLoading)
92            break;
93       }
94   }
95   delete doc;
96   return objLoading;
97}
98
99//------------------------------------------------------------------------------------------------
100Object* DotLoader::parseObject(const TiXmlNode *child, const String &object_name, const String &instance_name)
101{
102    Object* objLoading = 0;
103    if ((child->Type() == TiXmlNode::ELEMENT) && (!strcmp(child->Value(), "vehicle")))
104    {
105        objLoading = parseVehicle (child, object_name, instance_name);
106    }
107    else if ((child->Type() == TiXmlNode::ELEMENT) && (!strcmp(child->Value(), "ragdoll")))
108    {
109        objLoading = parseRagdoll (child, object_name, instance_name);
110    }
111    else if ((child->Type() == TiXmlNode::ELEMENT) && (!strcmp(child->Value(), "composite")))
112    {
113        objLoading = parseCompositeObject  (child, object_name, instance_name);
114    }
115    else if ((child->Type() == TiXmlNode::ELEMENT) && (!strcmp(child->Value(), "object")))
116    {
117        objLoading = parseSingleObject (child, object_name, instance_name);
118    }
119    return objLoading;
120}
121
122//------------------------------------------------------------------------------------------------
123Object*  DotLoader::parseCompositeObject(const TiXmlNode*child, const String &object_name, const String &instance_name)
124{
125        Object* object = new Object(ObjectType_CompositeObject, _world);
126
127       
128
129        return  object;
130}
131//------------------------------------------------------------------------------------------------
132Object*  DotLoader::parseSingleObject(const TiXmlNode*child, const String &object_name, const String &instance_name)
133{
134    Object* object = new Object(ObjectType_Single_Object, _world);
135
136
137
138    return  object;
139}
140//------------------------------------------------------------------------------------------------
141Vehicle* DotLoader::parseVehicle(const TiXmlNode* child, const String &vehicle_name, const String &instance_name)
142{
143        String my_name = vehicle_name;
144        Vehicle *vehicle = 0;
145
146        const TiXmlElement *vehicleElement = (const TiXmlElement*)child;
147        if (vehicleElement->Attribute("name") && (!strcmp(vehicleElement->Attribute("name"),my_name.c_str())))
148        {
149
150        String instanceFinalName ((instance_name == StringUtil::BLANK) ?
151            vehicle_name + StringConverter::toString(OgreOde_Prefab::Object::getInstanceNumberAndIncrement ())
152            : instance_name);
153
154        vehicle = new Vehicle(instanceFinalName, _world, _space);
155
156                for (const TiXmlNode *tag = child->FirstChild(); tag; tag = tag->NextSibling() )
157                {
158                        if (tag->Type() == TiXmlNode::ELEMENT)
159                        {
160                                const TiXmlElement *element = (const TiXmlElement*)tag;
161
162                                if (!strcmp(tag->Value(),"body"))
163                                {
164                                        if (element->Attribute("mesh"))
165                                        {
166                                                MeshManager::getSingleton().load(
167                                                        element->Attribute("mesh"),
168                                                        // note that you can change the group by pre-loading the mesh
169                                                        ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );
170                                                vehicle->setEntity (_world->getSceneManager()->createEntity(
171                                                        vehicle->getName() + Ogre::StringConverter::toString (vehicle->getInstanceNumber()) +  "_Entity", 
172                                                        element->Attribute("mesh")));
173                                                vehicle->getEntity()->setCastShadows(true);
174
175                                                vehicle->getTransNode()->attachObject(vehicle->getEntity());
176
177                                                EntityInformer ei(vehicle->getEntity());
178                                                Vector3 box = ei.getSize();
179
180                                                if (!vehicle->getGeometry()) 
181                                                        vehicle->setGeometry(new BoxGeometry(box, _world, _space));
182                                                vehicle->getGeometry()->setUserObject(vehicle);
183
184                                                vehicle->setTransformGeometry(new TransformGeometry(_world, vehicle->getSpace()));
185                                                vehicle->getTransformGeometry()->setEncapsulatedGeometry(vehicle->getGeometry());
186                                                vehicle->getTransformGeometry()->setBody(vehicle->getBody());
187                                        }
188
189                                        for (const TiXmlNode *sub_tag = tag->FirstChild(); sub_tag; sub_tag = sub_tag->NextSibling() )
190                                        {
191                                                if (sub_tag->Type() == TiXmlNode::ELEMENT)
192                                                {
193                                                        const TiXmlElement *sub_element = (const TiXmlElement*)sub_tag;
194
195                                                        if (vehicle->getEntity() && (!strcmp(sub_tag->Value(),"mass")))
196                                                        {
197                                                                double tmp;
198                                                                if (sub_element->Attribute("value",&tmp))
199                                                                {
200                                                                        EntityInformer ei(vehicle->getEntity());
201                                                                        Vector3 box = ei.getSize();
202
203                                                                        BoxMass box_mass((Real)tmp,Vector3(box.x,box.y,box.z));
204                                                                        vehicle->getBody()->setMass(box_mass);
205                                                                }
206
207                                                                Vector3 offset = Ogre::Vector3::ZERO;
208
209                                                                if (sub_element->Attribute("x",&tmp)) offset.x = (Real)tmp; 
210                                                                if (sub_element->Attribute("y",&tmp)) offset.y = (Real)tmp; 
211                                                                if (sub_element->Attribute("z",&tmp)) offset.z = (Real)tmp; 
212
213                                                                vehicle->setOffset(-offset);
214                                                        }
215                                                }
216                                        }
217                                }
218                                else if (!strcmp(tag->Value(),"wheel"))
219                                {
220                                        Vehicle::Wheel *wheel = 0;
221                                        double x,y,z,mass;
222
223                                        if (element->Attribute("mesh"))
224                                        {
225                                                wheel = vehicle->addWheel(element->Attribute("mesh"),
226                                                                                Vector3((element->Attribute("x",&x))?(Real)x:0.0,
227                                                                                                (element->Attribute("y",&y))?(Real)y:0.0,
228                                                                                                (element->Attribute("z",&z))?(Real)z:0.0),
229                                                                                (element->Attribute("mass",&mass))?(Real)mass:1.0);
230                                        }
231
232                                        if (wheel)
233                                        {
234                                                for (const TiXmlNode *sub_tag = tag->FirstChild(); sub_tag; sub_tag = sub_tag->NextSibling() )
235                                                {
236                                                        if (sub_tag->Type() == TiXmlNode::ELEMENT)
237                                                        {
238                                                                const TiXmlElement *sub_element = (const TiXmlElement*)sub_tag;
239
240                                                                if (!strcmp(sub_tag->Value(),"steer"))
241                                                                {
242                                                                        double tmp;
243                                                                        if (sub_element->Attribute("factor",&tmp)) wheel->setSteerFactor(tmp);
244                                                                        if (sub_element->Attribute("limit",&tmp)) wheel->setSteerLimit(tmp);
245                                                                        if (sub_element->Attribute("force",&tmp)) wheel->setSteerForce(tmp);
246                                                                        if (sub_element->Attribute("speed",&tmp)) wheel->setSteerSpeed(tmp);
247                                                                }
248                                                                else if (!strcmp(sub_tag->Value(),"power"))
249                                                                {
250                                                                        double tmp;
251                                                                        if (sub_element->Attribute("factor",&tmp)) wheel->setPowerFactor(tmp);
252                                                                }
253                                                                else if (!strcmp(sub_tag->Value(),"brake"))
254                                                                {
255                                                                        double tmp;
256                                                                        if (sub_element->Attribute("factor",&tmp)) wheel->setBrakeFactor(tmp);
257                                                                }
258                                                                else if (!strcmp(sub_tag->Value(),"contact"))
259                                                                {
260                                                                        double bouncyness,friction,fds;
261                                                                        wheel->setContact((sub_element->Attribute("bouncyness",&bouncyness))?(Real)bouncyness:0.0,(sub_element->Attribute("friction",&friction))?(Real)friction:0.0,(sub_element->Attribute("fds",&fds))?(Real)fds:0.0);
262                                                                }
263                                                                else if (!strcmp(sub_tag->Value(),"suspension"))
264                                                                {
265                                                                        double spring,damping,step;
266                                                                        vehicle->setSuspension((sub_element->Attribute("spring",&spring))?(Real)spring:0.0,(sub_element->Attribute("damping",&damping))?(Real)damping:0.0,(sub_element->Attribute("step",&step))?(Real)step:0.0);
267                                                                }
268                                                        }
269                                                }
270                                        }
271                                }
272                                else if (!strcmp(tag->Value(),"suspension"))
273                                {
274                                        double spring,damping,step;
275                                        vehicle->setSuspension((element->Attribute("spring",&spring))?(Real)spring:0.0,(element->Attribute("damping",&damping))?(Real)damping:0.0,(element->Attribute("step",&step))?(Real)step:0.0);
276                                }
277                                else if (!strcmp(tag->Value(),"engine"))
278                                {
279                                        double tmp;
280
281                                        if (element->Attribute("redline",&tmp)) vehicle->getEngine()->setRevLimit((Real)tmp);
282                                        if (element->Attribute("brake",&tmp)) vehicle->getEngine()->setBrakeForce((Real)tmp);
283
284                                        static const unsigned int MAX_SAMPLES = 255;
285                                        Real torqueCurve[MAX_SAMPLES];
286                                        unsigned int torqueSamples = 0;
287                                        for (const TiXmlNode *sub_tag = tag->FirstChild(); sub_tag; sub_tag = sub_tag->NextSibling() )
288                                        {
289                                                if (sub_tag->Type() == TiXmlNode::ELEMENT)
290                                                {
291                                                        const TiXmlElement *sub_element = (const TiXmlElement*)sub_tag;
292
293                                                        if (!strcmp(sub_tag->Value(),"torque"))
294                                                        {
295                                                                double min_torque,max_torque;
296                                                                vehicle->getEngine()->setTorque((sub_element->Attribute("min",&min_torque))?min_torque:0.0,(sub_element->Attribute("max",&max_torque))?max_torque:0.0);
297                                                        }
298                                                        else if (!strcmp(sub_tag->Value(),"torquecurve"))
299                                                        {
300                                                                double curveValue;
301                                                                if( sub_element->Attribute( "value", &curveValue ) )
302                                                                {
303                                                                        if( torqueSamples < MAX_SAMPLES )
304                                                                                torqueCurve[torqueSamples++] = curveValue;
305                                                                }
306                                                        }
307                                                }
308                                        }
309                                        if( torqueSamples )
310                                        {
311                                                vehicle->getEngine()->setTorque( torqueCurve, torqueSamples );
312                                        }
313                                }
314                                else if (!strcmp(tag->Value(),"antisway"))
315                                {
316                                        vehicle->enableAntiSway (true);
317
318                                        double dtmp;
319                                        if (element->Attribute("swayForce",&dtmp)) 
320                                                vehicle->setSwayForce((Real) dtmp);
321
322                                        int uitmp;
323                                        if (element->Attribute("forceLimit",&uitmp)) 
324                                                vehicle->setSwayForceLimit((unsigned int) uitmp);
325
326                                        if (element->Attribute("rate",&dtmp)) 
327                                                vehicle->setSwayForceRate((Real) dtmp);
328                                }
329                        }
330                }
331        }
332
333       
334
335    if (vehicle)
336    {
337        if (vehicle->isAntiSwayEnabled() && vehicle->getWheelCount() != 4)
338            {
339                    assert (0 && "no sway for non 4 wheels");
340                    vehicle->enableAntiSway (false);
341            }
342    }
343        return vehicle;
344}
345//------------------------------------------------------------------------------------------------
346Ragdoll* DotLoader::parseRagdoll(const TiXmlNode *child, const String &ragdoll_name, const String &instance_name)
347{
348    Ragdoll *ragdoll = 0;
349
350        const TiXmlElement *ragdollElement = (const TiXmlElement*)child;
351        Ogre::String ragdoll_name_asked (ragdoll_name);
352        Ogre::String ragdoll_name_from_file (ragdollElement->Attribute("name"));
353
354        Ogre::StringUtil::toLowerCase(ragdoll_name_from_file);
355        Ogre::StringUtil::toLowerCase(ragdoll_name_asked);
356        bool found = ragdoll_name_asked.empty() || (!ragdoll_name_from_file.empty() && ragdoll_name_from_file == ragdoll_name_asked);
357
358        if (found)
359        {
360        const String meshFileName (ragdollElement->Attribute("meshName"));
361
362        String instanceFinalName ((instance_name == StringUtil::BLANK) ?
363             meshFileName + StringConverter::toString(OgreOde_Prefab::Object::getInstanceNumberAndIncrement ())
364            : instance_name);
365 
366
367        NameValuePairList params;
368        params["mesh"] = meshFileName;
369        ragdoll = static_cast<OgreOde_Prefab::Ragdoll*>
370            (_world->getSceneManager ()->createMovableObject(instanceFinalName, 
371                                                                            OgreOde_Prefab::RagdollFactory::FACTORY_TYPE_NAME,
372                                                                            &params)); 
373
374                Ragdoll::BoneSettings settings;
375
376                for (const TiXmlNode *tag = child->FirstChild(); tag; tag = tag->NextSibling() )
377                {
378                        if (tag->Type() == TiXmlNode::ELEMENT)
379                        {
380                const TiXmlElement *element = (const TiXmlElement*)tag;
381                                if (!strcmp(tag->Value(),"defaults"))
382                                {
383                                        parseRagdollSettings(&settings,tag);
384                                        ragdoll->setDefaultBoneSettings(settings);
385                                }
386                                else if ((!strcmp(tag->Value(),"bone")) 
387                        && (element->Attribute("name")))
388                                {
389                                        parseRagdollSettings(&settings,tag);
390                                        ragdoll->setBoneSettings(element->Attribute("name"),settings); 
391                                }
392                        }
393                }
394        }
395        return ragdoll;
396}
397
398//------------------------------------------------------------------------------------------------
399void DotLoader::parseRagdollSettings(Ragdoll::BoneSettings *bone_settings,const void *tag) const
400{
401    const TiXmlElement *element = (const TiXmlElement *)tag;
402
403    for (const TiXmlNode *node = element->FirstChild(); node; node = node->NextSibling() )
404    {
405        if ((node->Type() ==  TiXmlNode::ELEMENT) && (!stricmp(node->Value(),"settings")))
406        {
407            const TiXmlElement *settings = (const TiXmlElement*)node;
408            double tmp;
409
410            if (settings->Attribute("geometry"))
411            {
412                if (!strcmp(settings->Attribute("geometry"),"capsule")) bone_settings->_geometry_class = Geometry::Class_Capsule;
413                else if (!strcmp(settings->Attribute("geometry"),"box")) bone_settings->_geometry_class = Geometry::Class_Box;
414                else if (!strcmp(settings->Attribute("geometry"),"none")) bone_settings->_geometry_class = Geometry::Class_NoGeometry;
415            }
416
417            if (settings->Attribute("joint"))
418            {
419                if (!strcmp(settings->Attribute("joint"),"fixed")) bone_settings->_joint_type = Joint::Type_FixedJoint;
420                else if (!strcmp(settings->Attribute("joint"),"hinge")) bone_settings->_joint_type = Joint::Type_HingeJoint;
421                else if (!strcmp(settings->Attribute("joint"),"ball")) bone_settings->_joint_type = Joint::Type_BallJoint;
422                else if (!strcmp(settings->Attribute("joint"),"universal")) bone_settings->_joint_type = Joint::Type_UniversalJoint;
423            }
424
425            if (settings->Attribute("joint"))
426            {
427                if (!strcmp(settings->Attribute("joint"),"fixed")) bone_settings->_joint_type = Joint::Type_FixedJoint;
428                else if (!strcmp(settings->Attribute("joint"),"hinge")) bone_settings->_joint_type = Joint::Type_HingeJoint;
429                else if (!strcmp(settings->Attribute("joint"),"ball")) bone_settings->_joint_type = Joint::Type_BallJoint;
430                else if (!strcmp(settings->Attribute("joint"),"universal")) bone_settings->_joint_type = Joint::Type_UniversalJoint;
431            }
432
433            if (settings->Attribute("collapse"))
434            {
435                if (!strcmp(settings->Attribute("collapse"),"none")) bone_settings->_collapse = Ragdoll::BoneSettings::Collapse_None;
436                else if (!strcmp(settings->Attribute("collapse"),"up")) bone_settings->_collapse = Ragdoll::BoneSettings::Collapse_Up;
437                else if (!strcmp(settings->Attribute("collapse"),"down")) bone_settings->_collapse = Ragdoll::BoneSettings::Collapse_Down;
438            }
439
440            if (settings->Attribute("mass",&tmp)) bone_settings->_mass = (Real)tmp;
441            if (settings->Attribute("radius",&tmp)) bone_settings->_radius = (Real)tmp;
442
443            for (const TiXmlNode *sub_node = node->FirstChild(); sub_node; sub_node = sub_node->NextSibling() )
444            {
445                if (sub_node->Type() ==  TiXmlNode::ELEMENT)
446                {
447                    const TiXmlElement *sub_settings = (const TiXmlElement*)sub_node;
448
449                    if (!stricmp(sub_node->Value(),"damping"))
450                    {
451                        if (sub_settings->Attribute("angular",&tmp)) bone_settings->_angular_damping = (Real)tmp;
452                        if (sub_settings->Attribute("linear",&tmp)) bone_settings->_linear_damping = (Real)tmp;
453                    }
454                    else if (!stricmp(sub_node->Value(),"axis"))
455                    {
456                        int n;
457                        if (sub_settings->Attribute("number",&n))
458                        {
459                            if (n == 1)
460                            {
461                                if (sub_settings->Attribute("x",&tmp)) bone_settings->_primary_axis.x = (Real)tmp;
462                                if (sub_settings->Attribute("y",&tmp)) bone_settings->_primary_axis.y = (Real)tmp;
463                                if (sub_settings->Attribute("z",&tmp)) bone_settings->_primary_axis.z = (Real)tmp;
464
465                                bone_settings->_primary_axis.normalise();
466                            }
467                            else if (n == 2)
468                            {
469                                if (sub_settings->Attribute("x",&tmp)) bone_settings->_secondary_axis.x = (Real)tmp;
470                                if (sub_settings->Attribute("y",&tmp)) bone_settings->_secondary_axis.y = (Real)tmp;
471                                if (sub_settings->Attribute("z",&tmp)) bone_settings->_secondary_axis.z = (Real)tmp;
472
473                                bone_settings->_secondary_axis.normalise();
474                            }
475
476                            for (const TiXmlNode *sub_sub_node = sub_node->FirstChild(); sub_sub_node; sub_sub_node = sub_sub_node->NextSibling() )
477                            {
478                                if ((sub_sub_node->Type() ==  TiXmlNode::ELEMENT) && (!stricmp(sub_sub_node->Value(),"stop")))
479                                {
480                                    const TiXmlElement *sub_sub_settings = (const TiXmlElement*)sub_sub_node;
481
482                                    if (n == 1)
483                                    {
484                                        if (sub_sub_settings->Attribute("low",&tmp)) bone_settings->_primary_lostop = (Real)tmp;
485                                        if (sub_sub_settings->Attribute("high",&tmp)) bone_settings->_primary_histop = (Real)tmp;
486                                    }
487                                    else if (n == 2)
488                                    {
489                                        if (sub_sub_settings->Attribute("low",&tmp)) bone_settings->_secondary_lostop = (Real)tmp;
490                                        if (sub_sub_settings->Attribute("high",&tmp)) bone_settings->_secondary_histop = (Real)tmp;
491                                    }
492                                }       
493                            }
494                        }
495                    }
496                }
497            }
498        }
499    }
500}
501
502//------------------------------------------------------------------------------------------------
503TiXmlDocument * DotLoader::loadFile(const String &filename)
504{
505    // load and check file
506    DataStreamPtr file = ResourceGroupManager::getSingleton().openResource(filename);
507    TiXmlDocument *doc = new TiXmlDocument(filename.c_str());
508    doc->Parse(file->getAsString().c_str());
509    if (doc->Error())
510    {
511        throw new Exception(doc->ErrorId(),
512            doc->ErrorDesc(), 
513            __FILE__,
514            "erreur",
515            ((char*)(file->getName().c_str())),
516            doc->ErrorRow());
517    }
518
519    // get the ogreode element.
520    TiXmlNode* node = doc->FirstChild( "ogreode" );
521    if (!node)
522    {
523        Ogre::LogManager::getSingleton().logMessage("  cannot find ogreode root in XML file!");
524        return 0;
525    }
526    return doc;
527}
Note: See TracBrowser for help on using the repository browser.