Browse Source

Object factory and submesh deltas

Josh Engebretson 9 years ago
parent
commit
67f275f159

+ 4 - 2
Source/Atomic/Core/Context.cpp

@@ -87,14 +87,16 @@ Context::~Context()
     eventDataMaps_.Clear();
     eventDataMaps_.Clear();
 }
 }
 
 
-SharedPtr<Object> Context::CreateObject(StringHash objectType)
+// ATOMIC BEGIN
+SharedPtr<Object> Context::CreateObject(StringHash objectType, const XMLElement& source)
 {
 {
     HashMap<StringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories_.Find(objectType);
     HashMap<StringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories_.Find(objectType);
     if (i != factories_.End())
     if (i != factories_.End())
-        return i->second_->CreateObject();
+        return i->second_->CreateObject(source);
     else
     else
         return SharedPtr<Object>();
         return SharedPtr<Object>();
 }
 }
+// ATOMIC END
 
 
 void Context::RegisterFactory(ObjectFactory* factory)
 void Context::RegisterFactory(ObjectFactory* factory)
 {
 {

+ 6 - 1
Source/Atomic/Core/Context.h

@@ -58,8 +58,13 @@ public:
     {
     {
         return StaticCast<T>(CreateObject(T::GetTypeStatic()));
         return StaticCast<T>(CreateObject(T::GetTypeStatic()));
     }
     }
+
+    // ATOMIC BEGIN
     /// Create an object by type hash. Return pointer to it or null if no factory found.
     /// Create an object by type hash. Return pointer to it or null if no factory found.
-    SharedPtr<Object> CreateObject(StringHash objectType);
+    SharedPtr<Object> CreateObject(StringHash objectType, const XMLElement &source = XMLElement::EMPTY);
+    // ATOMIC END
+
+
     /// Register a factory for an object type.
     /// Register a factory for an object type.
     void RegisterFactory(ObjectFactory* factory);
     void RegisterFactory(ObjectFactory* factory);
     /// Register a factory for an object type and specify the object category.
     /// Register a factory for an object type and specify the object category.

+ 11 - 2
Source/Atomic/Core/Object.h

@@ -24,6 +24,11 @@
 
 
 #include "../Container/LinkedList.h"
 #include "../Container/LinkedList.h"
 #include "../Core/Variant.h"
 #include "../Core/Variant.h"
+
+// ATOMIC BEGIN
+#include "../Resource/XMLElement.h"
+// ATOMIC END
+
 #if ATOMIC_CXX11
 #if ATOMIC_CXX11
 #include <functional>
 #include <functional>
 #endif
 #endif
@@ -220,8 +225,10 @@ public:
         assert(context_);
         assert(context_);
     }
     }
 
 
+// ATOMIC BEGIN
     /// Create an object. Implemented in templated subclasses.
     /// Create an object. Implemented in templated subclasses.
-    virtual SharedPtr<Object> CreateObject() = 0;
+    virtual SharedPtr<Object> CreateObject(const XMLElement& source = XMLElement::EMPTY) = 0;
+// ATOMIC END
 
 
     /// Return execution context.
     /// Return execution context.
     Context* GetContext() const { return context_; }
     Context* GetContext() const { return context_; }
@@ -253,8 +260,10 @@ public:
         typeInfo_ = T::GetTypeInfoStatic();
         typeInfo_ = T::GetTypeInfoStatic();
     }
     }
 
 
+    // ATOMIC BEGIN
     /// Create an object of the specific type.
     /// Create an object of the specific type.
-    virtual SharedPtr<Object> CreateObject() { return SharedPtr<Object>(new T(context_)); }
+    virtual SharedPtr<Object> CreateObject(const XMLElement& source = XMLElement::EMPTY) { return SharedPtr<Object>(new T(context_)); }
+    // ATOMIC END
 };
 };
 
 
 /// Internal helper class for invoking event handler functions.
 /// Internal helper class for invoking event handler functions.

+ 61 - 3
Source/Atomic/Graphics/Model.cpp

@@ -74,14 +74,26 @@ void Model::RegisterObject(Context* context)
 bool Model::BeginLoad(Deserializer& source)
 bool Model::BeginLoad(Deserializer& source)
 {
 {
     // Check ID
     // Check ID
+
     String fileID = source.ReadFileID();
     String fileID = source.ReadFileID();
-    if (fileID != "UMDL" && fileID != "UMD2")
+
+// ATOMIC BEGIN
+
+    bool umdl = false;
+    if (fileID == "UMDL" || fileID == "UMD2")
+        umdl = true;
+
+    if (!umdl && fileID != "AMDL" && fileID != "AMD2")
     {
     {
         ATOMIC_LOGERROR(source.GetName() + " is not a valid model file");
         ATOMIC_LOGERROR(source.GetName() + " is not a valid model file");
         return false;
         return false;
     }
     }
 
 
-    bool hasVertexDeclarations = (fileID == "UMD2");
+    bool hasVertexDeclarations = (fileID == "UMD2" || fileID == "AMD2");
+
+    geometryNames_.Clear();
+
+// ATOMIC END
 
 
     geometries_.Clear();
     geometries_.Clear();
     geometryBoneMappings_.Clear();
     geometryBoneMappings_.Clear();
@@ -306,7 +318,26 @@ bool Model::BeginLoad(Deserializer& source)
         geometryCenters_.Push(Vector3::ZERO);
         geometryCenters_.Push(Vector3::ZERO);
     memoryUse += sizeof(Vector3) * geometries_.Size();
     memoryUse += sizeof(Vector3) * geometries_.Size();
 
 
+// ATOMIC BEGIN
+    if (umdl)
+    {
+        SetMemoryUse(memoryUse);
+        return true;
+    }
+
+    // MODEL_VERSION
+    unsigned version = source.ReadUInt();
+
+    // Read geometry names
+    geometryNames_.Resize(geometries_.Size());
+    for (unsigned i = 0; i < geometries_.Size(); ++i)
+    {
+        geometryNames_[i] = source.ReadString();
+    }
+
     SetMemoryUse(memoryUse);
     SetMemoryUse(memoryUse);
+
+// ATOMIC END
     return true;
     return true;
 }
 }
 
 
@@ -359,10 +390,14 @@ bool Model::EndLoad()
 
 
 bool Model::Save(Serializer& dest) const
 bool Model::Save(Serializer& dest) const
 {
 {
+    // ATOMIC BEGIN
+
     // Write ID
     // Write ID
-    if (!dest.WriteFileID("UMD2"))
+    if (!dest.WriteFileID("AMD2"))
         return false;
         return false;
 
 
+    // ATOMIC END
+
     // Write vertex buffers
     // Write vertex buffers
     dest.WriteUInt(vertexBuffers_.Size());
     dest.WriteUInt(vertexBuffers_.Size());
     for (unsigned i = 0; i < vertexBuffers_.Size(); ++i)
     for (unsigned i = 0; i < vertexBuffers_.Size(); ++i)
@@ -453,6 +488,16 @@ bool Model::Save(Serializer& dest) const
     for (unsigned i = 0; i < geometryCenters_.Size(); ++i)
     for (unsigned i = 0; i < geometryCenters_.Size(); ++i)
         dest.WriteVector3(geometryCenters_[i]);
         dest.WriteVector3(geometryCenters_[i]);
 
 
+    // ATOMIC BEGIN
+
+    dest.WriteUInt(MODEL_VERSION);
+
+    // Write geometry names
+    for (unsigned i = 0; i < geometryNames_.Size(); ++i)
+        dest.WriteString(geometryNames_[i]);
+
+    // ATOMIC END
+
     return true;
     return true;
 }
 }
 
 
@@ -518,6 +563,10 @@ void Model::SetNumGeometries(unsigned num)
     geometryBoneMappings_.Resize(num);
     geometryBoneMappings_.Resize(num);
     geometryCenters_.Resize(num);
     geometryCenters_.Resize(num);
 
 
+    // ATOMIC BEGIN
+    geometryNames_.Resize(num);
+    // ATOMIC END
+
     // For easier creation of from-scratch geometry, ensure that all geometries start with at least 1 LOD level (0 makes no sense)
     // For easier creation of from-scratch geometry, ensure that all geometries start with at least 1 LOD level (0 makes no sense)
     for (unsigned i = 0; i < geometries_.Size(); ++i)
     for (unsigned i = 0; i < geometries_.Size(); ++i)
     {
     {
@@ -656,6 +705,11 @@ SharedPtr<Model> Model::Clone(const String& cloneName) const
         ret->indexBuffers_.Push(cloneBuffer);
         ret->indexBuffers_.Push(cloneBuffer);
     }
     }
 
 
+
+    // ATOMIC BEGIN
+    ret->geometryNames_.Resize(geometryNames_.Size());
+    // ATOMIC END
+
     // Deep copy all the geometry LOD levels and refer to the copied vertex/index buffers
     // Deep copy all the geometry LOD levels and refer to the copied vertex/index buffers
     ret->geometries_.Resize(geometries_.Size());
     ret->geometries_.Resize(geometries_.Size());
     for (unsigned i = 0; i < geometries_.Size(); ++i)
     for (unsigned i = 0; i < geometries_.Size(); ++i)
@@ -663,6 +717,10 @@ SharedPtr<Model> Model::Clone(const String& cloneName) const
         ret->geometries_[i].Resize(geometries_[i].Size());
         ret->geometries_[i].Resize(geometries_[i].Size());
         for (unsigned j = 0; j < geometries_[i].Size(); ++j)
         for (unsigned j = 0; j < geometries_[i].Size(); ++j)
         {
         {
+            // ATOMIC BEGIN
+            ret->geometryNames_[i] = geometryNames_[i];
+            // ATOMIC END
+
             SharedPtr<Geometry> cloneGeometry;
             SharedPtr<Geometry> cloneGeometry;
             Geometry* origGeometry = geometries_[i][j];
             Geometry* origGeometry = geometries_[i][j];
 
 

+ 6 - 0
Source/Atomic/Graphics/Model.h

@@ -104,6 +104,12 @@ struct GeometryDesc
     unsigned indexCount_;
     unsigned indexCount_;
 };
 };
 
 
+// ATOMIC BEGIN
+
+static const unsigned MODEL_VERSION = 1;
+
+// ATOMIC END
+
 /// 3D model resource.
 /// 3D model resource.
 class ATOMIC_API Model : public Resource
 class ATOMIC_API Model : public Resource
 {
 {

+ 20 - 5
Source/Atomic/Scene/Node.cpp

@@ -898,7 +898,8 @@ void Node::RemoveChildren(bool removeReplicated, bool removeLocal, bool recursiv
         MarkReplicationDirty();
         MarkReplicationDirty();
 }
 }
 
 
-Component* Node::CreateComponent(StringHash type, CreateMode mode, unsigned id)
+// ATOMIC BEGIN
+Component* Node::CreateComponentInternal(StringHash type, CreateMode mode, unsigned id, const XMLElement& source)
 {
 {
     // Do not attempt to create replicated components to local nodes, as that may lead to component ID overwrite
     // Do not attempt to create replicated components to local nodes, as that may lead to component ID overwrite
     // as replicated components are synced over
     // as replicated components are synced over
@@ -906,7 +907,7 @@ Component* Node::CreateComponent(StringHash type, CreateMode mode, unsigned id)
         mode = LOCAL;
         mode = LOCAL;
 
 
     // Check that creation succeeds and that the object in fact is a component
     // Check that creation succeeds and that the object in fact is a component
-    SharedPtr<Component> newComponent = DynamicCast<Component>(context_->CreateObject(type));
+    SharedPtr<Component> newComponent = DynamicCast<Component>(context_->CreateObject(type, source));
     if (!newComponent)
     if (!newComponent)
     {
     {
         ATOMIC_LOGERROR("Could not create unknown component type " + type.ToString());
         ATOMIC_LOGERROR("Could not create unknown component type " + type.ToString());
@@ -915,8 +916,16 @@ Component* Node::CreateComponent(StringHash type, CreateMode mode, unsigned id)
 
 
     AddComponent(newComponent, id, mode);
     AddComponent(newComponent, id, mode);
     return newComponent;
     return newComponent;
+
 }
 }
 
 
+Component* Node::CreateComponent(StringHash type, CreateMode mode, unsigned id)
+{
+    return CreateComponentInternal(type, mode, id);
+}
+
+// ATOMIC END
+
 Component* Node::GetOrCreateComponent(StringHash type, CreateMode mode, unsigned id)
 Component* Node::GetOrCreateComponent(StringHash type, CreateMode mode, unsigned id)
 {
 {
     Component* oldComponent = GetComponent(type);
     Component* oldComponent = GetComponent(type);
@@ -1553,8 +1562,10 @@ bool Node::LoadXML(const XMLElement& source, SceneResolver& resolver, bool readC
     {
     {
         String typeName = compElem.GetAttribute("type");
         String typeName = compElem.GetAttribute("type");
         unsigned compID = compElem.GetUInt("id");
         unsigned compID = compElem.GetUInt("id");
+// ATOMIC BEGIN
         Component* newComponent = SafeCreateComponent(typeName, StringHash(typeName),
         Component* newComponent = SafeCreateComponent(typeName, StringHash(typeName),
-            (mode == REPLICATED && compID < FIRST_LOCAL_ID) ? REPLICATED : LOCAL, rewriteIDs ? 0 : compID);
+            (mode == REPLICATED && compID < FIRST_LOCAL_ID) ? REPLICATED : LOCAL, rewriteIDs ? 0 : compID, compElem);
+// ATOMIC END
         if (newComponent)
         if (newComponent)
         {
         {
             resolver.AddComponent(compID, newComponent);
             resolver.AddComponent(compID, newComponent);
@@ -2005,7 +2016,9 @@ void Node::SetEnabled(bool enable, bool recursive, bool storeSelf)
     }
     }
 }
 }
 
 
-Component* Node::SafeCreateComponent(const String& typeName, StringHash type, CreateMode mode, unsigned id)
+// ATOMIC BEGIN
+
+Component* Node::SafeCreateComponent(const String& typeName, StringHash type, CreateMode mode, unsigned id, const XMLElement& source)
 {
 {
     // Do not attempt to create replicated components to local nodes, as that may lead to component ID overwrite
     // Do not attempt to create replicated components to local nodes, as that may lead to component ID overwrite
     // as replicated components are synced over
     // as replicated components are synced over
@@ -2014,7 +2027,7 @@ Component* Node::SafeCreateComponent(const String& typeName, StringHash type, Cr
 
 
     // First check if factory for type exists
     // First check if factory for type exists
     if (!context_->GetTypeName(type).Empty())
     if (!context_->GetTypeName(type).Empty())
-        return CreateComponent(type, mode, id);
+        return CreateComponentInternal(type, mode, id, source);
     else
     else
     {
     {
         ATOMIC_LOGWARNING("Component type " + type.ToString() + " not known, creating UnknownComponent as placeholder");
         ATOMIC_LOGWARNING("Component type " + type.ToString() + " not known, creating UnknownComponent as placeholder");
@@ -2030,6 +2043,8 @@ Component* Node::SafeCreateComponent(const String& typeName, StringHash type, Cr
     }
     }
 }
 }
 
 
+// ATOMIC END
+
 void Node::UpdateWorldTransform() const
 void Node::UpdateWorldTransform() const
 {
 {
     Matrix3x4 transform = GetTransform();
     Matrix3x4 transform = GetTransform();

+ 7 - 1
Source/Atomic/Scene/Node.h

@@ -620,8 +620,12 @@ protected:
 private:
 private:
     /// Set enabled/disabled state with optional recursion. Optionally affect the remembered enable state.
     /// Set enabled/disabled state with optional recursion. Optionally affect the remembered enable state.
     void SetEnabled(bool enable, bool recursive, bool storeSelf);
     void SetEnabled(bool enable, bool recursive, bool storeSelf);
+
+// ATOMIC BEGIN
     /// Create component, allowing UnknownComponent if actual type is not supported. Leave typeName empty if not known.
     /// Create component, allowing UnknownComponent if actual type is not supported. Leave typeName empty if not known.
-    Component* SafeCreateComponent(const String& typeName, StringHash type, CreateMode mode, unsigned id);
+    Component* SafeCreateComponent(const String& typeName, StringHash type, CreateMode mode, unsigned id, const XMLElement& source = XMLElement::EMPTY);
+// ATOMIC END
+
     /// Recalculate the world transform.
     /// Recalculate the world transform.
     void UpdateWorldTransform() const;
     void UpdateWorldTransform() const;
     /// Remove child node by iterator.
     /// Remove child node by iterator.
@@ -687,6 +691,8 @@ private:
     /// Return child nodes by name, recursively
     /// Return child nodes by name, recursively
     void GetChildrenWithNameRecursive(PODVector<Node*>& dest, StringHash nameHash) const;
     void GetChildrenWithNameRecursive(PODVector<Node*>& dest, StringHash nameHash) const;
 
 
+    Component* CreateComponentInternal(StringHash type, CreateMode mode, unsigned id, const XMLElement& source = XMLElement::EMPTY);
+
     // ATOMIC END
     // ATOMIC END
 };
 };
 
 

+ 1 - 1
Source/AtomicJS/Javascript/JSComponent.cpp

@@ -138,7 +138,7 @@ JSComponent::~JSComponent()
 
 
 void JSComponent::RegisterObject(Context* context)
 void JSComponent::RegisterObject(Context* context)
 {
 {
-    context->RegisterFactory<JSComponent>(LOGIC_CATEGORY);
+    context->RegisterFactory( new JSComponentFactory(context), LOGIC_CATEGORY);
     ATOMIC_MIXED_ACCESSOR_ATTRIBUTE("ComponentFile", GetComponentFileAttr, SetComponentFileAttr, ResourceRef, ResourceRef(JSComponentFile::GetTypeStatic()), AM_DEFAULT);
     ATOMIC_MIXED_ACCESSOR_ATTRIBUTE("ComponentFile", GetComponentFileAttr, SetComponentFileAttr, ResourceRef, ResourceRef(JSComponentFile::GetTypeStatic()), AM_DEFAULT);
     ATOMIC_COPY_BASE_ATTRIBUTES(ScriptComponent);
     ATOMIC_COPY_BASE_ATTRIBUTES(ScriptComponent);
 }
 }