Selaa lähdekoodia

Added support for inline properties within the scene file.
Removed support for wildcards in node urls in the scene file.
Adds support for namespaces to end on the same line they begin on in Properties.cpp.

Chris Culy 13 vuotta sitten
vanhempi
sitoutus
5da5cd58f5
3 muutettua tiedostoa jossa 194 lisäystä ja 228 poistoa
  1. 75 0
      gameplay/src/Properties.cpp
  2. 109 216
      gameplay/src/SceneLoader.cpp
  3. 10 12
      gameplay/src/SceneLoader.h

+ 75 - 0
gameplay/src/Properties.cpp

@@ -145,6 +145,7 @@ void Properties::readProperties(FILE* file)
     char* parentID;
     char* parentID;
     char* rc;
     char* rc;
     char* rcc;
     char* rcc;
+    char* rccc;
 
 
     while (true)
     while (true)
     {
     {
@@ -205,6 +206,9 @@ void Properties::readProperties(FILE* file)
             {
             {
                 parentID = NULL;
                 parentID = NULL;
 
 
+                // Get the last character on the line (ignoring whitespace).
+                const char* lineEnd = trimWhiteSpace(line) + (strlen(trimWhiteSpace(line)) - 1);
+
                 // This line might begin or end a namespace,
                 // This line might begin or end a namespace,
                 // or it might be a key/value pair without '='.
                 // or it might be a key/value pair without '='.
 
 
@@ -213,6 +217,9 @@ void Properties::readProperties(FILE* file)
 
 
                 // Check for inheritance: ':'
                 // Check for inheritance: ':'
                 rcc = strchr(line, ':');
                 rcc = strchr(line, ':');
+
+                // Check for '}' on same line.
+                rccc = strchr(line, '}');
             
             
                 // Get the name of the namespace.
                 // Get the name of the namespace.
                 name = strtok(line, " \t\n{");
                 name = strtok(line, " \t\n{");
@@ -231,6 +238,8 @@ void Properties::readProperties(FILE* file)
                 // Get its ID if it has one.
                 // Get its ID if it has one.
                 value = strtok(NULL, ":{");
                 value = strtok(NULL, ":{");
                 value = trimWhiteSpace(value);
                 value = trimWhiteSpace(value);
+
+                // Get its parent ID if it has one.
                 if (rcc != NULL)
                 if (rcc != NULL)
                 {
                 {
                     parentID = strtok(NULL, "{");
                     parentID = strtok(NULL, "{");
@@ -239,18 +248,84 @@ void Properties::readProperties(FILE* file)
 
 
                 if (value != NULL && value[0] == '{')
                 if (value != NULL && value[0] == '{')
                 {
                 {
+                    // If the namespace ends on this line, seek back to right before the '}' character.
+                    if (rccc && rccc == lineEnd)
+                    {
+                        if (fseek(file, -1, SEEK_CUR) != 0)
+                        {
+                            GP_ERROR("Failed to seek back to before a '}' character in properties file.");
+                            return;
+                        }
+                        while (fgetc(file) != '}')
+                        {
+                            if (fseek(file, -2, SEEK_CUR) != 0)
+                            {
+                                GP_ERROR("Failed to seek back to before a '}' character in properties file.");
+                                return;
+                            }
+                        }
+                        if (fseek(file, -1, SEEK_CUR) != 0)
+                        {
+                            GP_ERROR("Failed to seek back to before a '}' character in properties file.");
+                            return;
+                        }
+                    }
+
                     // New namespace without an ID.
                     // New namespace without an ID.
                     Properties* space = new Properties(file, name, NULL, parentID);
                     Properties* space = new Properties(file, name, NULL, parentID);
                     _namespaces.push_back(space);
                     _namespaces.push_back(space);
+
+                    // If the namespace ends on this line, seek to right after the '}' character.
+                    if (rccc && rccc == lineEnd)
+                    {
+                        if (fseek(file, 1, SEEK_CUR) != 0)
+                        {
+                            GP_ERROR("Failed to seek to immediately after a '}' character in properties file.");
+                            return;
+                        }
+                    }
                 }
                 }
                 else
                 else
                 {
                 {
                     // If '{' appears on the same line.
                     // If '{' appears on the same line.
                     if (rc != NULL)
                     if (rc != NULL)
                     {
                     {
+                        // If the namespace ends on this line, seek back to right before the '}' character.
+                        if (rccc && rccc == lineEnd)
+                        {
+                            if (fseek(file, -1, SEEK_CUR) != 0)
+                            {
+                                GP_ERROR("Failed to seek back to before a '}' character in properties file.");
+                                return;
+                            }
+                            while (fgetc(file) != '}')
+                            {
+                                if (fseek(file, -2, SEEK_CUR) != 0)
+                                {
+                                    GP_ERROR("Failed to seek back to before a '}' character in properties file.");
+                                    return;
+                                }
+                            }
+                            if (fseek(file, -1, SEEK_CUR) != 0)
+                            {
+                                GP_ERROR("Failed to seek back to before a '}' character in properties file.");
+                                return;
+                            }
+                        }
+
                         // Create new namespace.
                         // Create new namespace.
                         Properties* space = new Properties(file, name, value, parentID);
                         Properties* space = new Properties(file, name, value, parentID);
                         _namespaces.push_back(space);
                         _namespaces.push_back(space);
+
+                        // If the namespace ends on this line, seek to right after the '}' character.
+                        if (rccc && rccc == lineEnd)
+                        {
+                            if (fseek(file, 1, SEEK_CUR) != 0)
+                            {
+                                GP_ERROR("Failed to seek to immediately after a '}' character in properties file.");
+                                return;
+                            }
+                        }
                     }
                     }
                     else
                     else
                     {
                     {

+ 109 - 216
gameplay/src/SceneLoader.cpp

@@ -6,13 +6,19 @@
 namespace gameplay
 namespace gameplay
 {
 {
 
 
-std::map<std::string, Properties*> SceneLoader::_propertiesFromFile;
+std::map<std::string, Properties*> SceneLoader::_properties;
 std::vector<SceneLoader::SceneAnimation> SceneLoader::_animations;
 std::vector<SceneLoader::SceneAnimation> SceneLoader::_animations;
 std::vector<SceneLoader::SceneNode> SceneLoader::_sceneNodes;
 std::vector<SceneLoader::SceneNode> SceneLoader::_sceneNodes;
+std::string SceneLoader::_gpbPath;
 std::string SceneLoader::_path;
 std::string SceneLoader::_path;
 
 
 Scene* SceneLoader::load(const char* url)
 Scene* SceneLoader::load(const char* url)
 {
 {
+    // Get the file part of the url that we are loading the scene from.
+    std::string urlStr = url ? url : "";
+    std::string id;
+    splitURL(urlStr, &_path, &id);
+
     // Load the scene properties from file.
     // Load the scene properties from file.
     Properties* properties = Properties::create(url);
     Properties* properties = Properties::create(url);
     if (properties == NULL)
     if (properties == NULL)
@@ -31,9 +37,9 @@ Scene* SceneLoader::load(const char* url)
     }
     }
 
 
     // Get the path to the main GPB.
     // Get the path to the main GPB.
-    _path = sceneProperties->getString("path");
+    _gpbPath = sceneProperties->getString("path");
 
 
-    // Build the node URL/property and animation reference tables and load the referenced files.
+    // Build the node URL/property and animation reference tables and load the referenced files/store the inline properties objects.
     buildReferenceTables(sceneProperties);
     buildReferenceTables(sceneProperties);
     loadReferencedFiles();
     loadReferencedFiles();
 
 
@@ -83,17 +89,18 @@ Scene* SceneLoader::load(const char* url)
         loadPhysics(physics, scene);
         loadPhysics(physics, scene);
 
 
     // Clean up all loaded properties objects.
     // Clean up all loaded properties objects.
-    std::map<std::string, Properties*>::iterator iter = _propertiesFromFile.begin();
-    for (; iter != _propertiesFromFile.end(); iter++)
+    std::map<std::string, Properties*>::iterator iter = _properties.begin();
+    for (; iter != _properties.end(); iter++)
     {
     {
-        SAFE_DELETE(iter->second);
+        if (iter->first.find(_path) == iter->first.npos)
+            SAFE_DELETE(iter->second);
     }
     }
 
 
     // Clean up the .scene file's properties object.
     // Clean up the .scene file's properties object.
     SAFE_DELETE(properties);
     SAFE_DELETE(properties);
 
 
     // Clear all temporary data stores.
     // Clear all temporary data stores.
-    _propertiesFromFile.clear();
+    _properties.clear();
     _animations.clear();
     _animations.clear();
     _sceneNodes.clear();
     _sceneNodes.clear();
 
 
@@ -102,46 +109,28 @@ Scene* SceneLoader::load(const char* url)
 
 
 void SceneLoader::addSceneAnimation(const char* animationID, const char* targetID, const char* url)
 void SceneLoader::addSceneAnimation(const char* animationID, const char* targetID, const char* url)
 {
 {
-    // Calculate the file and id from the given url.
-    std::string file;
-    std::string id;
-    splitURL(url, &file, &id);
+    std::string urlStr = url ? url : "";
 
 
     // If there is a file that needs to be loaded later, add an 
     // If there is a file that needs to be loaded later, add an 
     // empty entry to the properties table to signify it.
     // empty entry to the properties table to signify it.
-    if (file.length() > 0 && _propertiesFromFile.count(file) == 0)
-        _propertiesFromFile[file] = NULL;
+    if (urlStr.length() > 0 && _properties.count(urlStr) == 0)
+        _properties[urlStr] = NULL;
 
 
     // Add the animation to the list of animations to be resolved later.
     // Add the animation to the list of animations to be resolved later.
-    _animations.push_back(SceneAnimation(animationID, targetID, file, id));
+    _animations.push_back(SceneAnimation(animationID, targetID, urlStr));
 }
 }
 
 
 void SceneLoader::addSceneNodeProperty(SceneNode& sceneNode, SceneNodeProperty::Type type, const char* url, int index)
 void SceneLoader::addSceneNodeProperty(SceneNode& sceneNode, SceneNodeProperty::Type type, const char* url, int index)
 {
 {
-    // Calculate the file and id from the given url.
-    std::string file;
-    std::string id;
-    splitURL(url, &file, &id);
+    std::string urlStr = url ? url : "";
 
 
     // If there is a non-GPB file that needs to be loaded later, add an 
     // If there is a non-GPB file that needs to be loaded later, add an 
     // empty entry to the properties table to signify it.
     // empty entry to the properties table to signify it.
-    if (file.length() > 0 && file.find(".gpb") == file.npos && _propertiesFromFile.count(file) == 0)
-        _propertiesFromFile[file] = NULL;
-
-    SceneNodeProperty prop(type, file, id, index);
-
-    // Parse for wildcharacter character (only supported on the URL attribute)
-    if (type == SceneNodeProperty::URL)
-    {
-        if (id.length() > 1 && id.at(id.length()-1) == '*')
-        {
-            prop._id = id.substr(0, id.length()-1);
-            sceneNode._exactMatch = false;
-        }
-    }
+    if (urlStr.length() > 0 && urlStr.find(".gpb") == urlStr.npos && _properties.count(urlStr) == 0)
+        _properties[urlStr] = NULL;
 
 
     // Add the node property to the list of node properties to be resolved later.
     // Add the node property to the list of node properties to be resolved later.
-    sceneNode._properties.push_back(prop);
+    sceneNode._properties.push_back(SceneNodeProperty(type, urlStr, index));
 }
 }
 
 
 void SceneLoader::applyNodeProperties(const Scene* scene, const Properties* sceneProperties, unsigned int typeFlags)
 void SceneLoader::applyNodeProperties(const Scene* scene, const Properties* sceneProperties, unsigned int typeFlags)
@@ -151,43 +140,19 @@ void SceneLoader::applyNodeProperties(const Scene* scene, const Properties* scen
         SceneNode& sceneNode = _sceneNodes[i];
         SceneNode& sceneNode = _sceneNodes[i];
         GP_ASSERT(sceneNode._nodeID);
         GP_ASSERT(sceneNode._nodeID);
 
 
-        if (sceneNode._exactMatch)
+        // Find the node matching the specified ID.
+        Node* node = scene->findNode(sceneNode._nodeID);
+        if (!node)
         {
         {
-            // Find the node matching the specified ID exactly.
-            Node* node = scene->findNode(sceneNode._nodeID);
-            if (!node)
-            {
-                GP_ERROR("Failed to set property for node '%s', which does not exist in the scene.", sceneNode._nodeID);
-                continue;
-            }
-
-            for (unsigned int j = 0, pcount = sceneNode._properties.size(); j < pcount; ++j)
-            {
-                SceneNodeProperty& snp = sceneNode._properties[j];
-                if (typeFlags & snp._type)
-                    applyNodeProperty(sceneNode, node, sceneProperties, snp, scene);
-            }
+            GP_ERROR("Failed to set property for node '%s', which does not exist in the scene.", sceneNode._nodeID);
+            continue;
         }
         }
-        else
-        {
-            // Find all nodes matching the specified ID.
-            std::vector<Node*> nodes;
-            unsigned int nodeCount = scene->findNodes(sceneNode._nodeID, nodes, true, false);
-            if (nodeCount == 0)
-            {
-                GP_ERROR("Failed to set property for nodes with id matching '%s'; no such nodes exist in the scene.", sceneNode._nodeID);
-                continue;
-            }
-            
-            for (unsigned int j = 0, pcount = sceneNode._properties.size(); j < pcount; ++j)
-            {
-                SceneNodeProperty& snp = sceneNode._properties[j];
-                if ((typeFlags & snp._type) == 0)
-                    continue;
 
 
-                for (unsigned int k = 0; k < nodeCount; ++k)
-                    applyNodeProperty(sceneNode, nodes[k], sceneProperties, snp, scene);
-            }
+        for (unsigned int j = 0, pcount = sceneNode._properties.size(); j < pcount; ++j)
+        {
+            SceneNodeProperty& snp = sceneNode._properties[j];
+            if (typeFlags & snp._type)
+                applyNodeProperty(sceneNode, node, sceneProperties, snp, scene);
         }
         }
     }
     }
 }
 }
@@ -200,30 +165,13 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
         snp._type == SceneNodeProperty::COLLISION_OBJECT)
         snp._type == SceneNodeProperty::COLLISION_OBJECT)
     {
     {
         // Check to make sure the referenced properties object was loaded properly.
         // Check to make sure the referenced properties object was loaded properly.
-        Properties* p = _propertiesFromFile[snp._file];
+        Properties* p = _properties[snp._url];
         if (!p)
         if (!p)
         {
         {
-            GP_ERROR("The referenced node data in file '%s' failed to load.", snp._file.c_str());
+            GP_ERROR("The referenced node data at url '%s' failed to load.", snp._url.c_str());
             return;
             return;
         }
         }
 
 
-        // If a specific namespace within the file was specified, load that namespace.
-        if (snp._id.size() > 0)
-        {
-            p = p->getNamespace(snp._id.c_str());
-            if (!p)
-            {
-                GP_ERROR("The referenced node data at '%s#%s' failed to load.", snp._file.c_str(), snp._id.c_str());
-                return;
-            }
-        }
-        else
-        {
-            // Otherwise, use the first namespace.
-            p->rewind();
-            p = p->getNextNamespace();
-        }
-
         switch (snp._type)
         switch (snp._type)
         {
         {
         case SceneNodeProperty::AUDIO:
         case SceneNodeProperty::AUDIO:
@@ -255,31 +203,6 @@ void SceneLoader::applyNodeProperty(SceneNode& sceneNode, Node* node, const Prop
         }
         }
         case SceneNodeProperty::COLLISION_OBJECT:
         case SceneNodeProperty::COLLISION_OBJECT:
         {
         {
-            // Check to make sure the referenced properties object was loaded properly.
-            Properties* p = _propertiesFromFile[snp._file];
-            if (!p)
-            {
-                GP_ERROR("The referenced node data in file '%s' failed to load.", snp._file.c_str());
-                return;
-            }
-
-            // If a specific namespace within the file was specified, load that namespace.
-            if (snp._id.size() > 0)
-            {
-                p = p->getNamespace(snp._id.c_str());
-                if (!p)
-                {
-                    GP_ERROR("The referenced node data at '%s#%s' failed to load.", snp._file.c_str(), snp._id.c_str());
-                    return;
-                }
-            }
-            else
-            {
-                // Otherwise, use the first namespace.
-                p->rewind();
-                p = p->getNextNamespace();
-            }
-
             // Check to make sure the type of the namespace used to load the physics collision object is correct.
             // Check to make sure the type of the namespace used to load the physics collision object is correct.
             if (snp._type == SceneNodeProperty::COLLISION_OBJECT && strcmp(p->getNamespace(), "collisionObject") != 0)
             if (snp._type == SceneNodeProperty::COLLISION_OBJECT && strcmp(p->getNamespace(), "collisionObject") != 0)
             {
             {
@@ -402,48 +325,24 @@ void SceneLoader::applyNodeUrls(Scene* scene)
             if (snp._type != SceneNodeProperty::URL)
             if (snp._type != SceneNodeProperty::URL)
                 continue;
                 continue;
 
 
-            if (snp._file.empty())
+            std::string file;
+            std::string id;
+            splitURL(snp._url, &file, &id);
+
+            if (file.empty())
             {
             {
                 // The node is from the main GPB and should just be renamed.
                 // The node is from the main GPB and should just be renamed.
 
 
                 // TODO: Should we do all nodes with this case first to allow users to stitch in nodes with
                 // TODO: Should we do all nodes with this case first to allow users to stitch in nodes with
                 // IDs equal to IDs that were in the original GPB file but were changed in the scene file?
                 // IDs equal to IDs that were in the original GPB file but were changed in the scene file?
-                if (sceneNode._exactMatch)
+                Node* node = scene->findNode(id.c_str());
+                if (node)
                 {
                 {
-                    Node* node = scene->findNode(snp._id.c_str());
-                    if (node)
-                    {
-                        node->setId(sceneNode._nodeID);
-                    }
-                    else
-                    {
-                        GP_ERROR("Could not find node '%s' in main scene GPB file.", snp._id.c_str());
-                    }
+                    node->setId(sceneNode._nodeID);
                 }
                 }
                 else
                 else
                 {
                 {
-                    // Search for nodes using a partial match
-                    std::string partialMatch = snp._id;
-                    std::vector<Node*> nodes;
-                    unsigned int nodeCount = scene->findNodes(snp._id.c_str(), nodes, true, false);
-                    if (nodeCount > 0)
-                    {
-                        GP_ASSERT(sceneNode._nodeID);
-
-                        for (unsigned int k = 0; k < nodeCount; ++k)
-                        {
-                            // Construct a new node ID using _nodeID plus the remainder of the partial match.
-                            Node* node = nodes[k];
-                            GP_ASSERT(node);
-                            std::string newID(sceneNode._nodeID);
-                            newID += (node->getId() + snp._id.length());
-                            node->setId(newID.c_str());
-                        }
-                    }
-                    else
-                    {
-                        GP_ERROR("Could not find any nodes matching '%s' in main scene GPB file.", snp._id.c_str());
-                    }
+                    GP_ERROR("Could not find node '%s' in main scene GPB file.", id.c_str());
                 }
                 }
             }
             }
             else
             else
@@ -453,60 +352,26 @@ void SceneLoader::applyNodeUrls(Scene* scene)
                 // TODO: Revisit this to determine if we should cache Bundle objects for the duration of the scene
                 // TODO: Revisit this to determine if we should cache Bundle objects for the duration of the scene
                 // load to prevent constantly creating/destroying the same externally referenced bundles each time
                 // load to prevent constantly creating/destroying the same externally referenced bundles each time
                 // a url with a file is encountered.
                 // a url with a file is encountered.
-                Bundle* tmpBundle = Bundle::create(snp._file.c_str());
+                Bundle* tmpBundle = Bundle::create(file.c_str());
                 if (tmpBundle)
                 if (tmpBundle)
                 {
                 {
-                    if (sceneNode._exactMatch)
+                    Node* node = tmpBundle->loadNode(id.c_str(), scene);
+                    if (node)
                     {
                     {
-                        Node* node = tmpBundle->loadNode(snp._id.c_str(), scene);
-                        if (node)
-                        {
-                            node->setId(sceneNode._nodeID);
-                            scene->addNode(node);
-                            SAFE_RELEASE(node);
-                        }
-                        else
-                        {
-                            GP_ERROR("Could not load node '%s' from GPB file '%s'.", snp._id.c_str(), snp._file.c_str());
-                        }
+                        node->setId(sceneNode._nodeID);
+                        scene->addNode(node);
+                        SAFE_RELEASE(node);
                     }
                     }
                     else
                     else
                     {
                     {
-                        // Search for nodes in the bundle using a partial match
-                        std::string partialMatch = snp._id;
-                        unsigned int objectCount = tmpBundle->getObjectCount();
-                        unsigned int matchCount = 0;
-                        for (unsigned int k = 0; k < objectCount; ++k)
-                        {
-                            const char* objid = tmpBundle->getObjectID(k);
-                            if (strstr(objid, snp._id.c_str()) == objid)
-                            {
-                                // This object ID matches (starts with).
-                                // Try to load this object as a Node.
-                                Node* node = tmpBundle->loadNode(objid);
-                                if (node)
-                                {
-                                    // Construct a new node ID using _nodeID plus the remainder of the partial match.
-                                    std::string newID(sceneNode._nodeID);
-                                    newID += (node->getId() + snp._id.length());
-                                    node->setId(newID.c_str());
-                                    scene->addNode(node);
-                                    SAFE_RELEASE(node);
-                                    matchCount++;
-                                }
-                            }
-                        }
-                        if (matchCount == 0)
-                        {
-                            GP_ERROR("Could not find any nodes matching '%s' in GPB file '%s'.", snp._id.c_str(), snp._file.c_str());
-                        }
+                        GP_ERROR("Could not load node '%s' from GPB file '%s'.", id.c_str(), file.c_str());
                     }
                     }
 
 
                     SAFE_RELEASE(tmpBundle);
                     SAFE_RELEASE(tmpBundle);
                 }
                 }
                 else
                 else
                 {
                 {
-                    GP_ERROR("Failed to load GPB file '%s' for node stitching.", snp._file.c_str());
+                    GP_ERROR("Failed to load GPB file '%s' for node stitching.", file.c_str());
                 }
                 }
             }
             }
 
 
@@ -536,6 +401,42 @@ void SceneLoader::buildReferenceTables(Properties* sceneProperties)
             SceneNode& sceneNode = _sceneNodes[_sceneNodes.size()-1];
             SceneNode& sceneNode = _sceneNodes[_sceneNodes.size()-1];
             sceneNode._nodeID = ns->getId();
             sceneNode._nodeID = ns->getId();
 
 
+            // Parse the node's sub-namespaces.
+            Properties* subns;
+            std::string propertyUrl = _path + "#" + ns->getId() + "/";
+            while ((subns = ns->getNextNamespace()) != NULL)
+            {
+                if (strcmp(subns->getNamespace(), "audio") == 0)
+                {
+                    propertyUrl += "audio/" + std::string(subns->getId());
+                    addSceneNodeProperty(sceneNode, SceneNodeProperty::AUDIO, propertyUrl.c_str());
+                    _properties[propertyUrl] = subns;
+                }
+                else if (strcmp(subns->getNamespace(), "material") == 0)
+                {
+                    propertyUrl += "material/" + std::string(subns->getId());
+                    addSceneNodeProperty(sceneNode, SceneNodeProperty::MATERIAL, propertyUrl.c_str());
+                    _properties[propertyUrl] = subns;
+                }
+                else if (strcmp(subns->getNamespace(), "particle") == 0)
+                {
+                    propertyUrl += "particle/" + std::string(subns->getId());
+                    addSceneNodeProperty(sceneNode, SceneNodeProperty::PARTICLE, propertyUrl.c_str());
+                    _properties[propertyUrl] = subns;
+                }
+                else if (strcmp(subns->getNamespace(), "collisionObject") == 0)
+                {
+                    propertyUrl += "collisionObject/" + std::string(subns->getId());
+                    addSceneNodeProperty(sceneNode, SceneNodeProperty::COLLISION_OBJECT, propertyUrl.c_str());
+                    _properties[propertyUrl] = subns;
+                }
+                else
+                {
+                    GP_ERROR("Unsupported child namespace '%s' of 'node' namespace.", subns->getNamespace());
+                }
+            }
+
+            // Parse the node's attributes.
             while ((name = ns->getNextProperty()) != NULL)
             while ((name = ns->getNextProperty()) != NULL)
             {
             {
                 if (strcmp(name, "url") == 0)
                 if (strcmp(name, "url") == 0)
@@ -660,21 +561,12 @@ void SceneLoader::createAnimations(const Scene* scene)
         }
         }
 
 
         // Check to make sure the referenced properties object was loaded properly.
         // Check to make sure the referenced properties object was loaded properly.
-        Properties* p = _propertiesFromFile[_animations[i]._file];
+        Properties* p = _properties[_animations[i]._url];
         if (!p)
         if (!p)
         {
         {
-            GP_ERROR("The referenced animation data in file '%s' failed to load.", _animations[i]._file.c_str());
+            GP_ERROR("The referenced animation data at url '%s' failed to load.", _animations[i]._url.c_str());
             continue;
             continue;
         }
         }
-        if (_animations[i]._id.size() > 0)
-        {
-            p = p->getNamespace(_animations[i]._id.c_str());
-            if (!p)
-            {
-                GP_ERROR("The referenced animation data at '%s#%s' failed to load.", _animations[i]._file.c_str(), _animations[i]._id.c_str());
-                continue;
-            }
-        }
 
 
         node->createAnimation(_animations[i]._animationID, p);
         node->createAnimation(_animations[i]._animationID, p);
     }
     }
@@ -789,10 +681,10 @@ Scene* SceneLoader::loadMainSceneData(const Properties* sceneProperties)
     GP_ASSERT(sceneProperties);
     GP_ASSERT(sceneProperties);
 
 
     // Load the main scene from the specified path.
     // Load the main scene from the specified path.
-    Bundle* bundle = Bundle::create(_path.c_str());
+    Bundle* bundle = Bundle::create(_gpbPath.c_str());
     if (!bundle)
     if (!bundle)
     {
     {
-        GP_ERROR("Failed to load scene GPB file '%s'.", _path.c_str());
+        GP_ERROR("Failed to load scene GPB file '%s'.", _gpbPath.c_str());
         return NULL;
         return NULL;
     }
     }
 
 
@@ -800,7 +692,7 @@ Scene* SceneLoader::loadMainSceneData(const Properties* sceneProperties)
     Scene* scene = bundle->loadScene(NULL);
     Scene* scene = bundle->loadScene(NULL);
     if (!scene)
     if (!scene)
     {
     {
-        GP_ERROR("Failed to load scene from '%s'.", _path.c_str());
+        GP_ERROR("Failed to load scene from '%s'.", _gpbPath.c_str());
         SAFE_RELEASE(bundle);
         SAFE_RELEASE(bundle);
         return NULL;
         return NULL;
     }
     }
@@ -930,14 +822,17 @@ void SceneLoader::loadPhysics(Properties* physics, Scene* scene)
 void SceneLoader::loadReferencedFiles()
 void SceneLoader::loadReferencedFiles()
 {
 {
     // Load all referenced properties files.
     // Load all referenced properties files.
-    std::map<std::string, Properties*>::iterator iter = _propertiesFromFile.begin();
-    for (; iter != _propertiesFromFile.end(); iter++)
+    std::map<std::string, Properties*>::iterator iter = _properties.begin();
+    for (; iter != _properties.end(); iter++)
     {
     {
-        Properties* p = Properties::create(iter->first.c_str());
-        if (p == NULL)
-            GP_ERROR("Failed to load referenced file '%s'.", iter->first.c_str());
+        if (iter->second == NULL)
+        {
+            Properties* p = Properties::create(iter->first.c_str());
+            if (p == NULL)
+                GP_ERROR("Failed to load referenced file '%s'.", iter->first.c_str());
 
 
-        iter->second = p;
+            iter->second = p;
+        }
     }
     }
 }
 }
 
 
@@ -1043,28 +938,26 @@ PhysicsConstraint* SceneLoader::loadSpringConstraint(const Properties* constrain
     return physicsConstraint;
     return physicsConstraint;
 }
 }
 
 
-void SceneLoader::splitURL(const char* url, std::string* file, std::string* id)
+void SceneLoader::splitURL(const std::string& url, std::string* file, std::string* id)
 {
 {
-    if (!url)
+    if (url.empty())
     {
     {
         // This is allowed since many scene node properties do not use the URL.
         // This is allowed since many scene node properties do not use the URL.
         return;
         return;
     }
     }
 
 
-    std::string urlString = url;
-
     // Check if the url references a file (otherwise, it only references a node within the main GPB).
     // Check if the url references a file (otherwise, it only references a node within the main GPB).
-    unsigned int loc = urlString.rfind(".");
-    if (loc != urlString.npos)
+    unsigned int loc = url.rfind(".");
+    if (loc != url.npos)
     {
     {
         // If the url references a specific namespace within the file,
         // If the url references a specific namespace within the file,
         // set the id out parameter appropriately. Otherwise, set the id out
         // set the id out parameter appropriately. Otherwise, set the id out
         // parameter to the empty string so we know to load the first namespace.
         // parameter to the empty string so we know to load the first namespace.
-        loc = urlString.rfind("#");
-        if (loc != urlString.npos)
+        loc = url.rfind("#");
+        if (loc != url.npos)
         {
         {
-            *file = urlString.substr(0, loc);
-            *id = urlString.substr(loc + 1);
+            *file = url.substr(0, loc);
+            *id = url.substr(loc + 1);
         }
         }
         else
         else
         {
         {

+ 10 - 12
gameplay/src/SceneLoader.h

@@ -33,13 +33,12 @@ private:
      */
      */
     struct SceneAnimation
     struct SceneAnimation
     {
     {
-        SceneAnimation(const char* animationID, const char* targetID, std::string file, std::string id)
-            : _animationID(animationID), _targetID(targetID), _file(file), _id(id) {}
+        SceneAnimation(const char* animationID, const char* targetID, std::string url)
+            : _animationID(animationID), _targetID(targetID), _url(url) {}
 
 
         const char* _animationID;
         const char* _animationID;
         const char* _targetID;
         const char* _targetID;
-        std::string _file;
-        std::string _id;
+        std::string _url;
     };
     };
 
 
     struct SceneNodeProperty
     struct SceneNodeProperty
@@ -58,20 +57,18 @@ private:
             DYNAMIC = 512
             DYNAMIC = 512
         };
         };
 
 
-        SceneNodeProperty(Type type, std::string file, std::string id, int index) : _type(type), _file(file), _id(id), _index(index) { }
+        SceneNodeProperty(Type type, std::string url, int index) : _type(type), _url(url), _index(index) { }
 
 
         Type _type;
         Type _type;
-        std::string _file;
-        std::string _id;
+        std::string _url;
         int _index;
         int _index;
     };
     };
 
 
     struct SceneNode
     struct SceneNode
     {
     {
-        SceneNode() : _nodeID(""), _exactMatch(true) { }
+        SceneNode() : _nodeID("") { }
 
 
         const char* _nodeID;
         const char* _nodeID;
-        bool _exactMatch;
         std::vector<SceneNodeProperty> _properties;
         std::vector<SceneNodeProperty> _properties;
     };
     };
 
 
@@ -105,13 +102,14 @@ private:
 
 
     static PhysicsConstraint* loadSpringConstraint(const Properties* constraint, PhysicsRigidBody* rbA, PhysicsRigidBody* rbB);
     static PhysicsConstraint* loadSpringConstraint(const Properties* constraint, PhysicsRigidBody* rbA, PhysicsRigidBody* rbB);
 
 
-    static void splitURL(const char* url, std::string* file, std::string* id);
+    static void splitURL(const std::string& url, std::string* file, std::string* id);
     
     
     
     
-    static std::map<std::string, Properties*> _propertiesFromFile;      // Holds the properties object for a given file path.
+    static std::map<std::string, Properties*> _properties;              // Holds the properties object for a given URL.
     static std::vector<SceneAnimation> _animations;                     // Holds the animations declared in the .scene file.
     static std::vector<SceneAnimation> _animations;                     // Holds the animations declared in the .scene file.
     static std::vector<SceneNode> _sceneNodes;                          // Holds all the nodes+properties declared in the .scene file.
     static std::vector<SceneNode> _sceneNodes;                          // Holds all the nodes+properties declared in the .scene file.
-    static std::string _path;                                           // The path of the main GPB for the scene being loaded.
+    static std::string _gpbPath;                                        // The path of the main GPB for the scene being loaded.
+    static std::string _path;                                           // The path of the scene file being loaded.
 };
 };
 
 
 }
 }