Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h2
-rw-r--r--source/blender/src/buttons_logic.c40
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp34
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp110
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.h12
5 files changed, 193 insertions, 5 deletions
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 2487216f764..0af1ec0a2c7 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -369,6 +369,7 @@ typedef struct FreeCamera {
#define ACT_CONST_PERMANENT 256
#define ACT_CONST_DISTANCE 512
#define ACT_CONST_LOCAL 1024
+#define ACT_CONST_DOROTFH 2048
/* constraint mode */
#define ACT_CONST_DIRPX 1
@@ -382,6 +383,7 @@ typedef struct FreeCamera {
#define ACT_CONST_TYPE_LOC 0
#define ACT_CONST_TYPE_DIST 1
#define ACT_CONST_TYPE_ORI 2
+#define ACT_CONST_TYPE_FH 3
/* editObjectActuator->type */
#define ACT_EDOB_ADD_OBJECT 0
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index ba8116dbc5b..052bf3f1ae4 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -2214,8 +2214,46 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
uiDefButF(block, NUM, 0, "min", xco+80, yco-84, (width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in degree) to maintain with target direction. No correction is done if angle with target direction is between min and max");
uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle (in degree) allowed with target direction. No correction is done if angle with target direction is between min and max");
+ } else if (coa->type == ACT_CONST_TYPE_FH) {
+ ysize= 106;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+
+ str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32";
+ uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray (in world coordinate)");
+
+ if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc;
+ else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1;
+ else fp= coa->minloc+2;
+
+ uiDefButF(block, NUM, 0, "damp", xco+10, yco-45, (width-70)/2, 19, &coa->maxrot[0], 0.0, 1.0, 1, 0, "Damping factor of the Fh spring force");
+ uiDefButF(block, NUM, 0, "dist", xco+10+(width-70)/2, yco-45, (width-70)/2, 19, fp, 0.010, 2000.0, 10, 0, "Height of the Fh area");
+ uiDefButBitS(block, TOG, ACT_CONST_DOROTFH, 0, "Rot Fh", xco+10+(width-70), yco-45, 50, 19, &coa->flag, 0.0, 0.0, 0, 0, "Keep object axis parallel to normal");
+
+ uiDefButF(block, NUMSLI, 0, "Fh ", xco+80, yco-65, (width-115), 19, fp+3, 0.0, 1.0, 0, 0, "Spring force within the Fh area");
+ uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19,
+ &coa->flag, 0.0, 0.0, 0, 0, "Add a horizontal spring force on slopes");
+ uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19,
+ &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property");
+ if (coa->flag & ACT_CONST_MATERIAL)
+ {
+ uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19,
+ coa->matprop, 0, 31, 0, 0,
+ "Ray detects only Objects with this material");
+ }
+ else
+ {
+ uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19,
+ coa->matprop, 0, 31, 0, 0,
+ "Ray detect only Objects with this property");
+ }
+ uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19,
+ &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target");
+ uiDefButS(block, NUM, 0, "time", xco+50, yco-103, 90, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
+ uiDefButF(block, NUM, 0, "rotDamp", xco+140, yco-103, (width-150), 19, &coa->maxrot[1], 0.0, 1.0, 1, 0, "Use a different damping for rotation");
}
- str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2";
+ str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2|Force field %x3";
but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, "");
yco-= ysize;
break;
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 78791c53d7c..b739e3b2094 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -719,6 +719,40 @@ void BL_ConvertActuators(char* maggiename,
break;
}
prop = conact->matprop;
+ } else if (conact->type == ACT_CONST_TYPE_FH) {
+ switch (conact->mode) {
+ case ACT_CONST_DIRPX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPX;
+ min = conact->minloc[0];
+ max = conact->maxloc[0];
+ break;
+ case ACT_CONST_DIRPY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPY;
+ min = conact->minloc[1];
+ max = conact->maxloc[1];
+ break;
+ case ACT_CONST_DIRPZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHPZ;
+ min = conact->minloc[2];
+ max = conact->maxloc[2];
+ break;
+ case ACT_CONST_DIRNX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNX;
+ min = conact->minloc[0];
+ max = conact->maxloc[0];
+ break;
+ case ACT_CONST_DIRNY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNY;
+ min = conact->minloc[1];
+ max = conact->maxloc[1];
+ break;
+ case ACT_CONST_DIRNZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_FHNZ;
+ min = conact->minloc[2];
+ max = conact->maxloc[2];
+ break;
+ }
+ prop = conact->matprop;
} else {
switch (conact->flag) {
case ACT_CONST_LOCX:
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index 49534ccbd4a..0210f78425e 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -112,7 +112,7 @@ KX_ConstraintActuator::~KX_ConstraintActuator()
bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data)
{
- KX_GameObject* hitKXObj = client->m_gameobject;
+ m_hitObject = client->m_gameobject;
bool bFound = false;
@@ -131,7 +131,7 @@ bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo* client, KX_RayCast* resu
}
else
{
- bFound = hitKXObj->GetProperty(m_property) != NULL;
+ bFound = m_hitObject->GetProperty(m_property) != NULL;
}
}
// update the hit status
@@ -372,7 +372,7 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
// logically we should cancel the speed along the ray direction as we set the
// position along that axis
spc = obj->GetPhysicsController();
- if (spc) {
+ if (spc && spc->IsDyna()) {
MT_Vector3 linV = spc->GetLinearVelocity();
// cancel the projection along the ray direction
MT_Scalar fallspeed = linV.dot(direction);
@@ -390,6 +390,110 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
}
}
break;
+ case KX_ACT_CONSTRAINT_FHPX:
+ case KX_ACT_CONSTRAINT_FHPY:
+ case KX_ACT_CONSTRAINT_FHPZ:
+ case KX_ACT_CONSTRAINT_FHNX:
+ case KX_ACT_CONSTRAINT_FHNY:
+ case KX_ACT_CONSTRAINT_FHNZ:
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_FHPX:
+ normal[0] = -rotation[0][0];
+ normal[1] = -rotation[1][0];
+ normal[2] = -rotation[2][0];
+ direction = MT_Vector3(1.0,0.0,0.0);
+ break;
+ case KX_ACT_CONSTRAINT_FHPY:
+ normal[0] = -rotation[0][1];
+ normal[1] = -rotation[1][1];
+ normal[2] = -rotation[2][1];
+ direction = MT_Vector3(0.0,1.0,0.0);
+ break;
+ case KX_ACT_CONSTRAINT_FHPZ:
+ normal[0] = -rotation[0][2];
+ normal[1] = -rotation[1][2];
+ normal[2] = -rotation[2][2];
+ direction = MT_Vector3(0.0,0.0,1.0);
+ break;
+ case KX_ACT_CONSTRAINT_FHNX:
+ normal[0] = rotation[0][0];
+ normal[1] = rotation[1][0];
+ normal[2] = rotation[2][0];
+ direction = MT_Vector3(-1.0,0.0,0.0);
+ break;
+ case KX_ACT_CONSTRAINT_FHNY:
+ normal[0] = rotation[0][1];
+ normal[1] = rotation[1][1];
+ normal[2] = rotation[2][1];
+ direction = MT_Vector3(0.0,-1.0,0.0);
+ break;
+ case KX_ACT_CONSTRAINT_FHNZ:
+ normal[0] = rotation[0][2];
+ normal[1] = rotation[1][2];
+ normal[2] = rotation[2][2];
+ direction = MT_Vector3(0.0,0.0,-1.0);
+ break;
+ }
+ normal.normalize();
+ {
+ PHY_IPhysicsEnvironment* pe = obj->GetPhysicsEnvironment();
+ KX_IPhysicsController *spc = obj->GetPhysicsController();
+
+ if (!pe) {
+ std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no physics environment!" << std::endl;
+ goto CHECK_TIME;
+ }
+ if (!spc || !spc->IsDyna()) {
+ // the object is not dynamic, it won't support setting speed
+ goto CHECK_TIME;
+ }
+ m_hitObject = NULL;
+ // distance of Fh area is stored in m_minimum
+ MT_Point3 topoint = position + (m_minimumBound+spc->GetRadius()) * direction;
+ KX_RayCast::Callback<KX_ConstraintActuator> callback(this,spc);
+ result = KX_RayCast::RayTest(pe, position, topoint, callback);
+ // we expect a hit object
+ if (!m_hitObject)
+ result = false;
+ if (result)
+ {
+ MT_Vector3 newnormal = callback.m_hitNormal;
+ // compute new position & orientation
+ MT_Scalar distance = (callback.m_hitPoint-position).length()-spc->GetRadius();
+ // estimate the velocity of the hit point
+ MT_Point3 relativeHitPoint;
+ relativeHitPoint = (callback.m_hitPoint-m_hitObject->NodeGetWorldPosition());
+ MT_Vector3 velocityHitPoint = m_hitObject->GetVelocity(relativeHitPoint);
+ MT_Vector3 relativeVelocity = spc->GetLinearVelocity() - velocityHitPoint;
+ MT_Scalar relativeVelocityRay = direction.dot(relativeVelocity);
+ MT_Scalar springExtent = 1.0 - distance/m_minimumBound;
+ // Fh force is stored in m_maximum
+ MT_Scalar springForce = springExtent * m_maximumBound;
+ // damping is stored in m_refDirection [0] = damping, [1] = rot damping
+ MT_Scalar springDamp = relativeVelocityRay * m_refDirection[0];
+ MT_Vector3 newVelocity = spc->GetLinearVelocity()-(springForce+springDamp)*direction;
+ if (m_option & KX_ACT_CONSTRAINT_NORMAL)
+ {
+ newVelocity+=(springForce+springDamp)*(newnormal-newnormal.dot(direction)*direction);
+ }
+ spc->SetLinearVelocity(newVelocity, false);
+ if (m_option & KX_ACT_CONSTRAINT_DOROTFH)
+ {
+ MT_Vector3 angSpring = (normal.cross(newnormal))*m_maximumBound;
+ MT_Vector3 angVelocity = spc->GetAngularVelocity();
+ // remove component that is parallel to normal
+ angVelocity -= angVelocity.dot(newnormal)*newnormal;
+ MT_Vector3 angDamp = angVelocity * ((m_refDirection[1]>MT_EPSILON)?m_refDirection[1]:m_refDirection[0]);
+ spc->SetAngularVelocity(spc->GetAngularVelocity()+(angSpring-angDamp), false);
+ }
+ } else if (m_option & KX_ACT_CONSTRAINT_PERMANENT) {
+ // no contact but still keep running
+ result = true;
+ }
+ // don't set the position with this constraint
+ goto CHECK_TIME;
+ }
+ break;
case KX_ACT_CONSTRAINT_LOCX:
case KX_ACT_CONSTRAINT_LOCY:
case KX_ACT_CONSTRAINT_LOCZ:
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h
index b2ef0dae553..28b9b1e6a0b 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.h
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h
@@ -38,6 +38,7 @@
#include "KX_ClientObjectInfo.h"
class KX_RayCast;
+class KX_GameObject;
class KX_ConstraintActuator : public SCA_IActuator
{
@@ -65,6 +66,8 @@ protected:
int m_option;
// property to check
char m_property[32];
+ // hit object
+ KX_GameObject* m_hitObject;
/**
* Clamp <var> to <min>, <max>. Borders are included (in as far as
@@ -92,6 +95,12 @@ protected:
KX_ACT_CONSTRAINT_ORIX,
KX_ACT_CONSTRAINT_ORIY,
KX_ACT_CONSTRAINT_ORIZ,
+ KX_ACT_CONSTRAINT_FHPX,
+ KX_ACT_CONSTRAINT_FHPY,
+ KX_ACT_CONSTRAINT_FHPZ,
+ KX_ACT_CONSTRAINT_FHNX,
+ KX_ACT_CONSTRAINT_FHNY,
+ KX_ACT_CONSTRAINT_FHNZ,
KX_ACT_CONSTRAINT_MAX
};
// match ACT_CONST_... values from BIF_interface.h
@@ -100,7 +109,8 @@ protected:
KX_ACT_CONSTRAINT_MATERIAL = 128,
KX_ACT_CONSTRAINT_PERMANENT = 256,
KX_ACT_CONSTRAINT_DISTANCE = 512,
- KX_ACT_CONSTRAINT_LOCAL = 1024
+ KX_ACT_CONSTRAINT_LOCAL = 1024,
+ KX_ACT_CONSTRAINT_DOROTFH = 2048
};
bool IsValidMode(KX_CONSTRAINTTYPE m);
bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);