From 1bf87fa26c6763ef282ec39b07b678723a7f389b Mon Sep 17 00:00:00 2001 From: Jorge Bernal Date: Mon, 14 Jul 2014 17:36:56 -0700 Subject: BGE: TrackTo actuator: increasing up & track axis options This is related to Task T34861 to increase up & track axis options for TrackTo actuator. I've just added it to differential to facilitate an easier review. With the patch applied you can select X, Y and Z axis for the Up axis, and X, Y, Z, -X, -Y and -Z for the track axis. Related to the implementation I have used the algorithm from Trackto constrain placed in constrain.c but adapted to be used with MOTO library. The wiki docs are here (http://wiki.blender.org/index.php/User:Lordloki/Doc:2.6/Manual/Game_Engine/Logic/Actuators/Edit_Object#Trackto_Actuator). Test file is here: {F97623} I have also uploaded 2 screenshots showing the UI modifications to the TrackTo actuator: {F91992} {F91990} Reviewers: moguri, dfelinto Reviewed By: moguri CC: Genome36 Differential Revision: https://developer.blender.org/D565 --- doc/python_api/rst/bge.logic.rst | 17 ++ .../rst/bge_types/bge.types.KX_TrackToActuator.rst | 22 ++ intern/moto/include/MT_Matrix3x3.h | 7 + intern/moto/include/MT_Vector3.h | 2 +- intern/moto/include/MT_Vector3.inl | 7 + release/scripts/startup/bl_ui/properties_object.py | 9 +- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/intern/sca.c | 4 + source/blender/blenloader/intern/versioning_270.c | 24 +++ source/blender/editors/space_logic/logic_window.c | 6 + source/blender/makesdna/DNA_actuator_types.h | 15 ++ source/blender/makesrna/intern/rna_actuator.c | 29 +++ .../gameengine/Converter/KX_ConvertActuators.cpp | 4 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 12 ++ source/gameengine/Ketsji/KX_TrackToActuator.cpp | 223 ++++++++------------- source/gameengine/Ketsji/KX_TrackToActuator.h | 15 ++ 16 files changed, 249 insertions(+), 149 deletions(-) diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst index 4e0d317e4bf..d901a4e4207 100644 --- a/doc/python_api/rst/bge.logic.rst +++ b/doc/python_api/rst/bge.logic.rst @@ -868,6 +868,23 @@ See :class:`bge.types.KX_SteeringActuator.behavior` :value: 3 +.. _logic-trackto-actuator: + +----------------- +TrackTo Actuator +----------------- + +See :class:`bge.types.KX_TrackToActuator` + +.. data:: KX_TRACK_UPAXIS_POS_X +.. data:: KX_TRACK_UPAXIS_POS_Y +.. data:: KX_TRACK_UPAXIS_POS_Z +.. data:: KX_TRACK_TRAXIS_POS_X +.. data:: KX_TRACK_TRAXIS_POS_Y +.. data:: KX_TRACK_TRAXIS_POS_Z +.. data:: KX_TRACK_TRAXIS_NEG_X +.. data:: KX_TRACK_TRAXIS_NEG_Y +.. data:: KX_TRACK_TRAXIS_NEG_Z ======= Various diff --git a/doc/python_api/rst/bge_types/bge.types.KX_TrackToActuator.rst b/doc/python_api/rst/bge_types/bge.types.KX_TrackToActuator.rst index 070243c6a05..5b5c5d0c0db 100644 --- a/doc/python_api/rst/bge_types/bge.types.KX_TrackToActuator.rst +++ b/doc/python_api/rst/bge_types/bge.types.KX_TrackToActuator.rst @@ -37,3 +37,25 @@ base class --- :class:`SCA_IActuator` :type: boolean + .. attribute:: upAxis + + The axis that points upward. + + :type: integer from 0 to 2 + + * KX_TRACK_UPAXIS_POS_X + * KX_TRACK_UPAXIS_POS_Y + * KX_TRACK_UPAXIS_POS_Z + + .. attribute:: trackAxis + + The axis that points to the target object. + + :type: integer from 0 to 5 + + * KX_TRACK_TRAXIS_POS_X + * KX_TRACK_TRAXIS_POS_Y + * KX_TRACK_TRAXIS_POS_Z + * KX_TRACK_TRAXIS_NEG_X + * KX_TRACK_TRAXIS_NEG_Y + * KX_TRACK_TRAXIS_NEG_Z diff --git a/intern/moto/include/MT_Matrix3x3.h b/intern/moto/include/MT_Matrix3x3.h index 6d709fae662..17dd5335217 100644 --- a/intern/moto/include/MT_Matrix3x3.h +++ b/intern/moto/include/MT_Matrix3x3.h @@ -84,11 +84,18 @@ public: MT_Vector3 getColumn(int i) const { return MT_Vector3(m_el[0][i], m_el[1][i], m_el[2][i]); } + void setColumn(int i, const MT_Vector3& v) { m_el[0][i] = v[0]; m_el[1][i] = v[1]; m_el[2][i] = v[2]; } + + void setRow(int i, const MT_Vector3& v) { + m_el[i][0] = v[0]; + m_el[i][1] = v[1]; + m_el[i][2] = v[2]; + } void setValue(const float *m) { m_el[0][0] = *m++; m_el[1][0] = *m++; m_el[2][0] = *m++; m++; diff --git a/intern/moto/include/MT_Vector3.h b/intern/moto/include/MT_Vector3.h index 83c53a19d66..b06f345bdaf 100644 --- a/intern/moto/include/MT_Vector3.h +++ b/intern/moto/include/MT_Vector3.h @@ -75,7 +75,7 @@ public: void normalize(); MT_Vector3 normalized() const; MT_Vector3 safe_normalized() const; - + MT_Vector3 safe_normalized_vec(MT_Vector3 vecnormalized) const; void scale(MT_Scalar x, MT_Scalar y, MT_Scalar z); MT_Vector3 scaled(MT_Scalar x, MT_Scalar y, MT_Scalar z) const; diff --git a/intern/moto/include/MT_Vector3.inl b/intern/moto/include/MT_Vector3.inl index b17ef47c709..09c92c6ab54 100644 --- a/intern/moto/include/MT_Vector3.inl +++ b/intern/moto/include/MT_Vector3.inl @@ -77,6 +77,13 @@ GEN_INLINE MT_Vector3 MT_Vector3::safe_normalized() const { *this / len; } +GEN_INLINE MT_Vector3 MT_Vector3::safe_normalized_vec(MT_Vector3 vecnormalized) const { + MT_Scalar len = length(); + return MT_fuzzyZero(len) ? + vecnormalized : + *this / len; +} + GEN_INLINE void MT_Vector3::scale(MT_Scalar xx, MT_Scalar yy, MT_Scalar zz) { m_co[0] *= xx; m_co[1] *= yy; m_co[2] *= zz; } diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 6b7e7b47281..9d958892c73 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -301,10 +301,11 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): split = layout.split() - col = split.column() - col.label(text="Tracking Axes:") - col.prop(ob, "track_axis", text="Axis") - col.prop(ob, "up_axis", text="Up Axis") + if context.scene.render.engine != 'BLENDER_GAME': + col = split.column() + col.label(text="Tracking Axes:") + col.prop(ob, "track_axis", text="Axis") + col.prop(ob, "up_axis", text="Up Axis") col = split.column() col.prop(ob, "use_slow_parent") diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 0af45a147a4..19fa60f5827 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 271 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 2 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 270 #define BLENDER_MINSUBVERSION 5 diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 1310162483e..4be75344133 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -392,6 +392,7 @@ void init_actuator(bActuator *act) bSteeringActuator *sta; bArmatureActuator *arma; bMouseActuator *ma; + bEditObjectActuator *eoa; if (act->data) MEM_freeN(act->data); act->data= NULL; @@ -430,6 +431,9 @@ void init_actuator(bActuator *act) break; case ACT_EDIT_OBJECT: act->data= MEM_callocN(sizeof(bEditObjectActuator), "editobact"); + eoa = act->data; + eoa->upflag= ACT_TRACK_UP_Z; + eoa->trackflag= ACT_TRACK_TRAXIS_Y; break; case ACT_CONSTRAINT: act->data= MEM_callocN(sizeof(bConstraintActuator), "cons act"); diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 103f9b76ba7..dde16c8d44f 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -42,6 +42,7 @@ #include "DNA_mesh_types.h" #include "DNA_modifier_types.h" #include "DNA_linestyle_types.h" +#include "DNA_actuator_types.h" #include "DNA_genfile.h" @@ -310,6 +311,29 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } + if (!MAIN_VERSION_ATLEAST(main, 271, 2)) { + /* init up & track axis property of trackto actuators */ + Object *ob; + + for (ob = main->object.first; ob; ob = ob->id.next) { + bActuator *act; + for (act = ob->actuators.first; act; act = act->next) { + if (act->type == ACT_EDIT_OBJECT) { + bEditObjectActuator *eoact = act->data; + eoact->trackflag = ob->trackflag; + /* if trackflag is pointing +-Z axis then upflag should point Y axis. + * Rest of trackflag cases, upflag should be point z axis */ + if ((ob->trackflag == OB_POSZ) || (ob->trackflag == OB_NEGZ)) { + eoact->upflag = 1; + } + else { + eoact->upflag = 2; + } + } + } + } + } + if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) { Scene *scene; for (scene = main->scene.first; scene; scene = scene->id.next) { diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index b52d6265800..c3a3dda2c47 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -1720,6 +1720,12 @@ static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr) sub = uiLayoutSplit(split, 0.7f, false); uiItemR(sub, ptr, "time", 0, NULL, ICON_NONE); uiItemR(sub, ptr, "use_3d_tracking", UI_ITEM_R_TOGGLE, NULL, ICON_NONE); + + row = uiLayoutRow(layout, false); + uiItemR(row, ptr, "up_axis", 0, NULL, ICON_NONE); + + row = uiLayoutRow(layout, false); + uiItemR(row, ptr, "track_axis", 0, NULL, ICON_NONE); break; case ACT_EDOB_DYNAMICS: if (ob->type != OB_MESH) { diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index 5ab799a75e5..7698d671117 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -97,6 +97,8 @@ typedef struct bEditObjectActuator { float mass; short localflag; /* flag for the lin & ang. vel: apply locally */ short dyn_operation; + short upflag, trackflag; /* flag for up axis and track axis */ + int pad; } bEditObjectActuator; typedef struct bSceneActuator { @@ -439,6 +441,19 @@ typedef struct bActuator { /* editObjectActuator->flag */ #define ACT_TRACK_3D 1 +/* editObjectActuator->upflag */ +#define ACT_TRACK_UP_X 0 +#define ACT_TRACK_UP_Y 1 +#define ACT_TRACK_UP_Z 2 + +/* editObjectActuator->trackflag */ +#define ACT_TRACK_TRAXIS_X 0 +#define ACT_TRACK_TRAXIS_Y 1 +#define ACT_TRACK_TRAXIS_Z 2 +#define ACT_TRACK_TRAXIS_NEGX 3 +#define ACT_TRACK_TRAXIS_NEGY 4 +#define ACT_TRACK_TRAXIS_NEGZ 5 + /* editObjectActuator->flag for replace mesh actuator */ #define ACT_EDOB_REPLACE_MESH_NOGFX 2 /* use for replace mesh actuator */ #define ACT_EDOB_REPLACE_MESH_PHYS 4 diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c index 62e681d1374..9d26978d098 100644 --- a/source/blender/makesrna/intern/rna_actuator.c +++ b/source/blender/makesrna/intern/rna_actuator.c @@ -1369,6 +1369,23 @@ static void rna_def_edit_object_actuator(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem prop_track_axis_items[] = { + {ACT_TRACK_TRAXIS_X, "TRACKAXISX", 0, "X axis", ""}, + {ACT_TRACK_TRAXIS_Y, "TRACKAXISY", 0, "Y axis", ""}, + {ACT_TRACK_TRAXIS_Z, "TRACKAXISZ", 0, "Z axis", ""}, + {ACT_TRACK_TRAXIS_NEGX, "TRACKAXISNEGX", 0, "-X axis", ""}, + {ACT_TRACK_TRAXIS_NEGY, "TRACKAXISNEGY", 0, "-Y axis", ""}, + {ACT_TRACK_TRAXIS_NEGZ, "TRACKAXISNEGZ", 0, "-Z axis", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem prop_up_axis_items[] = { + {ACT_TRACK_UP_X, "UPAXISX", 0, "X axis", ""}, + {ACT_TRACK_UP_Y, "UPAXISY", 0, "Y axis", ""}, + {ACT_TRACK_UP_Z, "UPAXISZ", 0, "Z axis", ""}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "EditObjectActuator", "Actuator"); RNA_def_struct_ui_text(srna, "Edit Object Actuator", "Actuator used to edit objects"); RNA_def_struct_sdna_from(srna, "bEditObjectActuator", "data"); @@ -1385,6 +1402,18 @@ static void rna_def_edit_object_actuator(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Dynamic Operation", ""); RNA_def_property_update(prop, NC_LOGIC, NULL); + prop = RNA_def_property(srna, "up_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "upflag"); + RNA_def_property_enum_items(prop, prop_up_axis_items); + RNA_def_property_ui_text(prop, "Up Axis", "The axis that points upward"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + + prop = RNA_def_property(srna, "track_axis", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "trackflag"); + RNA_def_property_enum_items(prop, prop_track_axis_items); + RNA_def_property_ui_text(prop, "Track Axis", "The axis that points to the target object"); + RNA_def_property_update(prop, NC_LOGIC, NULL); + prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Object"); RNA_def_property_pointer_sdna(prop, NULL, "ob"); diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp index 45fc11b97d2..f6ed3366625 100644 --- a/source/gameengine/Converter/KX_ConvertActuators.cpp +++ b/source/gameengine/Converter/KX_ConvertActuators.cpp @@ -538,8 +538,8 @@ void BL_ConvertActuators(const char* maggiename, originalval, editobact->time, editobact->flag, - blenderobject->trackflag, - blenderobject->upflag); + editobact->trackflag, + editobact->upflag); baseact = tmptrackact; break; } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index fa52fab06fc..bbf9f427a6c 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -88,6 +88,7 @@ extern "C" { #include "KX_SteeringActuator.h" #include "KX_NavMeshObject.h" #include "KX_MouseActuator.h" +#include "KX_TrackToActuator.h" #include "SCA_IInputDevice.h" #include "SCA_PropertySensor.h" @@ -1754,6 +1755,17 @@ PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_Y, KX_RaySensor::KX_RAY_AXIS_NEG_Y); KX_MACRO_addTypesToDict(d, KX_RAY_AXIS_NEG_Z, KX_RaySensor::KX_RAY_AXIS_NEG_Z); + /* TrackTo Actuator */ + KX_MACRO_addTypesToDict(d, KX_TRACK_UPAXIS_POS_X, KX_TrackToActuator::KX_TRACK_UPAXIS_POS_X); + KX_MACRO_addTypesToDict(d, KX_TRACK_UPAXIS_POS_Y, KX_TrackToActuator::KX_TRACK_UPAXIS_POS_Y); + KX_MACRO_addTypesToDict(d, KX_TRACK_UPAXIS_POS_Z, KX_TrackToActuator::KX_TRACK_UPAXIS_POS_Z); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_POS_X, KX_TrackToActuator::KX_TRACK_TRAXIS_POS_X); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_POS_Y, KX_TrackToActuator::KX_TRACK_TRAXIS_POS_Y); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_POS_Z, KX_TrackToActuator::KX_TRACK_TRAXIS_POS_Z); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_NEG_X, KX_TrackToActuator::KX_TRACK_TRAXIS_NEG_X); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_NEG_Y, KX_TrackToActuator::KX_TRACK_TRAXIS_NEG_Y); + KX_MACRO_addTypesToDict(d, KX_TRACK_TRAXIS_NEG_Z, KX_TrackToActuator::KX_TRACK_TRAXIS_NEG_Z); + /* Dynamic actuator */ KX_MACRO_addTypesToDict(d, KX_DYN_RESTORE_DYNAMICS, KX_SCA_DynamicActuator::KX_DYN_RESTORE_DYNAMICS); KX_MACRO_addTypesToDict(d, KX_DYN_DISABLE_DYNAMICS, KX_SCA_DynamicActuator::KX_DYN_DISABLE_DYNAMICS); diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp index 90b7850946b..75baf5fac1d 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -31,8 +31,7 @@ * Replace the mesh for this actuator's parent */ -/* todo: not all trackflags / upflags are implemented/tested ! - * m_trackflag is used to determine the forward tracking direction +/* m_trackflag is used to determine the forward tracking direction * m_upflag for the up direction * normal situation is +y for forward, +z for up */ @@ -177,7 +176,77 @@ static MT_Matrix3x3 matrix3x3_interpol(MT_Matrix3x3 oldmat, MT_Matrix3x3 mat, in return EulToMat3(eul); } +static float basis_cross(int n, int m) +{ + switch (n - m) { + case 1: + case -2: + return 1.0f; + + case -1: + case 2: + return -1.0f; + + default: + return 0.0f; + } +} +/* vectomat function obtained from constrain.c and modified to work with MOTO library */ +static MT_Matrix3x3 vectomat(MT_Vector3 vec, short axis, short upflag, short threedimup) +{ + MT_Matrix3x3 mat; + MT_Vector3 y(MT_Scalar(0.0), MT_Scalar(1.0), MT_Scalar(0.0)); + MT_Vector3 z(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(1.0)); /* world Z axis is the global up axis */ + MT_Vector3 proj; + MT_Vector3 right; + MT_Scalar mul; + int right_index; + + /* Normalized Vec vector*/ + vec = vec.safe_normalized_vec(z); + + /* if 2D doesn't move the up vector */ + if (!threedimup){ + vec.setValue(MT_Scalar(vec[0]), MT_Scalar(vec[1]), MT_Scalar(0.0)); + vec = (vec - z.dot(vec)*z).safe_normalized_vec(z); + } + + if (axis > 2) + axis -= 3; + else + vec = -vec; + + /* project the up vector onto the plane specified by vec */ + /* first z onto vec... */ + mul = z.dot(vec) / vec.dot(vec); + proj = vec * mul; + /* then onto the plane */ + proj = z - proj; + /* proj specifies the transformation of the up axis */ + proj = proj.safe_normalized_vec(y); + + /* Normalized cross product of vec and proj specifies transformation of the right axis */ + right = proj.cross(vec); + right.normalize(); + + if (axis != upflag) { + right_index = 3 - axis - upflag; + + /* account for up direction, track direction */ + right = right * basis_cross(axis, upflag); + mat.setRow(right_index, right); + mat.setRow(upflag, proj); + mat.setRow(axis, vec); + mat = mat.inverse(); + } + /* identity matrix - don't do anything if the two axes are the same */ + else { + mat.setIdentity(); + } + + return mat; +} KX_TrackToActuator::~KX_TrackToActuator() { @@ -247,153 +316,24 @@ bool KX_TrackToActuator::Update(double curtime, bool frame) else if (m_object) { KX_GameObject* curobj = (KX_GameObject*) GetParent(); - MT_Vector3 dir = ((KX_GameObject*)m_object)->NodeGetWorldPosition() - curobj->NodeGetWorldPosition(); - if (dir.length2()) - dir.normalize(); - MT_Vector3 up(0,0,1); - - -#ifdef DSADSA - switch (m_upflag) - { - case 0: - { - up.setValue(1.0,0,0); - break; - } - case 1: - { - up.setValue(0,1.0,0); - break; - } - case 2: - default: - { - up.setValue(0,0,1.0); - } - } -#endif - if (m_allow3D) - { - up = (up - up.dot(dir) * dir).safe_normalized(); - - } - else - { - dir = (dir - up.dot(dir)*up).safe_normalized(); - } - - MT_Vector3 left; + MT_Vector3 dir = curobj->NodeGetWorldPosition() - ((KX_GameObject*)m_object)->NodeGetWorldPosition(); MT_Matrix3x3 mat; - - switch (m_trackflag) - { - case 0: // TRACK X - { - // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = dir.safe_normalized(); - dir = up.cross(left).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - - break; - }; - case 1: // TRACK Y - { - // (0.0 , 1.0 , 0.0 ) y direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = (dir.cross(up)).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - - break; - } - - case 2: // track Z - { - left = up.safe_normalized(); - up = dir.safe_normalized(); - dir = left; - left = (dir.cross(up)).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - break; - } - - case 3: // TRACK -X - { - // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = -dir.safe_normalized(); - dir = up.cross(left).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - - break; - }; - case 4: // TRACK -Y - { - // (0.0 , -1.0 , 0.0 ) -y direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = (-dir.cross(up)).safe_normalized(); - mat.setValue ( - left[0], -dir[0],up[0], - left[1], -dir[1],up[1], - left[2], -dir[2],up[2] - ); - break; - } - case 5: // track -Z - { - left = up.safe_normalized(); - up = -dir.safe_normalized(); - dir = left; - left = (dir.cross(up)).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - - break; - } - - default: - { - // (1.0 , 0.0 , 0.0 ) -x direction is forward, z (0.0 , 0.0 , 1.0 ) up - left = -dir.safe_normalized(); - dir = up.cross(left).safe_normalized(); - mat.setValue ( - left[0], dir[0],up[0], - left[1], dir[1],up[1], - left[2], dir[2],up[2] - ); - } - } - MT_Matrix3x3 oldmat; - oldmat= curobj->NodeGetWorldOrientation(); + + mat = vectomat(dir, m_trackflag, m_upflag, m_allow3D); + oldmat = curobj->NodeGetWorldOrientation(); /* erwin should rewrite this! */ - mat= matrix3x3_interpol(oldmat, mat, m_time); + mat = matrix3x3_interpol(oldmat, mat, m_time); - - if (m_parentobj) { // check if the model is parented and calculate the child transform + /* check if the model is parented and calculate the child transform */ + if (m_parentobj) { MT_Point3 localpos; localpos = curobj->GetSGNode()->GetLocalPosition(); // Get the inverse of the parent matrix MT_Matrix3x3 parentmatinv; - parentmatinv = m_parentobj->NodeGetWorldOrientation ().inverse (); + parentmatinv = m_parentobj->NodeGetWorldOrientation().inverse(); // transform the local coordinate system into the parents system mat = parentmatinv * mat; // append the initial parent local rotation matrix @@ -404,8 +344,7 @@ bool KX_TrackToActuator::Update(double curtime, bool frame) curobj->NodeSetLocalPosition(localpos); //curobj->UpdateTransform(); } - else - { + else { curobj->NodeSetLocalOrientation(mat); } @@ -451,6 +390,8 @@ PyMethodDef KX_TrackToActuator::Methods[] = { PyAttributeDef KX_TrackToActuator::Attributes[] = { KX_PYATTRIBUTE_INT_RW("time",0,1000,true,KX_TrackToActuator,m_time), KX_PYATTRIBUTE_BOOL_RW("use3D",KX_TrackToActuator,m_allow3D), + KX_PYATTRIBUTE_INT_RW("upAxis", 0, 2, true, KX_TrackToActuator,m_upflag), + KX_PYATTRIBUTE_INT_RW("trackAxis", 0, 5, true, KX_TrackToActuator,m_trackflag), KX_PYATTRIBUTE_RW_FUNCTION("object", KX_TrackToActuator, pyattr_get_object, pyattr_set_object), { NULL } //Sentinel diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index 4df240a0063..124014eede2 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -68,6 +68,21 @@ class KX_TrackToActuator : public SCA_IActuator virtual void Relink(CTR_Map *obj_map); virtual bool Update(double curtime, bool frame); + //Python Interface + enum UpAxis { + KX_TRACK_UPAXIS_POS_X = 0, + KX_TRACK_UPAXIS_POS_Y, + KX_TRACK_UPAXIS_POS_Z + }; + enum TrackAxis { + KX_TRACK_TRAXIS_POS_X = 0, + KX_TRACK_TRAXIS_POS_Y, + KX_TRACK_TRAXIS_POS_Z, + KX_TRACK_TRAXIS_NEG_X, + KX_TRACK_TRAXIS_NEG_Y, + KX_TRACK_TRAXIS_NEG_Z + }; + #ifdef WITH_PYTHON /* Python part */ -- cgit v1.2.3