Browse Source

Further attribute reorganization.
Refactored CollisionShape shape setting functions, which now take default parameters.
CollisionShape triangle meshes can now use the size attribute as well.
Fixed CollisionShape model not changing when picked with the file selector.
Added occluder triangles & instancing parameters to the editor settings dialog.

Lasse Öörni 14 years ago
parent
commit
6dd8679214

+ 6 - 0
Bin/Data/Scripts/Editor.as

@@ -99,7 +99,10 @@ void LoadConfig()
         renderer.textureQuality = renderingElem.GetInt("texturequality");
         renderer.textureQuality = renderingElem.GetInt("texturequality");
         renderer.materialQuality = renderingElem.GetInt("materialquality");
         renderer.materialQuality = renderingElem.GetInt("materialquality");
         SetShadowQuality(renderingElem.GetInt("shadowquality"));
         SetShadowQuality(renderingElem.GetInt("shadowquality"));
+        renderer.maxOccluderTriangles = renderingElem.GetInt("maxoccludertriangles");
         renderer.specularLighting = renderingElem.GetBool("specularlighting");
         renderer.specularLighting = renderingElem.GetBool("specularlighting");
+        renderer.dynamicInstancing = renderingElem.GetBool("dynamicinstancing");
+        renderer.shadowMapHiresDepth = renderingElem.GetBool("shadowmaphiresdepth");
         engine.maxFps = renderingElem.GetBool("framelimiter") ? 200 : 0;
         engine.maxFps = renderingElem.GetBool("framelimiter") ? 200 : 0;
     }
     }
 }
 }
@@ -134,7 +137,10 @@ void SaveConfig()
     renderingElem.SetInt("texturequality", renderer.textureQuality);
     renderingElem.SetInt("texturequality", renderer.textureQuality);
     renderingElem.SetInt("materialquality", renderer.materialQuality);
     renderingElem.SetInt("materialquality", renderer.materialQuality);
     renderingElem.SetInt("shadowquality", GetShadowQuality());
     renderingElem.SetInt("shadowquality", GetShadowQuality());
+    renderingElem.SetInt("maxoccludertriangles", renderer.maxOccluderTriangles);
     renderingElem.SetBool("specularlighting", renderer.specularLighting);
     renderingElem.SetBool("specularlighting", renderer.specularLighting);
+    renderingElem.SetBool("dynamicinstancing", renderer.dynamicInstancing);
+    renderingElem.SetBool("shadowmaphiresdepth", renderer.shadowMapHiresDepth);
     renderingElem.SetBool("framelimiter", engine.maxFps > 0);
     renderingElem.SetBool("framelimiter", engine.maxFps > 0);
 
 
     config.Save(File(configFileName, FILE_WRITE));
     config.Save(File(configFileName, FILE_WRITE));

+ 29 - 6
Bin/Data/Scripts/Editor/EditorCamera.as

@@ -117,13 +117,19 @@ void UpdateEditorSettingsDialog()
 
 
     DropDownList@ shadowQualityEdit = editorSettingsDialog.GetChild("ShadowQualityEdit", true);
     DropDownList@ shadowQualityEdit = editorSettingsDialog.GetChild("ShadowQualityEdit", true);
     shadowQualityEdit.selection = GetShadowQuality();
     shadowQualityEdit.selection = GetShadowQuality();
-    
-    CheckBox@ shadowMapHiresDepthToggle = editorSettingsDialog.GetChild("ShadowMapHiresDepthToggle", true);
-    shadowMapHiresDepthToggle.checked = renderer.shadowMapHiresDepth;
+
+    LineEdit@ maxOccluderTrianglesEdit = editorSettingsDialog.GetChild("MaxOccluderTrianglesEdit", true);
+    maxOccluderTrianglesEdit.text = String(renderer.maxOccluderTriangles);
 
 
     CheckBox@ specularLightingToggle = editorSettingsDialog.GetChild("SpecularLightingToggle", true);
     CheckBox@ specularLightingToggle = editorSettingsDialog.GetChild("SpecularLightingToggle", true);
     specularLightingToggle.checked = renderer.specularLighting;
     specularLightingToggle.checked = renderer.specularLighting;
 
 
+    CheckBox@ dynamicInstancingToggle = editorSettingsDialog.GetChild("DynamicInstancingToggle", true);
+    dynamicInstancingToggle.checked = renderer.dynamicInstancing;
+
+    CheckBox@ shadowMapHiresDepthToggle = editorSettingsDialog.GetChild("ShadowMapHiresDepthToggle", true);
+    shadowMapHiresDepthToggle.checked = renderer.shadowMapHiresDepth;
+
     CheckBox@ frameLimiterToggle = editorSettingsDialog.GetChild("FrameLimiterToggle", true);
     CheckBox@ frameLimiterToggle = editorSettingsDialog.GetChild("FrameLimiterToggle", true);
     frameLimiterToggle.checked = engine.maxFps > 0;
     frameLimiterToggle.checked = engine.maxFps > 0;
 
 
@@ -154,8 +160,11 @@ void UpdateEditorSettingsDialog()
         SubscribeToEvent(textureQualityEdit, "ItemSelected", "EditTextureQuality");
         SubscribeToEvent(textureQualityEdit, "ItemSelected", "EditTextureQuality");
         SubscribeToEvent(materialQualityEdit, "ItemSelected", "EditMaterialQuality");
         SubscribeToEvent(materialQualityEdit, "ItemSelected", "EditMaterialQuality");
         SubscribeToEvent(shadowQualityEdit, "ItemSelected", "EditShadowQuality");
         SubscribeToEvent(shadowQualityEdit, "ItemSelected", "EditShadowQuality");
-        SubscribeToEvent(shadowMapHiresDepthToggle, "Toggled", "EditShadowMapHiresDepth");
+        SubscribeToEvent(maxOccluderTrianglesEdit, "TextChanged", "EditMaxOccluderTriangles");
+        SubscribeToEvent(maxOccluderTrianglesEdit, "TextFinished", "EditMaxOccluderTriangles");
         SubscribeToEvent(specularLightingToggle, "Toggled", "EditSpecularLighting");
         SubscribeToEvent(specularLightingToggle, "Toggled", "EditSpecularLighting");
+        SubscribeToEvent(dynamicInstancingToggle, "Toggled", "EditDynamicInstancing");
+        SubscribeToEvent(shadowMapHiresDepthToggle, "Toggled", "EditShadowMapHiresDepth");
         SubscribeToEvent(frameLimiterToggle, "Toggled", "EditFrameLimiter");
         SubscribeToEvent(frameLimiterToggle, "Toggled", "EditFrameLimiter");
         SubscribeToEvent(editorSettingsDialog.GetChild("CloseButton", true), "Released", "HideEditorSettingsDialog");
         SubscribeToEvent(editorSettingsDialog.GetChild("CloseButton", true), "Released", "HideEditorSettingsDialog");
         subscribedToCameraEdits = true;
         subscribedToCameraEdits = true;
@@ -292,16 +301,30 @@ void EditShadowQuality(StringHash eventType, VariantMap& eventData)
     SetShadowQuality(edit.selection);
     SetShadowQuality(edit.selection);
 }
 }
 
 
+void EditMaxOccluderTriangles(StringHash eventType, VariantMap& eventData)
+{
+    LineEdit@ edit = eventData["Element"].GetUIElement();
+    renderer.maxOccluderTriangles = edit.text.ToInt();
+    if (eventType == StringHash("TextFinished"))
+        edit.text = String(renderer.maxOccluderTriangles);
+}
+
+void EditSpecularLighting(StringHash eventType, VariantMap& eventData)
+{
+    CheckBox@ edit = eventData["Element"].GetUIElement();
+    renderer.specularLighting = edit.checked;
+}
+
 void EditShadowMapHiresDepth(StringHash eventType, VariantMap& eventData)
 void EditShadowMapHiresDepth(StringHash eventType, VariantMap& eventData)
 {
 {
     CheckBox@ edit = eventData["Element"].GetUIElement();
     CheckBox@ edit = eventData["Element"].GetUIElement();
     renderer.shadowMapHiresDepth = edit.checked;
     renderer.shadowMapHiresDepth = edit.checked;
 }
 }
 
 
-void EditSpecularLighting(StringHash eventType, VariantMap& eventData)
+void EditDynamicInstancing(StringHash eventType, VariantMap& eventData)
 {
 {
     CheckBox@ edit = eventData["Element"].GetUIElement();
     CheckBox@ edit = eventData["Element"].GetUIElement();
-    renderer.specularLighting = edit.checked;
+    renderer.dynamicInstancing = edit.checked;
 }
 }
 
 
 void EditFrameLimiter(StringHash eventType, VariantMap& eventData)
 void EditFrameLimiter(StringHash eventType, VariantMap& eventData)

+ 2 - 0
Bin/Data/Scripts/Editor/EditorNodeWindow.as

@@ -755,6 +755,7 @@ void PickResourceDone(StringHash eventType, VariantMap& eventData)
         ref.type = ShortStringHash(resourcePicker.resourceType);
         ref.type = ShortStringHash(resourcePicker.resourceType);
         ref.id = StringHash(resourceName);
         ref.id = StringHash(resourceName);
         target.attributes[resourcePickIndex] = Variant(ref);
         target.attributes[resourcePickIndex] = Variant(ref);
+        target.FinishUpdate();
     }
     }
     else if (info.type == VAR_RESOURCEREFLIST)
     else if (info.type == VAR_RESOURCEREFLIST)
     {
     {
@@ -763,6 +764,7 @@ void PickResourceDone(StringHash eventType, VariantMap& eventData)
         {
         {
             refList.ids[resourcePickSubIndex] = StringHash(resourceName);
             refList.ids[resourcePickSubIndex] = StringHash(resourceName);
             target.attributes[resourcePickIndex] = Variant(refList);
             target.attributes[resourcePickIndex] = Variant(refList);
+            target.FinishUpdate();
         }
         }
     }
     }
 
 

+ 2 - 2
Bin/Data/Scripts/NinjaSnowWar.as

@@ -148,7 +148,7 @@ void InitScene()
     zone.fogStart = 5000;
     zone.fogStart = 5000;
     zone.fogEnd = 15000;
     zone.fogEnd = 15000;
 
 
-    Node@ lightNode = gameScene.CreateChild("Sunlight");
+    Node@ lightNode = gameScene.CreateChild("GlobalLight");
     lightNode.rotation = Quaternion(0.888074, 0.325058, -0.325058, 0);
     lightNode.rotation = Quaternion(0.888074, 0.325058, -0.325058, 0);
     Light@ light = lightNode.CreateComponent("Light");
     Light@ light = lightNode.CreateComponent("Light");
     light.lightType = LIGHT_DIRECTIONAL;
     light.lightType = LIGHT_DIRECTIONAL;
@@ -163,7 +163,7 @@ void InitScene()
     staticModel.model = cache.GetResource("Model", "Models/Level.mdl");
     staticModel.model = cache.GetResource("Model", "Models/Level.mdl");
     staticModel.material = cache.GetResource("Material", "Materials/Snow.xml");
     staticModel.material = cache.GetResource("Material", "Materials/Snow.xml");
     CollisionShape@ shape = staticNode.CreateComponent("CollisionShape");
     CollisionShape@ shape = staticNode.CreateComponent("CollisionShape");
-    shape.SetTriangleMesh(cache.GetResource("Model", "Models/Level.mdl"), 0, Vector3(), Quaternion());
+    shape.SetTriangleMesh(cache.GetResource("Model", "Models/Level.mdl"), 0);
     shape.collisionGroup = 2;
     shape.collisionGroup = 2;
     shape.collisionMask = 3;
     shape.collisionMask = 3;
 
 

+ 1 - 1
Bin/Data/Scripts/NinjaSnowWar/Potion.as

@@ -39,7 +39,7 @@ class Potion : GameObject
 
 
         // Create collision shape
         // Create collision shape
         CollisionShape@ shape = node.CreateComponent("CollisionShape");
         CollisionShape@ shape = node.CreateComponent("CollisionShape");
-        shape.SetBox(Vector3(20, 40, 20), Vector3(), Quaternion());
+        shape.SetBox(Vector3(20, 40, 20));
         shape.collisionGroup = 1;
         shape.collisionGroup = 1;
         shape.collisionMask = 3;
         shape.collisionMask = 3;
         shape.friction = potionFriction;
         shape.friction = potionFriction;

+ 1 - 1
Bin/Data/Scripts/NinjaSnowWar/SnowBall.as

@@ -45,7 +45,7 @@ class SnowBall : GameObject
     
     
         // Create collision shape. Create as local to avoid divergent simulation by the client
         // Create collision shape. Create as local to avoid divergent simulation by the client
         CollisionShape@ shape = node.CreateComponent("CollisionShape", LOCAL);
         CollisionShape@ shape = node.CreateComponent("CollisionShape", LOCAL);
-        shape.SetBox(Vector3(15, 15, 15), Vector3(), Quaternion());
+        shape.SetBox(Vector3(15, 15, 15));
         shape.collisionGroup = 1;
         shape.collisionGroup = 1;
         shape.collisionMask = 3;
         shape.collisionMask = 3;
         shape.friction = snowballFriction;
         shape.friction = snowballFriction;

+ 1 - 1
Bin/Data/Scripts/NinjaSnowWar/SnowCrate.as

@@ -38,7 +38,7 @@ class SnowCrate : GameObject
 
 
         // Create collision shape
         // Create collision shape
         CollisionShape@ shape = node.CreateComponent("CollisionShape");
         CollisionShape@ shape = node.CreateComponent("CollisionShape");
-        shape.SetBox(Vector3(80, 80, 80), Vector3(), Quaternion());
+        shape.SetBox(Vector3(80, 80, 80));
         shape.collisionGroup = 2;
         shape.collisionGroup = 2;
         shape.collisionMask = 3;
         shape.collisionMask = 3;
         shape.friction = snowcrateFriction;
         shape.friction = snowcrateFriction;

+ 8 - 7
Bin/Data/Scripts/TestScene.as

@@ -102,7 +102,8 @@ void InitScene()
     world.angularRestThreshold = 0.1;
     world.angularRestThreshold = 0.1;
     world.contactSurfaceLayer = 0.001;
     world.contactSurfaceLayer = 0.001;
 
 
-    Zone@ zone = testScene.CreateComponent("Zone");
+    Node@ zoneNode = testScene.CreateChild("Zone");
+    Zone@ zone = zoneNode.CreateComponent("Zone");
     zone.ambientColor = Color(0.1, 0.1, 0.1);
     zone.ambientColor = Color(0.1, 0.1, 0.1);
     zone.fogColor = Color(0.5, 0.5, 0.7);
     zone.fogColor = Color(0.5, 0.5, 0.7);
     zone.fogStart = 100.0;
     zone.fogStart = 100.0;
@@ -110,7 +111,7 @@ void InitScene()
     zone.boundingBox = BoundingBox(-1000.0, 1000.0);
     zone.boundingBox = BoundingBox(-1000.0, 1000.0);
 
 
     {
     {
-        Node@ lightNode = testScene.CreateChild("Light");
+        Node@ lightNode = testScene.CreateChild("GlobalLight");
         lightNode.direction = Vector3(0.5, -0.5, 0.5);
         lightNode.direction = Vector3(0.5, -0.5, 0.5);
 
 
         Light@ light = lightNode.CreateComponent("Light");
         Light@ light = lightNode.CreateComponent("Light");
@@ -132,7 +133,7 @@ void InitScene()
         object.occluder = true;
         object.occluder = true;
 
 
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
-        shape.SetBox(Vector3(2.0, 2.0, 2.0), Vector3(), Quaternion());
+        shape.SetBox(Vector3(2.0, 2.0, 2.0));
         shape.collisionGroup = 2;
         shape.collisionGroup = 2;
         shape.collisionMask = 1;
         shape.collisionMask = 1;
     }
     }
@@ -148,7 +149,7 @@ void InitScene()
         object.castShadows = true;
         object.castShadows = true;
 
 
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
-        shape.SetBox(Vector3(2.0, 2.0, 2.0), Vector3(), Quaternion());
+        shape.SetBox(Vector3(2.0, 2.0, 2.0));
         shape.collisionGroup = 2;
         shape.collisionGroup = 2;
         shape.collisionMask = 1;
         shape.collisionMask = 1;
     }
     }
@@ -166,7 +167,7 @@ void InitScene()
         object.occluder = true;
         object.occluder = true;
 
 
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
-        shape.SetBox(Vector3(2.0, 2.0, 2.0), Vector3(), Quaternion());
+        shape.SetBox(Vector3(2.0, 2.0, 2.0));
         shape.collisionGroup = 2;
         shape.collisionGroup = 2;
         shape.collisionMask = 1;
         shape.collisionMask = 1;
     }
     }
@@ -184,7 +185,7 @@ void InitScene()
         object.castShadows = true;
         object.castShadows = true;
 
 
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
         CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
-        shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"), 0, Vector3(), Quaternion());
+        shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"), 0);
         shape.collisionGroup = 2;
         shape.collisionGroup = 2;
         shape.collisionMask = 1;
         shape.collisionMask = 1;
     }
     }
@@ -411,7 +412,7 @@ void HandleSpawnBox(StringHash eventType, VariantMap& eventData)
     newNode.SetScale(0.1);
     newNode.SetScale(0.1);
 
 
     CollisionShape@ shape = newNode.CreateComponent("CollisionShape");
     CollisionShape@ shape = newNode.CreateComponent("CollisionShape");
-    shape.SetBox(Vector3(2, 2, 2), Vector3(), Quaternion());
+    shape.SetBox(Vector3(2, 2, 2));
     shape.friction = 1.0;
     shape.friction = 1.0;
     shape.collisionGroup = 1;
     shape.collisionGroup = 1;
     shape.collisionMask = 3;
     shape.collisionMask = 3;

+ 24 - 4
Bin/Data/UI/EditorSettingsDialog.xml

@@ -219,24 +219,44 @@
             <popupitem name="ShadowsHigh" />
             <popupitem name="ShadowsHigh" />
         </element>
         </element>
     </element>
     </element>
+    <element>
+        <fixedheight value="17" />
+        <layout mode="horizontal" spacing="20" />
+        <element type="Text">
+            <text value="Max occluder triangles" />
+        </element>
+        <element type="LineEdit" name="MaxOccluderTrianglesEdit">
+            <fixedwidth value="80" />
+         </element>
+    </element>
     <element>
     <element>
         <fixedheight value="17" />
         <fixedheight value="17" />
         <layout mode="horizontal" spacing="8" />
         <layout mode="horizontal" spacing="8" />
-        <element type="CheckBox" name="ShadowMapHiresDepthToggle">
+        <element type="CheckBox" name="SpecularLightingToggle">
             <fixedsize value="16 16" />
             <fixedsize value="16 16" />
         </element>
         </element>
         <element type="Text">
         <element type="Text">
-            <text value="Shadow map 24-bit depth" />
+            <text value="Specular lighting" />
         </element>
         </element>
     </element>
     </element>
     <element>
     <element>
         <fixedheight value="17" />
         <fixedheight value="17" />
         <layout mode="horizontal" spacing="8" />
         <layout mode="horizontal" spacing="8" />
-        <element type="CheckBox" name="SpecularLightingToggle">
+        <element type="CheckBox" name="DynamicInstancingToggle">
             <fixedsize value="16 16" />
             <fixedsize value="16 16" />
         </element>
         </element>
         <element type="Text">
         <element type="Text">
-            <text value="Specular lighting" />
+            <text value="Dynamic instancing" />
+        </element>
+    </element>
+    <element>
+        <fixedheight value="17" />
+        <layout mode="horizontal" spacing="8" />
+        <element type="CheckBox" name="ShadowMapHiresDepthToggle">
+            <fixedsize value="16 16" />
+        </element>
+        <element type="Text">
+            <text value="Shadow map 24-bit depth" />
         </element>
         </element>
     </element>
     </element>
     <element>
     <element>

+ 1 - 1
Engine/Audio/SoundSource3D.cpp

@@ -50,8 +50,8 @@ SoundSource3D::SoundSource3D(Context* context) :
 void SoundSource3D::RegisterObject(Context* context)
 void SoundSource3D::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<SoundSource3D>();
     context->RegisterFactory<SoundSource3D>();
-    context->CopyBaseAttributes<SoundSource, SoundSource3D>();
     
     
+    COPY_BASE_ATTRIBUTES(SoundSource3D, SoundSource);
     ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Near Distance", nearDistance_, DEFAULT_NEARDISTANCE, AM_DEFAULT);
     ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Near Distance", nearDistance_, DEFAULT_NEARDISTANCE, AM_DEFAULT);
     ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Far Distance", farDistance_, DEFAULT_FARDISTANCE, AM_DEFAULT);
     ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Far Distance", farDistance_, DEFAULT_FARDISTANCE, AM_DEFAULT);
     ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Rolloff Factor", rolloffFactor_, DEFAULT_ROLLOFF, AM_DEFAULT);
     ATTRIBUTE(SoundSource3D, VAR_FLOAT, "Rolloff Factor", rolloffFactor_, DEFAULT_ROLLOFF, AM_DEFAULT);

+ 7 - 7
Engine/Engine/PhysicsAPI.cpp

@@ -74,13 +74,13 @@ static void RegisterCollisionShape(asIScriptEngine* engine)
     
     
     RegisterComponent<CollisionShape>(engine, "CollisionShape");
     RegisterComponent<CollisionShape>(engine, "CollisionShape");
     engine->RegisterObjectMethod("CollisionShape", "void Clear()", asMETHOD(CollisionShape, Clear), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void Clear()", asMETHOD(CollisionShape, Clear), asCALL_THISCALL);
-    engine->RegisterObjectMethod("CollisionShape", "void SetSphere(float, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetSphere), asCALL_THISCALL);
-    engine->RegisterObjectMethod("CollisionShape", "void SetBox(const Vector3&in, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetBox), asCALL_THISCALL);
-    engine->RegisterObjectMethod("CollisionShape", "void SetCylinder(float, float, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetCylinder), asCALL_THISCALL);
-    engine->RegisterObjectMethod("CollisionShape", "void SetCapsule(float, float, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetCapsule), asCALL_THISCALL);
-    engine->RegisterObjectMethod("CollisionShape", "void SetTriangleMesh(Model@+, uint, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetTriangleMesh), asCALL_THISCALL);
-    engine->RegisterObjectMethod("CollisionShape", "void SetHeightfield(Model@+, uint, uint, float, uint, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetHeightfield), asCALL_THISCALL);
-    engine->RegisterObjectMethod("CollisionShape", "void SetConvexHull(Model@+, float, uint, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetConvexHull), asCALL_THISCALL);
+    engine->RegisterObjectMethod("CollisionShape", "void SetSphere(float, const Vector3&in pos = Vector3(0, 0, 0), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetSphere), asCALL_THISCALL);
+    engine->RegisterObjectMethod("CollisionShape", "void SetBox(const Vector3&in, const Vector3&in pos = Vector3(0, 0, 0), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetBox), asCALL_THISCALL);
+    engine->RegisterObjectMethod("CollisionShape", "void SetCylinder(float, float, const Vector3&in pos = Vector3(0, 0, 0), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetCylinder), asCALL_THISCALL);
+    engine->RegisterObjectMethod("CollisionShape", "void SetCapsule(float, float, const Vector3&in pos = Vector3(0, 0, 0), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetCapsule), asCALL_THISCALL);
+    engine->RegisterObjectMethod("CollisionShape", "void SetTriangleMesh(Model@+, uint, const Vector3&in scale = Vector3(1, 1, 1), const Vector3&in pos = Vector3(0, 0, 0), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetTriangleMesh), asCALL_THISCALL);
+    engine->RegisterObjectMethod("CollisionShape", "void SetHeightfield(Model@+, uint, uint, float, uint, const Vector3&in scale = Vector3(1, 1, 1), const Vector3&in pos = Vector3(0, 0, 0), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetHeightfield), asCALL_THISCALL);
+    engine->RegisterObjectMethod("CollisionShape", "void SetConvexHull(Model@+, float, uint, const Vector3&in scale = Vector3(1, 1, 1), const Vector3&in pos = Vector3(0, 0, 0), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetConvexHull), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void SetTransform(const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetTransform), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void SetTransform(const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetTransform), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void DrawDebugGeometry(DebugRenderer@+, bool)", asMETHOD(CollisionShape, DrawDebugGeometry), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void DrawDebugGeometry(DebugRenderer@+, bool)", asMETHOD(CollisionShape, DrawDebugGeometry), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "Model@+ get_model()", asMETHOD(CollisionShape, GetModel), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "Model@+ get_model()", asMETHOD(CollisionShape, GetModel), asCALL_THISCALL);

+ 9 - 6
Engine/Graphics/AnimatedModel.cpp

@@ -78,17 +78,20 @@ AnimatedModel::~AnimatedModel()
 void AnimatedModel::RegisterObject(Context* context)
 void AnimatedModel::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<AnimatedModel>();
     context->RegisterFactory<AnimatedModel>();
-    context->CopyBaseAttributes<Drawable, AnimatedModel>();
     
     
-    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
+    ATTRIBUTE(AnimatedModel, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
+    ATTRIBUTE(AnimatedModel, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
+    ATTRIBUTE(AnimatedModel, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREFLIST, "Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_RESOURCEREFLIST, "Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_FLOAT, "Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(AnimatedModel, Drawable);
+    ATTRIBUTE(AnimatedModel, VAR_INT, "Ray/Occl. LOD Level", softwareLodLevel_, M_MAX_UNSIGNED, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_VARIANTVECTOR, "Bone Animation Enabled", GetBonesEnabledAttr, SetBonesEnabledAttr, VariantVector, VariantVector(), AM_FILE | AM_NOEDIT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_VARIANTVECTOR, "Bone Animation Enabled", GetBonesEnabledAttr, SetBonesEnabledAttr, VariantVector, VariantVector(), AM_FILE | AM_NOEDIT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_VARIANTVECTOR, "Animation States", GetAnimationStatesAttr, SetAnimationStatesAttr, VariantVector, VariantVector(), AM_FILE | AM_NOEDIT);
     ACCESSOR_ATTRIBUTE(AnimatedModel, VAR_VARIANTVECTOR, "Animation States", GetAnimationStatesAttr, SetAnimationStatesAttr, VariantVector, VariantVector(), AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(AnimatedModel, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
-    ATTRIBUTE(AnimatedModel, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
-    ATTRIBUTE(AnimatedModel, VAR_INT, "Max Lights", maxLights_, 0, AM_DEFAULT);
-    ATTRIBUTE(AnimatedModel, VAR_INT, "Raycast LOD Level", softwareLodLevel_, M_MAX_UNSIGNED, AM_DEFAULT);
 }
 }
 
 
 void AnimatedModel::FinishUpdate()
 void AnimatedModel::FinishUpdate()

+ 8 - 5
Engine/Graphics/BillboardSet.cpp

@@ -73,17 +73,20 @@ BillboardSet::~BillboardSet()
 void BillboardSet::RegisterObject(Context* context)
 void BillboardSet::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<BillboardSet>();
     context->RegisterFactory<BillboardSet>();
-    context->CopyBaseAttributes<Drawable, BillboardSet>();
     
     
+    ATTRIBUTE(BillboardSet, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
+    ATTRIBUTE(BillboardSet, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
+    ATTRIBUTE(BillboardSet, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
     ATTRIBUTE(BillboardSet, VAR_FLOAT, "Animation LOD Bias", animationLodBias_, 1.0f, AM_DEFAULT);
     ATTRIBUTE(BillboardSet, VAR_FLOAT, "Animation LOD Bias", animationLodBias_, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Relative Position", IsRelative, SetRelative, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Relative Position", IsRelative, SetRelative, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Relative Scale", IsScaled, SetScaled, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Relative Scale", IsScaled, SetScaled, bool, true, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Sort By Distance", IsSorted, SetSorted, bool, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BOOL, "Sort By Distance", IsSorted, SetSorted, bool, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(BillboardSet, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_VARIANTVECTOR, "Billboards", GetBillboardsAttr, SetBillboardsAttr, VariantVector, VariantVector(), AM_FILE);
     ACCESSOR_ATTRIBUTE(BillboardSet, VAR_VARIANTVECTOR, "Billboards", GetBillboardsAttr, SetBillboardsAttr, VariantVector, VariantVector(), AM_FILE);
-    ATTRIBUTE(BillboardSet, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
-    ATTRIBUTE(BillboardSet, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
-    ATTRIBUTE(BillboardSet, VAR_INT, "Max Lights", maxLights_, 0, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(BillboardSet, Drawable);
     REF_ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BUFFER, "Network Billboards", GetNetBillboardsAttr, SetNetBillboardsAttr, PODVector<unsigned char>, PODVector<unsigned char>(), AM_NET | AM_NOEDIT);
     REF_ACCESSOR_ATTRIBUTE(BillboardSet, VAR_BUFFER, "Network Billboards", GetNetBillboardsAttr, SetNetBillboardsAttr, PODVector<unsigned char>, PODVector<unsigned char>(), AM_NET | AM_NOEDIT);
 }
 }
 
 

+ 3 - 6
Engine/Graphics/Drawable.cpp

@@ -69,12 +69,9 @@ Drawable::~Drawable()
 
 
 void Drawable::RegisterObject(Context* context)
 void Drawable::RegisterObject(Context* context)
 {
 {
-    ATTRIBUTE(Drawable, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
-    ATTRIBUTE(Drawable, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
-    ATTRIBUTE(Drawable, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Drawable, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Drawable, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Drawable, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
+    ATTRIBUTE(Drawable, VAR_INT, "Max Lights", maxLights_, 0, AM_DEFAULT);
+    ATTRIBUTE(Drawable, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
+    ATTRIBUTE(Drawable, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
 }
 }
 
 
 void Drawable::ProcessRayQuery(RayOctreeQuery& query, float initialDistance)
 void Drawable::ProcessRayQuery(RayOctreeQuery& query, float initialDistance)

+ 4 - 4
Engine/Graphics/Light.cpp

@@ -111,10 +111,6 @@ void Light::RegisterObject(Context* context)
     ATTRIBUTE(Light, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ENUM_ATTRIBUTE(Light, "Light Type", lightType_, typeNames, DEFAULT_LIGHTTYPE, AM_DEFAULT);
     ENUM_ATTRIBUTE(Light, "Light Type", lightType_, typeNames, DEFAULT_LIGHTTYPE, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Fade Distance", GetFadeDistance, SetFadeDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
-    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Fade Distance", GetShadowFadeDistance, SetShadowFadeDistance, float, 0.0f, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_COLOR, "Color", color_, Color(), AM_DEFAULT);
     ATTRIBUTE(Light, VAR_COLOR, "Color", color_, Color(), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Specular Intensity", GetSpecularIntensity, SetSpecularIntensity, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Specular Intensity", GetSpecularIntensity, SetSpecularIntensity, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Range", GetRange, SetRange, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Range", GetRange, SetRange, float, 0.0f, AM_DEFAULT);
@@ -122,6 +118,10 @@ void Light::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Attenuation Texture", GetRampTextureAttr, SetRampTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Light Shape Texture", GetShapeTextureAttr, SetShapeTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_RESOURCEREF, "Light Shape Texture", GetShapeTextureAttr, SetShapeTextureAttr, ResourceRef, ResourceRef(Texture2D::GetTypeStatic()), AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Fade Distance", GetFadeDistance, SetFadeDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Fade Distance", GetShadowFadeDistance, SetShadowFadeDistance, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Intensity", GetShadowIntensity, SetShadowIntensity, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Intensity", GetShadowIntensity, SetShadowIntensity, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Resolution", GetShadowResolution, SetShadowResolution, float, 1.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Shadow Resolution", GetShadowResolution, SetShadowResolution, float, 1.0f, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_FLOAT, "Near/Farclip Ratio", shadowNearFarRatio_, DEFAULT_SHADOWNEARFARRATIO, AM_DEFAULT);
     ATTRIBUTE(Light, VAR_FLOAT, "Near/Farclip Ratio", shadowNearFarRatio_, DEFAULT_SHADOWNEARFARRATIO, AM_DEFAULT);

+ 2 - 1
Engine/Graphics/Skybox.cpp

@@ -41,7 +41,8 @@ Skybox::~Skybox()
 void Skybox::RegisterObject(Context* context)
 void Skybox::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<Skybox>();
     context->RegisterFactory<Skybox>();
-    context->CopyBaseAttributes<StaticModel, Skybox>();
+    
+    COPY_BASE_ATTRIBUTES(Skybox, StaticModel);
 }
 }
 
 
 void Skybox::UpdateDistance(const FrameInfo& frame)
 void Skybox::UpdateDistance(const FrameInfo& frame)

+ 8 - 5
Engine/Graphics/StaticModel.cpp

@@ -55,14 +55,17 @@ StaticModel::~StaticModel()
 void StaticModel::RegisterObject(Context* context)
 void StaticModel::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<StaticModel>();
     context->RegisterFactory<StaticModel>();
-    context->CopyBaseAttributes<Drawable, StaticModel>();
     
     
+    ATTRIBUTE(StaticModel, VAR_BOOL, "Is Visible", visible_, true, AM_DEFAULT);
+    ATTRIBUTE(StaticModel, VAR_BOOL, "Is Occluder", occluder_, false, AM_DEFAULT);
+    ATTRIBUTE(StaticModel, VAR_BOOL, "Cast Shadows", castShadows_, false, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(StaticModel, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(StaticModel, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(StaticModel, VAR_RESOURCEREFLIST, "Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(StaticModel, VAR_RESOURCEREFLIST, "Material", GetMaterialsAttr, SetMaterialsAttr, ResourceRefList, ResourceRefList(Material::GetTypeStatic()), AM_DEFAULT);
-    ATTRIBUTE(StaticModel, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
-    ATTRIBUTE(StaticModel, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
-    ATTRIBUTE(StaticModel, VAR_INT, "Max Lights", maxLights_, 0, AM_DEFAULT);
-    ATTRIBUTE(StaticModel, VAR_INT, "Raycast LOD Level", softwareLodLevel_, M_MAX_UNSIGNED, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(StaticModel, VAR_FLOAT, "Draw Distance", GetDrawDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(StaticModel, VAR_FLOAT, "Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(StaticModel, VAR_FLOAT, "LOD Bias", GetLodBias, SetLodBias, float, 1.0f, AM_DEFAULT);
+    COPY_BASE_ATTRIBUTES(StaticModel, Drawable);
+    ATTRIBUTE(StaticModel, VAR_INT, "Ray/Occl. LOD Level", softwareLodLevel_, M_MAX_UNSIGNED, AM_DEFAULT);
 }
 }
 
 
 void StaticModel::ProcessRayQuery(RayOctreeQuery& query, float initialDistance)
 void StaticModel::ProcessRayQuery(RayOctreeQuery& query, float initialDistance)

+ 1 - 1
Engine/Graphics/Zone.cpp

@@ -59,7 +59,7 @@ void Zone::RegisterObject(Context* context)
     ATTRIBUTE(Zone, VAR_COLOR, "Fog Color", fogColor_, DEFAULT_FOG_COLOR, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_COLOR, "Fog Color", fogColor_, DEFAULT_FOG_COLOR, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_FLOAT, "Fog Start", fogStart_, DEFAULT_FOGSTART, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_FLOAT, "Fog Start", fogStart_, DEFAULT_FOGSTART, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_FLOAT, "Fog End", fogEnd_, DEFAULT_FOGEND, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_FLOAT, "Fog End", fogEnd_, DEFAULT_FOGEND, AM_DEFAULT);
-    ATTRIBUTE(Zone, VAR_INT, "Zone Priority", priority_, 0, AM_DEFAULT);
+    ATTRIBUTE(Zone, VAR_INT, "Priority", priority_, 0, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_INT, "View Mask", viewMask_, DEFAULT_VIEWMASK, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
     ATTRIBUTE(Zone, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
 }
 }

+ 23 - 18
Engine/Physics/CollisionShape.cpp

@@ -301,9 +301,9 @@ CollisionShape::CollisionShape(Context* context) :
     Component(context),
     Component(context),
     geometry_(0),
     geometry_(0),
     shapeType_(SHAPE_NONE),
     shapeType_(SHAPE_NONE),
-    size_(Vector3::ZERO),
+    size_(Vector3::UNITY),
     thickness_(0.0f),
     thickness_(0.0f),
-    lodLevel_(M_MAX_UNSIGNED),
+    lodLevel_(0),
     position_(Vector3::ZERO),
     position_(Vector3::ZERO),
     rotation_(Quaternion::IDENTITY),
     rotation_(Quaternion::IDENTITY),
     geometryScale_(Vector3::UNITY),
     geometryScale_(Vector3::UNITY),
@@ -324,13 +324,13 @@ void CollisionShape::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<CollisionShape>();
     context->RegisterFactory<CollisionShape>();
     
     
+    ENUM_ATTRIBUTE(CollisionShape, "Shape Type", shapeType_, typeNames, SHAPE_NONE, AM_DEFAULT);
+    ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Size", size_, Vector3::UNITY, AM_DEFAULT);
     REF_ACCESSOR_ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Offset Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_DEFAULT);
     REF_ACCESSOR_ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Offset Position", GetPosition, SetPosition, Vector3, Vector3::ZERO, AM_DEFAULT);
     REF_ACCESSOR_ATTRIBUTE(CollisionShape, VAR_QUATERNION, "Offset Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_DEFAULT);
     REF_ACCESSOR_ATTRIBUTE(CollisionShape, VAR_QUATERNION, "Offset Rotation", GetRotation, SetRotation, Quaternion, Quaternion::IDENTITY, AM_DEFAULT);
-    ATTRIBUTE(CollisionShape, VAR_VECTOR3, "Size", size_, Vector3::ZERO, AM_DEFAULT);
-    ENUM_ATTRIBUTE(CollisionShape, "Shape Type", shapeType_, typeNames, SHAPE_NONE, AM_DEFAULT);
-    ATTRIBUTE(CollisionShape, VAR_FLOAT, "Hull Thickness", thickness_, 0.0f, AM_DEFAULT);
-    ATTRIBUTE(CollisionShape, VAR_INT, "LOD Level", lodLevel_, M_MAX_UNSIGNED, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
+    ATTRIBUTE(CollisionShape, VAR_INT, "LOD Level", lodLevel_, 0, AM_DEFAULT);
+    ATTRIBUTE(CollisionShape, VAR_FLOAT, "Hull Thickness", thickness_, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape, VAR_INT, "Collision Group", GetCollisionGroup, SetCollisionGroup, unsigned, M_MAX_UNSIGNED, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape, VAR_INT, "Collision Group", GetCollisionGroup, SetCollisionGroup, unsigned, M_MAX_UNSIGNED, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape, VAR_INT, "Collision Mask", GetCollisionMask, SetCollisionMask, unsigned, M_MAX_UNSIGNED, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape, VAR_INT, "Collision Mask", GetCollisionMask, SetCollisionMask, unsigned, M_MAX_UNSIGNED, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape, VAR_FLOAT, "Friction", GetFriction, SetFriction, float, DEFAULT_FRICTION, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(CollisionShape, VAR_FLOAT, "Friction", GetFriction, SetFriction, float, DEFAULT_FRICTION, AM_DEFAULT);
@@ -344,8 +344,12 @@ void CollisionShape::OnSetAttribute(const AttributeInfo& attr, const Variant& sr
     // Change of some attributes requires the geometry to be recreated
     // Change of some attributes requires the geometry to be recreated
     switch (attr.offset_)
     switch (attr.offset_)
     {
     {
-    case offsetof(CollisionShape, shapeType_):
     case offsetof(CollisionShape, size_):
     case offsetof(CollisionShape, size_):
+        size_ = size_.Abs(); // Negative size is not allowed
+        recreateGeometry_ = true;
+        break;
+        
+    case offsetof(CollisionShape, shapeType_):
     case offsetof(CollisionShape, thickness_):
     case offsetof(CollisionShape, thickness_):
     case offsetof(CollisionShape, lodLevel_):
     case offsetof(CollisionShape, lodLevel_):
         recreateGeometry_ = true;
         recreateGeometry_ = true;
@@ -417,7 +421,7 @@ void CollisionShape::SetCylinder(float radius, float height, const Vector3& posi
     CreateGeometry();
     CreateGeometry();
 }
 }
 
 
-void CollisionShape::SetTriangleMesh(Model* model, unsigned lodLevel, const Vector3& position, const Quaternion& rotation)
+void CollisionShape::SetTriangleMesh(Model* model, unsigned lodLevel, const Vector3& size, const Vector3& position, const Quaternion& rotation)
 {
 {
     PROFILE(SetTriangleMeshShape);
     PROFILE(SetTriangleMeshShape);
     
     
@@ -432,14 +436,14 @@ void CollisionShape::SetTriangleMesh(Model* model, unsigned lodLevel, const Vect
     model_ = model;
     model_ = model;
     shapeType_ = SHAPE_TRIANGLEMESH;
     shapeType_ = SHAPE_TRIANGLEMESH;
     lodLevel_ = lodLevel;
     lodLevel_ = lodLevel;
-    size_ = model->GetBoundingBox().Size();
+    size_ = size.Abs();
     position_ = position;
     position_ = position;
     rotation_ = rotation;
     rotation_ = rotation;
     
     
     CreateGeometry();
     CreateGeometry();
 }
 }
 
 
-void CollisionShape::SetHeightfield(Model* model, unsigned xPoints, unsigned zPoints, float thickness, unsigned lodLevel, const Vector3& position, const Quaternion& rotation)
+void CollisionShape::SetHeightfield(Model* model, unsigned xPoints, unsigned zPoints, float thickness, unsigned lodLevel, const Vector3& size, const Vector3& position, const Quaternion& rotation)
 {
 {
     PROFILE(SetHeightFieldShape);
     PROFILE(SetHeightFieldShape);
     
     
@@ -456,14 +460,14 @@ void CollisionShape::SetHeightfield(Model* model, unsigned xPoints, unsigned zPo
     numPoints_ = IntVector2(xPoints, zPoints);
     numPoints_ = IntVector2(xPoints, zPoints);
     thickness_ = thickness;
     thickness_ = thickness;
     lodLevel_ = lodLevel;
     lodLevel_ = lodLevel;
+    size_ = size.Abs();
     position_ = position;
     position_ = position;
     rotation_ = rotation;
     rotation_ = rotation;
-    size_ = model->GetBoundingBox().Size();
     
     
     CreateGeometry();
     CreateGeometry();
 }
 }
 
 
-void CollisionShape::SetConvexHull(Model* model, float thickness, unsigned lodLevel, const Vector3& position, const Quaternion& rotation)
+void CollisionShape::SetConvexHull(Model* model, float thickness, unsigned lodLevel, const Vector3& size, const Vector3& position, const Quaternion& rotation)
 {
 {
     PROFILE(SetConvexHullShape);
     PROFILE(SetConvexHullShape);
     
     
@@ -479,7 +483,7 @@ void CollisionShape::SetConvexHull(Model* model, float thickness, unsigned lodLe
     shapeType_ = SHAPE_CONVEXHULL;
     shapeType_ = SHAPE_CONVEXHULL;
     thickness_ = thickness;
     thickness_ = thickness;
     lodLevel_ = lodLevel;
     lodLevel_ = lodLevel;
-    size_ = model->GetBoundingBox().Size();
+    size_ = size.Abs();
     position_ = position;
     position_ = position;
     rotation_ = rotation;
     rotation_ = rotation;
     
     
@@ -783,7 +787,7 @@ void CollisionShape::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
 void CollisionShape::OnMarkedDirty(Node* node)
 void CollisionShape::OnMarkedDirty(Node* node)
 {
 {
     // If scale has changed, must recreate the geometry
     // If scale has changed, must recreate the geometry
-    if (node->GetScale() != geometryScale_)
+    if (node->GetWorldScale() != geometryScale_)
         CreateGeometry();
         CreateGeometry();
     else
     else
         UpdateTransform();
         UpdateTransform();
@@ -855,7 +859,7 @@ void CollisionShape::CreateGeometry()
     case SHAPE_CONVEXHULL:
     case SHAPE_CONVEXHULL:
         {
         {
             // Check the geometry cache
             // Check the geometry cache
-            String id = model_->GetName() + "_" + String(geometryScale_) + "_" + String(lodLevel_);
+            String id = model_->GetName() + "_" + String(size) + "_" + String(lodLevel_);
             if (shapeType_ == SHAPE_CONVEXHULL)
             if (shapeType_ == SHAPE_CONVEXHULL)
                 id += "_" + String(thickness_);
                 id += "_" + String(thickness_);
             
             
@@ -869,7 +873,7 @@ void CollisionShape::CreateGeometry()
             else
             else
             {
             {
                 SharedPtr<TriangleMeshData> newData(new TriangleMeshData(model_, shapeType_ == SHAPE_CONVEXHULL, thickness_,
                 SharedPtr<TriangleMeshData> newData(new TriangleMeshData(model_, shapeType_ == SHAPE_CONVEXHULL, thickness_,
-                    lodLevel_, geometryScale_));
+                    lodLevel_, size));
                 cache[id] = newData;
                 cache[id] = newData;
                 geometry_ = dCreateTriMesh(space, newData->triMesh_, 0, 0, 0);
                 geometry_ = dCreateTriMesh(space, newData->triMesh_, 0, 0, 0);
                 geometryData_ = StaticCast<CollisionGeometryData>(newData);
                 geometryData_ = StaticCast<CollisionGeometryData>(newData);
@@ -880,7 +884,8 @@ void CollisionShape::CreateGeometry()
     case SHAPE_HEIGHTFIELD:
     case SHAPE_HEIGHTFIELD:
         {
         {
             // Check the geometry cache
             // Check the geometry cache
-            String id = model_->GetName() + "_" + String(numPoints_) + "_" + String(thickness_) + "_" + String(lodLevel_);
+            String id = model_->GetName() + "_" + String(size) + "_" + String(numPoints_) + "_" + String(thickness_) + "_" +
+                String(lodLevel_);
             
             
             Map<String, SharedPtr<HeightfieldData> >& cache = physicsWorld_->GetHeightfieldCache();
             Map<String, SharedPtr<HeightfieldData> >& cache = physicsWorld_->GetHeightfieldCache();
             Map<String, SharedPtr<HeightfieldData> >::Iterator j = cache.Find(id);
             Map<String, SharedPtr<HeightfieldData> >::Iterator j = cache.Find(id);
@@ -891,7 +896,7 @@ void CollisionShape::CreateGeometry()
             }
             }
             else
             else
             {
             {
-                SharedPtr<HeightfieldData> newData(new HeightfieldData(model_, numPoints_, thickness_, lodLevel_, geometryScale_));
+                SharedPtr<HeightfieldData> newData(new HeightfieldData(model_, numPoints_, thickness_, lodLevel_, size));
                 cache[id] = newData;
                 cache[id] = newData;
                 geometry_ = dCreateHeightfield(space, newData->heightfield_, 1);
                 geometry_ = dCreateHeightfield(space, newData->heightfield_, 1);
                 geometryData_ = StaticCast<CollisionGeometryData>(newData);
                 geometryData_ = StaticCast<CollisionGeometryData>(newData);

+ 7 - 7
Engine/Physics/CollisionShape.h

@@ -107,19 +107,19 @@ public:
     /// Clear the collision geometry.
     /// Clear the collision geometry.
     void Clear();
     void Clear();
     /// %Set as a sphere.
     /// %Set as a sphere.
-    void SetSphere(float radius, const Vector3& position, const Quaternion& rotation);
+    void SetSphere(float radius, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
     /// %Set as a box.
     /// %Set as a box.
-    void SetBox(const Vector3& size, const Vector3& position, const Quaternion& rotation);
+    void SetBox(const Vector3& size, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
     /// %Set as a cylinder.
     /// %Set as a cylinder.
-    void SetCylinder(float radius, float height, const Vector3& position, const Quaternion& rotation);
+    void SetCylinder(float radius, float height, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
     /// %Set as a capsule.
     /// %Set as a capsule.
-    void SetCapsule(float radius, float height, const Vector3& position, const Quaternion& rotation);
+    void SetCapsule(float radius, float height, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
     /// %Set as a triangle mesh.
     /// %Set as a triangle mesh.
-    void SetTriangleMesh(Model* model, unsigned lodLevel, const Vector3& position, const Quaternion& rotation);
+    void SetTriangleMesh(Model* model, unsigned lodLevel, const Vector3& size = Vector3::UNITY, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
     /// %Set as a heightfield.
     /// %Set as a heightfield.
-    void SetHeightfield(Model* model, unsigned xPoints, unsigned zPoints, float thickness, unsigned lodLevel, const Vector3& position, const Quaternion& rotation);
+    void SetHeightfield(Model* model, unsigned xPoints, unsigned zPoints, float thickness, unsigned lodLevel, const Vector3& size = Vector3::UNITY, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
     /// %Set as a convex hull (internally an ODE trimesh as well.)
     /// %Set as a convex hull (internally an ODE trimesh as well.)
-    void SetConvexHull(Model* model, float skinWidth, unsigned lodLevel, const Vector3& position, const Quaternion& rotation);
+    void SetConvexHull(Model* model, float skinWidth, unsigned lodLevel, const Vector3& size = Vector3::UNITY, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
     /// %Set offset position.
     /// %Set offset position.
     void SetPosition(const Vector3& position);
     void SetPosition(const Vector3& position);
     /// %Set rotation.
     /// %Set rotation.

+ 3 - 3
Engine/Physics/PhysicsWorld.cpp

@@ -134,13 +134,11 @@ void PhysicsWorld::RegisterObject(Context* context)
 {
 {
     context->RegisterFactory<PhysicsWorld>();
     context->RegisterFactory<PhysicsWorld>();
     
     
+    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_VECTOR3, "Gravity", GetGravity, SetGravity, Vector3, Vector3::ZERO, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_INT, "Physics FPS", fps_, DEFAULT_FPS, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_INT, "Physics FPS", fps_, DEFAULT_FPS, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_INT, "Max Contacts", maxContacts_, DEFAULT_MAX_CONTACTS, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_INT, "Max Contacts", maxContacts_, DEFAULT_MAX_CONTACTS, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Bounce Threshold", bounceThreshold_, DEFAULT_BOUNCE_THRESHOLD, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Bounce Threshold", bounceThreshold_, DEFAULT_BOUNCE_THRESHOLD, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Network Max Ang Vel.", maxNetworkAngularVelocity_, DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY, AM_DEFAULT);
     ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Network Max Ang Vel.", maxNetworkAngularVelocity_, DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY, AM_DEFAULT);
-    ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Time Accumulator", timeAcc_, 0.0f, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(PhysicsWorld, VAR_INT, "Random Seed", randomSeed_, 0, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_VECTOR3, "Gravity", GetGravity, SetGravity, Vector3, Vector3::ZERO, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Lin Rest Threshold", GetLinearRestThreshold, SetLinearRestThreshold, float, 0.01f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Lin Rest Threshold", GetLinearRestThreshold, SetLinearRestThreshold, float, 0.01f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Lin Damp Threshold", GetLinearDampingThreshold, SetLinearDampingThreshold, float, 0.01f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Lin Damp Threshold", GetLinearDampingThreshold, SetLinearDampingThreshold, float, 0.01f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Lin Damp Scale", GetLinearDampingScale, SetLinearDampingScale, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Lin Damp Scale", GetLinearDampingScale, SetLinearDampingScale, float, 0.0f, AM_DEFAULT);
@@ -150,6 +148,8 @@ void PhysicsWorld::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "ERP Parameter", GetERP, SetERP, float, 0.2f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "ERP Parameter", GetERP, SetERP, float, 0.2f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "CFM Parameter", GetCFM, SetCFM, float, 0.00001f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "CFM Parameter", GetCFM, SetCFM, float, 0.00001f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Contact Surface Layer", GetContactSurfaceLayer, SetContactSurfaceLayer, float, 0.0f, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Contact Surface Layer", GetContactSurfaceLayer, SetContactSurfaceLayer, float, 0.0f, AM_DEFAULT);
+    ATTRIBUTE(PhysicsWorld, VAR_FLOAT, "Time Accumulator", timeAcc_, 0.0f, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE(PhysicsWorld, VAR_INT, "Random Seed", randomSeed_, 0, AM_FILE | AM_NOEDIT);
 }
 }
 
 
 void PhysicsWorld::Update(float timeStep)
 void PhysicsWorld::Update(float timeStep)

+ 2 - 2
Engine/Scene/Node.cpp

@@ -220,14 +220,14 @@ void Node::SetDirection(const Vector3& direction)
 
 
 void Node::SetScale(float scale)
 void Node::SetScale(float scale)
 {
 {
-    scale_ = Vector3(scale, scale, scale);
+    scale_ = Vector3(scale, scale, scale).Abs();
     if (!dirty_)
     if (!dirty_)
         MarkDirty();
         MarkDirty();
 }
 }
 
 
 void Node::SetScale(const Vector3& scale)
 void Node::SetScale(const Vector3& scale)
 {
 {
-    scale_ = scale;
+    scale_ = scale.Abs();
     if (!dirty_)
     if (!dirty_)
         MarkDirty();
         MarkDirty();
 }
 }

+ 2 - 0
Engine/Scene/Serializable.h

@@ -169,6 +169,8 @@ public:
     SetFunctionPtr setFunction_;
     SetFunctionPtr setFunction_;
 };
 };
 
 
+#define COPY_BASE_ATTRIBUTES(className, sourceClassName) context->CopyBaseAttributes<sourceClassName, className>()
+#define REMOVE_ATTRIBUTE(className, name) context->RemoveAttribute<className>(name)
 #define ATTRIBUTE(className, type, name, variable, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, offsetof(className, variable), defaultValue, mode))
 #define ATTRIBUTE(className, type, name, variable, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, offsetof(className, variable), defaultValue, mode))
 #define ENUM_ATTRIBUTE(className, name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, offsetof(className, variable), enumNames, defaultValue, mode))
 #define ENUM_ATTRIBUTE(className, name, variable, enumNames, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(VAR_INT, name, offsetof(className, variable), enumNames, defaultValue, mode))
 #define ACCESSOR_ATTRIBUTE(className, type, name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, new AttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, mode))
 #define ACCESSOR_ATTRIBUTE(className, type, name, getFunction, setFunction, typeName, defaultValue, mode) context->RegisterAttribute<className>(AttributeInfo(type, name, new AttributeAccessorImpl<className, typeName>(&className::getFunction, &className::setFunction), defaultValue, mode))