Browse Source

Take node parenting into account when moving nodes in the editor.
Added LocalToWorld() & WorldToLocal() functions to Node.

Lasse Öörni 14 years ago
parent
commit
bad42bcc5f

+ 6 - 2
Bin/Data/Scripts/Editor/EditorView.as

@@ -215,7 +215,9 @@ void MoveCamera(float timeStep)
                         Node@ node = editNodes[i];
                         Vector3 nodeAdjust = adjust;
                         if (axisMode == AXIS_LOCAL)
-                            nodeAdjust = node.rotation * nodeAdjust;
+                            nodeAdjust = node.worldRotation * nodeAdjust;
+                        if (node.parent !is null)
+                            nodeAdjust = node.parent.WorldToLocal(Vector4(nodeAdjust, 0.0));
                         node.position = node.position + nodeAdjust * moveStep;
                     }
                     changed = true;
@@ -302,7 +304,9 @@ void SteppedObjectManipulation(int key)
             Node@ node = editNodes[i];
             Vector3 nodeAdjust = adjust;
             if (axisMode == AXIS_LOCAL)
-                nodeAdjust = node.rotation * nodeAdjust;
+                nodeAdjust = node.worldRotation * nodeAdjust;
+            if (node.parent !is null)
+                nodeAdjust = node.parent.WorldToLocal(Vector4(nodeAdjust, 0.0));
 
             Vector3 pos = node.position;
             if (adjust.x != 0)

+ 8 - 0
Docs/ScriptAPI.dox

@@ -1095,6 +1095,10 @@ Methods:<br>
 - Component@[]@ GetComponents(const String&) const
 - Component@ GetComponent(const String&) const
 - bool HasComponent(const String&) const
+- Vector3 LocalToWorld(const Vector3&) const
+- Vector3 LocalToWorld(const Vector4&) const
+- Vector3 WorldToLocal(const Vector3&) const
+- Vector3 WorldToLocal(const Vector4&) const
 - ScriptObject@ CreateScriptObject(ScriptFile@, const String&, CreateMode arg2 = REPLICATED)
 - ScriptObject@ CreateScriptObject(const String&, const String&, CreateMode arg2 = REPLICATED)
 - ScriptObject@ GetScriptObject() const
@@ -1174,6 +1178,10 @@ Methods:<br>
 - Component@[]@ GetComponents(const String&) const
 - Component@ GetComponent(const String&) const
 - bool HasComponent(const String&) const
+- Vector3 LocalToWorld(const Vector3&) const
+- Vector3 LocalToWorld(const Vector4&) const
+- Vector3 WorldToLocal(const Vector3&) const
+- Vector3 WorldToLocal(const Vector4&) const
 - bool LoadXML(File@)
 - bool SaveXML(File@)
 - bool LoadAsync(File@)

+ 4 - 0
Engine/Engine/APITemplates.h

@@ -524,6 +524,10 @@ template <class T> void RegisterNode(asIScriptEngine* engine, const char* classN
     engine->RegisterObjectMethod(className, "Array<Component@>@ GetComponents(const String&in) const", asFUNCTION(NodeGetComponentsWithType), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "Component@+ GetComponent(const String&in) const", asFUNCTION(NodeGetComponentWithType), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod(className, "bool HasComponent(const String&in) const", asFUNCTION(NodeHasComponent), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod(className, "Vector3 LocalToWorld(const Vector3&in) const", asMETHODPR(T, LocalToWorld, (const Vector3&) const, Vector3), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "Vector3 LocalToWorld(const Vector4&in) const", asMETHODPR(T, LocalToWorld, (const Vector4&) const, Vector3), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "Vector3 WorldToLocal(const Vector3&in) const", asMETHODPR(T, WorldToLocal, (const Vector3&) const, Vector3), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "Vector3 WorldToLocal(const Vector4&in) const", asMETHODPR(T, WorldToLocal, (const Vector4&) const, Vector3), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_position(const Vector3&in)", asMETHOD(T, SetPosition), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const Vector3& get_position() const", asMETHOD(T, GetPosition), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void set_rotation(const Quaternion&in)", asMETHOD(T, SetRotation), asCALL_THISCALL);

+ 6 - 0
Engine/Engine/MathAPI.cpp

@@ -279,12 +279,18 @@ static void ConstructVector4Init(float x, float y, float z, float w, Vector4* pt
     new(ptr) Vector4(x, y, z, w);
 }
 
+static void ConstructVector4InitVector3(const Vector3& vector, float w, Vector4* ptr)
+{
+    new(ptr) Vector4(vector, w);
+}
+
 static void RegisterVector4(asIScriptEngine* engine)
 {
     engine->RegisterObjectType("Vector4", sizeof(Vector4), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CAK);
     engine->RegisterObjectBehaviour("Vector4", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructVector4), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Vector4", asBEHAVE_CONSTRUCT, "void f(const Vector4&in)", asFUNCTION(ConstructVector4Copy), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("Vector4", asBEHAVE_CONSTRUCT, "void f(float, float, float, float)", asFUNCTION(ConstructVector4Init), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("Vector4", asBEHAVE_CONSTRUCT, "void f(const Vector3&in, float)", asFUNCTION(ConstructVector4InitVector3), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Vector4", "Vector4& opAssign(const Vector4&in)", asMETHOD(Vector4, operator =), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector4", "Vector4& opAddAssign(const Vector4&in)", asMETHOD(Vector4, operator +=), asCALL_THISCALL);
     engine->RegisterObjectMethod("Vector4", "Vector4& opSubAssign(const Vector4&in)", asMETHOD(Vector4, operator -=), asCALL_THISCALL);

+ 20 - 0
Engine/Scene/Node.cpp

@@ -596,6 +596,26 @@ Matrix3x4 Node::GetWorldTargetTransform() const
     return ret;
 }
 
+Vector3 Node::LocalToWorld(const Vector3& position) const
+{
+    return GetWorldTransform() * position;
+}
+
+Vector3 Node::LocalToWorld(const Vector4& vector) const
+{
+    return GetWorldTransform() * vector;
+}
+
+Vector3 Node::WorldToLocal(const Vector3& position) const
+{
+    return GetWorldTransform().Inverse() * position;
+}
+
+Vector3 Node::WorldToLocal(const Vector4& vector) const
+{
+    return GetWorldTransform().Inverse() * vector;
+}
+
 unsigned Node::GetNumChildren(bool recursive) const
 {
     if (!recursive)

+ 8 - 0
Engine/Scene/Node.h

@@ -227,6 +227,14 @@ public:
     
     /// Return world-space unsmoothed (target) transform. Is recalculated each time.
     Matrix3x4 GetWorldTargetTransform() const;
+    /// Convert a local-space position to world space.
+    Vector3 LocalToWorld(const Vector3& position) const;
+    /// Convert a local-space position or rotation to world space.
+    Vector3 LocalToWorld(const Vector4& vector) const;
+    /// Convert a world-space position to local space.
+    Vector3 WorldToLocal(const Vector3& position) const;
+    /// Convert a world-space position or rotation to local space.
+    Vector3 WorldToLocal(const Vector4& vector) const;
     /// Return whether transform has changed and world transform needs recalculation.
     bool IsDirty() const { return dirty_; }
     /// Return whether motion smoothing is enabled.