BGE: New Mouse Actuator
Disclaimer: The author of this patch is Geoffrey Gollmer (gomer). I only updated the patch to the current git master status, reworked several parts to fit well with current coding style and applied several fixes.
This actuator allows users to show/hide the mouse cursor using logic bricks, as well as control object rotation with a mouse in the BGE.
The mouse rotation is flexible enough to allow any type of mouse look, as well as banking for flight controls.
{F94520}
{F91859}
Blend file for testing Mouse actuator (with default parameters and crosshair): {F94920}
Reviewers: moguri
Reviewed By: moguri
CC: gomer, lordodin
Differential Revision: https://developer.blender.org/D559
This commit is contained in:
@@ -72,6 +72,7 @@ See the actuator's reference for available methods
|
||||
* :class:`~bge.types.KX_CameraActuator`
|
||||
* :class:`~bge.types.KX_ConstraintActuator`
|
||||
* :class:`~bge.types.KX_GameActuator`
|
||||
* :class:`~bge.types.KX_MouseActuator`
|
||||
* :class:`~bge.types.KX_NetworkMessageActuator`
|
||||
* :class:`~bge.types.KX_ObjectActuator`
|
||||
* :class:`~bge.types.KX_ParentActuator`
|
||||
@@ -764,6 +765,16 @@ See :class:`bge.types.KX_GameActuator`
|
||||
.. data:: KX_GAME_SAVECFG
|
||||
.. data:: KX_GAME_LOADCFG
|
||||
|
||||
.. _mouse-actuator:
|
||||
|
||||
---------------
|
||||
Mouse Actuator
|
||||
---------------
|
||||
|
||||
.. data:: KX_ACT_MOUSE_OBJECT_AXIS_X
|
||||
.. data:: KX_ACT_MOUSE_OBJECT_AXIS_Y
|
||||
.. data:: KX_ACT_MOUSE_OBJECT_AXIS_Z
|
||||
|
||||
---------------
|
||||
Parent Actuator
|
||||
---------------
|
||||
|
||||
103
doc/python_api/rst/bge_types/bge.types.KX_MouseActuator.rst
Normal file
103
doc/python_api/rst/bge_types/bge.types.KX_MouseActuator.rst
Normal file
@@ -0,0 +1,103 @@
|
||||
KX_MouseActuator(SCA_IActuator)
|
||||
====================================
|
||||
|
||||
.. module:: bge.types
|
||||
|
||||
base class --- :class:`SCA_IActuator`
|
||||
|
||||
.. class:: KX_MouseActuator(SCA_IActuator)
|
||||
|
||||
The mouse actuator gives control over the visibility of the mouse cursor and rotates the parent object according to mouse movement.
|
||||
|
||||
.. method:: reset()
|
||||
|
||||
Undoes the rotation caused by the mouse actuator.
|
||||
|
||||
.. attribute:: visible
|
||||
|
||||
The visibility of the mouse cursor.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: use_axis_x
|
||||
|
||||
Mouse movement along the x axis effects object rotation.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: use_axis_y
|
||||
|
||||
Mouse movement along the y axis effects object rotation.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: threshold
|
||||
|
||||
Amount of movement from the mouse required before rotation is triggered.
|
||||
|
||||
:type: list (vector of 2 floats)
|
||||
|
||||
The values in the list should be between 0.0 and 0.5.
|
||||
|
||||
.. attribute:: reset_x
|
||||
|
||||
Mouse is locked to the center of the screen on the x axis.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: reset_y
|
||||
|
||||
Mouse is locked to the center of the screen on the y axis.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: object_axis
|
||||
|
||||
The object's 3D axis to rotate with the mouse movement. ([x, y])
|
||||
|
||||
:type: list (vector of 2 integers from 0 to 2)
|
||||
|
||||
* KX_ACT_MOUSE_OBJECT_AXIS_X
|
||||
* KX_ACT_MOUSE_OBJECT_AXIS_Y
|
||||
* KX_ACT_MOUSE_OBJECT_AXIS_Z
|
||||
|
||||
.. attribute:: local_x
|
||||
|
||||
Rotation caused by mouse movement along the x axis is local.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: local_y
|
||||
|
||||
Rotation caused by mouse movement along the y axis is local.
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: sensitivity
|
||||
|
||||
The amount of rotation caused by mouse movement along the x and y axis.
|
||||
|
||||
:type: list (vector of 2 floats)
|
||||
|
||||
Negative values invert the rotation.
|
||||
|
||||
.. attribute:: limit_x
|
||||
|
||||
The minimum and maximum angle of rotation caused by mouse movement along the x axis in degrees.
|
||||
limit_x[0] is minimum, limit_x[1] is maximum.
|
||||
|
||||
:type: list (vector of 2 floats)
|
||||
|
||||
.. attribute:: limit_y
|
||||
|
||||
The minimum and maximum angle of rotation caused by mouse movement along the y axis in degrees.
|
||||
limit_y[0] is minimum, limit_y[1] is maximum.
|
||||
|
||||
:type: list (vector of 2 floats)
|
||||
|
||||
.. attribute:: angle
|
||||
|
||||
The current rotational offset caused by the mouse actuator in degrees.
|
||||
|
||||
:type: list (vector of 2 floats)
|
||||
|
||||
@@ -391,6 +391,7 @@ void init_actuator(bActuator *act)
|
||||
bSoundActuator *sa;
|
||||
bSteeringActuator *sta;
|
||||
bArmatureActuator *arma;
|
||||
bMouseActuator *ma;
|
||||
|
||||
if (act->data) MEM_freeN(act->data);
|
||||
act->data= NULL;
|
||||
@@ -477,6 +478,15 @@ void init_actuator(bActuator *act)
|
||||
sta->flag = ACT_STEERING_AUTOMATICFACING;
|
||||
sta->facingaxis = 1;
|
||||
break;
|
||||
case ACT_MOUSE:
|
||||
ma = act->data = MEM_callocN(sizeof( bMouseActuator ), "mouse act");
|
||||
ma->flag = ACT_MOUSE_VISIBLE|ACT_MOUSE_USE_AXIS_X|ACT_MOUSE_USE_AXIS_Y|ACT_MOUSE_RESET_X|ACT_MOUSE_RESET_Y|ACT_MOUSE_LOCAL_Y;
|
||||
ma->sensitivity[0] = ma->sensitivity[1] = 2.f;
|
||||
ma->object_axis[0] = ACT_MOUSE_OBJECT_AXIS_Z;
|
||||
ma->object_axis[1] = ACT_MOUSE_OBJECT_AXIS_X;
|
||||
ma->limit_y[0] = DEG2RADF(-90.0f);
|
||||
ma->limit_y[1] = DEG2RADF(90.0f);
|
||||
break;
|
||||
default:
|
||||
; /* this is very severe... I cannot make any memory for this */
|
||||
/* logic brick... */
|
||||
|
||||
@@ -4450,6 +4450,9 @@ static void lib_link_object(FileData *fd, Main *main)
|
||||
steeringa->target = newlibadr(fd, ob->id.lib, steeringa->target);
|
||||
steeringa->navmesh = newlibadr(fd, ob->id.lib, steeringa->navmesh);
|
||||
}
|
||||
else if(act->type == ACT_MOUSE) {
|
||||
/* bMouseActuator *moa= act->data; */
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -1237,6 +1237,9 @@ static void write_actuators(WriteData *wd, ListBase *lb)
|
||||
case ACT_STEERING:
|
||||
writestruct(wd, DATA, "bSteeringActuator", 1, act->data);
|
||||
break;
|
||||
case ACT_MOUSE:
|
||||
writestruct(wd, DATA, "bMouseActuator", 1, act->data);
|
||||
break;
|
||||
default:
|
||||
; /* error: don't know how to write this file */
|
||||
}
|
||||
|
||||
@@ -519,6 +519,8 @@ static const char *actuator_name(int type)
|
||||
return N_("Armature");
|
||||
case ACT_STEERING:
|
||||
return N_("Steering");
|
||||
case ACT_MOUSE:
|
||||
return N_("Mouse");
|
||||
}
|
||||
return N_("Unknown");
|
||||
}
|
||||
@@ -2177,6 +2179,68 @@ static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr)
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_actuator_mouse(uiLayout *layout, PointerRNA *ptr)
|
||||
{
|
||||
uiLayout *row, *col, *subcol, *split, *subsplit;
|
||||
|
||||
uiItemR(layout, ptr, "mode", 0, NULL, 0);
|
||||
|
||||
switch (RNA_enum_get(ptr, "mode")) {
|
||||
case ACT_MOUSE_VISIBILITY:
|
||||
row = uiLayoutRow(layout, 0);
|
||||
uiItemR(row, ptr, "visible", UI_ITEM_R_TOGGLE, NULL, 0);
|
||||
break;
|
||||
|
||||
case ACT_MOUSE_LOOK:
|
||||
/* X axis */
|
||||
row = uiLayoutRow(layout, 0);
|
||||
col = uiLayoutColumn(row, 1);
|
||||
|
||||
uiItemR(col, ptr, "use_axis_x", UI_ITEM_R_TOGGLE, NULL, 0);
|
||||
|
||||
subcol = uiLayoutColumn(col, 1);
|
||||
uiLayoutSetActive(subcol, RNA_boolean_get(ptr, "use_axis_x")==1);
|
||||
uiItemR(subcol, ptr, "sensitivity_x", 0, NULL, 0);
|
||||
uiItemR(subcol, ptr, "threshold_x", 0, NULL, 0);
|
||||
|
||||
uiItemR(subcol, ptr, "min_x", 0, NULL, 0);
|
||||
uiItemR(subcol, ptr, "max_x", 0, NULL, 0);
|
||||
|
||||
uiItemR(subcol, ptr, "object_axis_x", 0, NULL, 0);
|
||||
|
||||
/* Y Axis */
|
||||
col = uiLayoutColumn(row, 1);
|
||||
|
||||
uiItemR(col, ptr, "use_axis_y", UI_ITEM_R_TOGGLE, NULL, 0);
|
||||
|
||||
subcol = uiLayoutColumn(col, 1);
|
||||
uiLayoutSetActive(subcol, RNA_boolean_get(ptr, "use_axis_y")==1);
|
||||
uiItemR(subcol, ptr, "sensitivity_y", 0, NULL, 0);
|
||||
uiItemR(subcol, ptr, "threshold_y", 0, NULL, 0);
|
||||
|
||||
uiItemR(subcol, ptr, "min_y", 0, NULL, 0);
|
||||
uiItemR(subcol, ptr, "max_y", 0, NULL, 0);
|
||||
|
||||
uiItemR(subcol, ptr, "object_axis_y", 0, NULL, 0);
|
||||
|
||||
/* Lower options */
|
||||
row = uiLayoutRow(layout, 0);
|
||||
split = uiLayoutSplit(row, 0.5, 0);
|
||||
|
||||
subsplit = uiLayoutSplit(split, 0.5, 1);
|
||||
uiLayoutSetActive(subsplit, RNA_boolean_get(ptr, "use_axis_x")==1);
|
||||
uiItemR(subsplit, ptr, "local_x", UI_ITEM_R_TOGGLE, NULL, 0);
|
||||
uiItemR(subsplit, ptr, "reset_x", UI_ITEM_R_TOGGLE, NULL, 0);
|
||||
|
||||
subsplit = uiLayoutSplit(split, 0.5, 1);
|
||||
uiLayoutSetActive(subsplit, RNA_boolean_get(ptr, "use_axis_y")==1);
|
||||
uiItemR(subsplit, ptr, "local_y", UI_ITEM_R_TOGGLE, NULL, 0);
|
||||
uiItemR(subsplit, ptr, "reset_y", UI_ITEM_R_TOGGLE, NULL, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C)
|
||||
{
|
||||
uiLayout *box;
|
||||
@@ -2241,6 +2305,10 @@ static void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C)
|
||||
break;
|
||||
case ACT_STEERING:
|
||||
draw_actuator_steering(box, ptr);
|
||||
break;
|
||||
case ACT_MOUSE:
|
||||
draw_actuator_mouse(box, ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -245,6 +245,18 @@ typedef struct bSteeringActuator {
|
||||
struct Object *navmesh;
|
||||
} bSteeringActuator;
|
||||
|
||||
typedef struct bMouseActuator {
|
||||
short type; /* 0=Visibility, 1=Look */
|
||||
short flag;
|
||||
|
||||
int object_axis[2];
|
||||
float threshold[2];
|
||||
float sensitivity[2];
|
||||
float limit_x[2];
|
||||
float limit_y[2];
|
||||
} bMouseActuator;
|
||||
|
||||
|
||||
typedef struct bActuator {
|
||||
struct bActuator *next, *prev, *mynew;
|
||||
short type;
|
||||
@@ -314,6 +326,7 @@ typedef struct bActuator {
|
||||
#define ACT_STATE 22
|
||||
#define ACT_ARMATURE 23
|
||||
#define ACT_STEERING 24
|
||||
#define ACT_MOUSE 25
|
||||
|
||||
/* actuator flag */
|
||||
#define ACT_SHOW 1
|
||||
@@ -542,4 +555,22 @@ typedef struct bActuator {
|
||||
#define ACT_STEERING_AUTOMATICFACING 4
|
||||
#define ACT_STEERING_NORMALUP 8
|
||||
|
||||
/* mouseactuator->type */
|
||||
#define ACT_MOUSE_VISIBILITY 0
|
||||
#define ACT_MOUSE_LOOK 1
|
||||
|
||||
/* mouseactuator->flag */
|
||||
#define ACT_MOUSE_VISIBLE (1 << 0)
|
||||
#define ACT_MOUSE_USE_AXIS_X (1 << 1)
|
||||
#define ACT_MOUSE_USE_AXIS_Y (1 << 2)
|
||||
#define ACT_MOUSE_RESET_X (1 << 3)
|
||||
#define ACT_MOUSE_RESET_Y (1 << 4)
|
||||
#define ACT_MOUSE_LOCAL_X (1 << 5)
|
||||
#define ACT_MOUSE_LOCAL_Y (1 << 6)
|
||||
|
||||
/* mouseactuator->object_axis */
|
||||
#define ACT_MOUSE_OBJECT_AXIS_X 0
|
||||
#define ACT_MOUSE_OBJECT_AXIS_Y 1
|
||||
#define ACT_MOUSE_OBJECT_AXIS_Z 2
|
||||
|
||||
#endif /* __DNA_ACTUATOR_TYPES_H__ */
|
||||
|
||||
@@ -55,6 +55,7 @@ static EnumPropertyItem actuator_type_items[] = {
|
||||
{ACT_2DFILTER, "FILTER_2D", 0, "Filter 2D", ""},
|
||||
{ACT_GAME, "GAME", 0, "Game", ""},
|
||||
{ACT_MESSAGE, "MESSAGE", 0, "Message", ""},
|
||||
{ACT_MOUSE, "MOUSE", 0, "Mouse", ""},
|
||||
{ACT_OBJECT, "MOTION", 0, "Motion", ""},
|
||||
{ACT_PARENT, "PARENT", 0, "Parent", ""},
|
||||
{ACT_PROPERTY, "PROPERTY", 0, "Property", ""},
|
||||
@@ -110,6 +111,8 @@ static StructRNA *rna_Actuator_refine(struct PointerRNA *ptr)
|
||||
return &RNA_ArmatureActuator;
|
||||
case ACT_STEERING:
|
||||
return &RNA_SteeringActuator;
|
||||
case ACT_MOUSE:
|
||||
return &RNA_MouseActuator;
|
||||
default:
|
||||
return &RNA_Actuator;
|
||||
}
|
||||
@@ -459,6 +462,7 @@ EnumPropertyItem *rna_Actuator_type_itemf(bContext *C, PointerRNA *ptr, Property
|
||||
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_2DFILTER);
|
||||
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_GAME);
|
||||
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_MESSAGE);
|
||||
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_MOUSE);
|
||||
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_OBJECT);
|
||||
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_PARENT);
|
||||
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_PROPERTY);
|
||||
@@ -2038,6 +2042,132 @@ static void rna_def_steering_actuator(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_mouse_actuator(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem prop_type_items[] = {
|
||||
{ACT_MOUSE_VISIBILITY, "VISIBILITY", 0, "Visibility", ""},
|
||||
{ACT_MOUSE_LOOK, "LOOK", 0, "Look", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem prop_object_axis_items[] = {
|
||||
{ACT_MOUSE_OBJECT_AXIS_X, "OBJECT_AXIS_X", 0, "X Axis", ""},
|
||||
{ACT_MOUSE_OBJECT_AXIS_Y, "OBJECT_AXIS_Y", 0, "Y Axis", ""},
|
||||
{ACT_MOUSE_OBJECT_AXIS_Z, "OBJECT_AXIS_Z", 0, "Z Axis", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "MouseActuator", "Actuator");
|
||||
RNA_def_struct_ui_text(srna, "Mouse Actuator", "Actuator to ..");
|
||||
RNA_def_struct_sdna_from(srna, "bMouseActuator", "data");
|
||||
|
||||
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "type");
|
||||
RNA_def_property_enum_items(prop, prop_type_items);
|
||||
RNA_def_property_ui_text(prop, "Mode", "");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
/* Visibility */
|
||||
prop = RNA_def_property(srna, "visible", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_MOUSE_VISIBLE);
|
||||
RNA_def_property_ui_text(prop, "Visible", "Make mouse cursor visible");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
/* Mouse Look */
|
||||
prop = RNA_def_property(srna, "use_axis_x", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_MOUSE_USE_AXIS_X);
|
||||
RNA_def_property_ui_text(prop, "Use X Axis", "Calculate mouse movement on the X axis");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_axis_y", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_MOUSE_USE_AXIS_Y);
|
||||
RNA_def_property_ui_text(prop, "Use Y Axis", "Calculate mouse movement on the Y axis");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "reset_x", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_MOUSE_RESET_X);
|
||||
RNA_def_property_ui_text(prop, "Reset", "Reset the cursor's X position to the center of the screen space after calculating");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "reset_y", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_MOUSE_RESET_Y);
|
||||
RNA_def_property_ui_text(prop, "Reset", "Reset the cursor's Y position to the center of the screen space after calculating");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "local_x", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_MOUSE_LOCAL_X);
|
||||
RNA_def_property_ui_text(prop, "Local", "Apply rotation locally");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "local_y", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", ACT_MOUSE_LOCAL_Y);
|
||||
RNA_def_property_ui_text(prop, "Local", "Apply rotation locally");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "threshold_x", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "threshold[0]");
|
||||
RNA_def_property_ui_range(prop, 0, 0.5, 1, 3);
|
||||
RNA_def_property_ui_text(prop, "Threshold", "The amount of X motion before mouse movement will register");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "threshold_y", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "threshold[1]");
|
||||
RNA_def_property_ui_range(prop, 0, 0.5, 1, 3);
|
||||
RNA_def_property_ui_text(prop, "Threshold", "The amount of Y motion before mouse movement will register");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "object_axis_x", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "object_axis[0]");
|
||||
RNA_def_property_enum_items(prop, prop_object_axis_items);
|
||||
RNA_def_property_ui_text(prop, "Obj Axis", "Local object axis mouse movement in the X direction will apply to");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "object_axis_y", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "object_axis[1]");
|
||||
RNA_def_property_enum_items(prop, prop_object_axis_items);
|
||||
RNA_def_property_ui_text(prop, "Obj Axis", "The object axis mouse movement in the Y direction will apply to");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "sensitivity_x", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "sensitivity[0]");
|
||||
RNA_def_property_ui_range(prop, -100.0, 100.0, 0.2, 3);
|
||||
RNA_def_property_ui_text(prop, "Sensitivity", "Set the sensitivity of the X axis");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "sensitivity_y", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "sensitivity[1]");
|
||||
RNA_def_property_ui_range(prop, -100.0, 100.0, 0.2, 3);
|
||||
RNA_def_property_ui_text(prop, "Sensitivity", "Set the sensitivity of the Y axis");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "min_x", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "limit_x[0]");
|
||||
RNA_def_property_ui_range(prop, DEG2RADF(-3600.0f), 0.0, 9, 3);
|
||||
RNA_def_property_ui_text(prop, "min", "The maximum negative rotation allowed by x mouse movement (0 for infinite)");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "max_x", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "limit_x[1]");
|
||||
RNA_def_property_ui_range(prop, 0.0, DEG2RADF(3600.0f), 9, 3);
|
||||
RNA_def_property_ui_text(prop, "max", "The maximum positive rotation allowed by x mouse movement (0 for infinite)");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "min_y", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "limit_y[0]");
|
||||
RNA_def_property_ui_range(prop, DEG2RADF(-3600.0f), 0.0, 9, 3);
|
||||
RNA_def_property_ui_text(prop, "min", "The maximum negative rotation allowed by y mouse movement (0 for infinite)");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "max_y", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "limit_y[1]");
|
||||
RNA_def_property_ui_range(prop, 0.0, DEG2RADF(3600.0f), 9, 3);
|
||||
RNA_def_property_ui_text(prop, "max", "The maximum positive rotation allowed by y mouse movement (0 for infinite)");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
}
|
||||
|
||||
void RNA_def_actuator(BlenderRNA *brna)
|
||||
{
|
||||
rna_def_actuator(brna);
|
||||
@@ -2059,6 +2189,7 @@ void RNA_def_actuator(BlenderRNA *brna)
|
||||
rna_def_state_actuator(brna);
|
||||
rna_def_armature_actuator(brna);
|
||||
rna_def_steering_actuator(brna);
|
||||
rna_def_mouse_actuator(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#include "KX_ParentActuator.h"
|
||||
#include "KX_SCA_DynamicActuator.h"
|
||||
#include "KX_SteeringActuator.h"
|
||||
#include "KX_MouseActuator.h"
|
||||
|
||||
#include "KX_Scene.h"
|
||||
#include "KX_KetsjiEngine.h"
|
||||
@@ -1094,6 +1095,50 @@ void BL_ConvertActuators(const char* maggiename,
|
||||
baseact = tmpstact;
|
||||
break;
|
||||
}
|
||||
case ACT_MOUSE:
|
||||
{
|
||||
bMouseActuator* mouAct = (bMouseActuator*) bact->data;
|
||||
int mode = KX_MouseActuator::KX_ACT_MOUSE_NODEF;
|
||||
|
||||
switch (mouAct->type) {
|
||||
case ACT_MOUSE_VISIBILITY:
|
||||
{
|
||||
mode = KX_MouseActuator::KX_ACT_MOUSE_VISIBILITY;
|
||||
break;
|
||||
}
|
||||
case ACT_MOUSE_LOOK:
|
||||
{
|
||||
mode = KX_MouseActuator::KX_ACT_MOUSE_LOOK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool visible = (mouAct->flag & ACT_MOUSE_VISIBLE) != 0;
|
||||
bool use_axis[2] = {(mouAct->flag & ACT_MOUSE_USE_AXIS_X) != 0, (mouAct->flag & ACT_MOUSE_USE_AXIS_Y) != 0};
|
||||
bool reset[2] = {(mouAct->flag & ACT_MOUSE_RESET_X) != 0, (mouAct->flag & ACT_MOUSE_RESET_Y) != 0};
|
||||
bool local[2] = {(mouAct->flag & ACT_MOUSE_LOCAL_X) != 0, (mouAct->flag & ACT_MOUSE_LOCAL_Y) != 0};
|
||||
|
||||
SCA_MouseManager* eventmgr = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
|
||||
if (eventmgr) {
|
||||
KX_MouseActuator* tmpbaseact = new KX_MouseActuator(gameobj,
|
||||
ketsjiEngine,
|
||||
eventmgr,
|
||||
mode,
|
||||
visible,
|
||||
use_axis,
|
||||
mouAct->threshold,
|
||||
reset,
|
||||
mouAct->object_axis,
|
||||
local,
|
||||
mouAct->sensitivity,
|
||||
mouAct->limit_x,
|
||||
mouAct->limit_y);
|
||||
baseact = tmpbaseact;
|
||||
} else {
|
||||
//cout << "\n Couldn't find mouse event manager..."; - should throw an error here...
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
; /* generate some error */
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
KX_ACT_STATE,
|
||||
KX_ACT_ARMATURE,
|
||||
KX_ACT_STEERING,
|
||||
KX_ACT_MOUSE,
|
||||
};
|
||||
|
||||
SCA_IActuator(SCA_IObject* gameobj, KX_ACTUATOR_TYPE type);
|
||||
|
||||
@@ -91,6 +91,7 @@ set(SRC
|
||||
KX_MaterialIpoController.cpp
|
||||
KX_MeshProxy.cpp
|
||||
KX_MotionState.cpp
|
||||
KX_MouseActuator.cpp
|
||||
KX_MouseFocusSensor.cpp
|
||||
KX_NavMeshObject.cpp
|
||||
KX_NearSensor.cpp
|
||||
@@ -169,6 +170,7 @@ set(SRC
|
||||
KX_MaterialIpoController.h
|
||||
KX_MeshProxy.h
|
||||
KX_MotionState.h
|
||||
KX_MouseActuator.h
|
||||
KX_MouseFocusSensor.h
|
||||
KX_NavMeshObject.h
|
||||
KX_NearSensor.h
|
||||
|
||||
525
source/gameengine/Ketsji/KX_MouseActuator.cpp
Normal file
525
source/gameengine/Ketsji/KX_MouseActuator.cpp
Normal file
@@ -0,0 +1,525 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Geoffrey Gollmer, Jorge Bernal
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "KX_MouseActuator.h"
|
||||
#include "KX_KetsjiEngine.h"
|
||||
#include "SCA_MouseManager.h"
|
||||
#include "SCA_IInputDevice.h"
|
||||
#include "RAS_ICanvas.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "MT_Vector3.h"
|
||||
#include "MT_Scalar.h"
|
||||
#include "MT_assert.h"
|
||||
#include "limits.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Native functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
KX_MouseActuator::KX_MouseActuator(
|
||||
SCA_IObject* gameobj,
|
||||
|
||||
KX_KetsjiEngine* ketsjiEngine,
|
||||
SCA_MouseManager* eventmgr,
|
||||
int acttype,
|
||||
bool visible,
|
||||
bool* use_axis,
|
||||
float* threshold,
|
||||
bool* reset,
|
||||
int* object_axis,
|
||||
bool* local,
|
||||
float* sensitivity,
|
||||
float* limit_x,
|
||||
float* limit_y
|
||||
):
|
||||
SCA_IActuator(gameobj, KX_ACT_MOUSE),
|
||||
m_ketsji(ketsjiEngine),
|
||||
m_eventmgr(eventmgr),
|
||||
m_type(acttype),
|
||||
m_visible(visible),
|
||||
m_use_axis_x(use_axis[0]),
|
||||
m_use_axis_y(use_axis[1]),
|
||||
m_reset_x(reset[0]),
|
||||
m_reset_y(reset[1]),
|
||||
m_local_x(local[0]),
|
||||
m_local_y(local[1])
|
||||
{
|
||||
m_canvas = m_ketsji->GetCanvas();
|
||||
m_oldposition[0] = m_oldposition[1] = -1.f;
|
||||
m_limit_x[0] = limit_x[0];
|
||||
m_limit_x[1] = limit_x[1];
|
||||
m_limit_y[0] = limit_y[0];
|
||||
m_limit_y[1] = limit_y[1];
|
||||
m_threshold[0] = threshold[0];
|
||||
m_threshold[1] = threshold[1];
|
||||
m_object_axis[0] = object_axis[0];
|
||||
m_object_axis[1] = object_axis[1];
|
||||
m_sensitivity[0] = sensitivity[0];
|
||||
m_sensitivity[1] = sensitivity[1];
|
||||
m_angle[0] = 0.f;
|
||||
m_angle[1] = 0.f;
|
||||
}
|
||||
|
||||
KX_MouseActuator::~KX_MouseActuator()
|
||||
{
|
||||
}
|
||||
|
||||
bool KX_MouseActuator::Update()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
bool bNegativeEvent = IsNegativeEvent();
|
||||
RemoveAllEvents();
|
||||
|
||||
if (bNegativeEvent)
|
||||
return false; // do nothing on negative events
|
||||
|
||||
KX_GameObject *parent = static_cast<KX_GameObject *>(GetParent());
|
||||
|
||||
m_mouse = ((SCA_MouseManager *)m_eventmgr)->GetInputDevice();
|
||||
|
||||
switch (m_type) {
|
||||
case KX_ACT_MOUSE_VISIBILITY:
|
||||
{
|
||||
if (m_visible) {
|
||||
if (m_canvas) {
|
||||
m_canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_canvas) {
|
||||
m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_LOOK:
|
||||
{
|
||||
if (m_mouse) {
|
||||
|
||||
float position[2];
|
||||
float movement[2];
|
||||
MT_Vector3 rotation;
|
||||
float setposition[2] = {0.0};
|
||||
|
||||
getMousePosition(position);
|
||||
|
||||
movement[0] = position[0];
|
||||
movement[1] = position[1];
|
||||
|
||||
//preventing initial skipping.
|
||||
if ((m_oldposition[0] <= -0.9) && (m_oldposition[1] <= -0.9)) {
|
||||
|
||||
if (m_reset_x) {
|
||||
m_oldposition[0] = 0.5;
|
||||
}
|
||||
else {
|
||||
m_oldposition[0] = position[0];
|
||||
}
|
||||
|
||||
if (m_reset_y) {
|
||||
m_oldposition[1] = 0.5;
|
||||
}
|
||||
else {
|
||||
m_oldposition[1] = position[1];
|
||||
}
|
||||
setMousePosition(m_oldposition[0], m_oldposition[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
//Calculating X axis.
|
||||
if (m_use_axis_x) {
|
||||
|
||||
if (m_reset_x) {
|
||||
setposition[0] = 0.5;
|
||||
movement[0] -= 0.5;
|
||||
}
|
||||
else {
|
||||
setposition[0] = position[0];
|
||||
movement[0] -= m_oldposition[0];
|
||||
}
|
||||
|
||||
movement[0] *= -1.0;
|
||||
|
||||
/* Don't apply the rotation when width resolution is odd (+ little movement) to
|
||||
avoid undesired drifting or when we are under a certain threshold for mouse
|
||||
movement */
|
||||
|
||||
if (!((m_canvas->GetWidth() % 2 != 0) && MT_abs(movement[0]) < 0.01) &&
|
||||
((movement[0] > (m_threshold[0] / 10.0)) ||
|
||||
((movement[0] * (-1.0)) > (m_threshold[0] / 10.0)))) {
|
||||
|
||||
movement[0] *= m_sensitivity[0];
|
||||
|
||||
if ((m_limit_x[0] != 0.0) && ((m_angle[0] + movement[0]) <= m_limit_x[0])) {
|
||||
movement[0] = m_limit_x[0] - m_angle[0];
|
||||
}
|
||||
|
||||
if ((m_limit_x[1] != 0.0) && ((m_angle[0] + movement[0]) >= m_limit_x[1])) {
|
||||
movement[0] = m_limit_x[1] - m_angle[0];
|
||||
}
|
||||
|
||||
m_angle[0] += movement[0];
|
||||
|
||||
switch (m_object_axis[0]) {
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_X:
|
||||
{
|
||||
rotation = MT_Vector3(movement[0], 0.0, 0.0);
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_Y:
|
||||
{
|
||||
rotation = MT_Vector3(0.0, movement[0], 0.0);
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_Z:
|
||||
{
|
||||
rotation = MT_Vector3(0.0, 0.0, movement[0]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
parent->ApplyRotation(rotation, m_local_x);
|
||||
}
|
||||
}
|
||||
|
||||
//Calculating Y axis.
|
||||
if (m_use_axis_y) {
|
||||
|
||||
if (m_reset_y) {
|
||||
setposition[1] = 0.5;
|
||||
movement[1] -= 0.5;
|
||||
}
|
||||
else {
|
||||
setposition[1] = position[1];
|
||||
movement[1] -= m_oldposition[1];
|
||||
}
|
||||
|
||||
movement[1] *= -1.0;
|
||||
|
||||
/* Don't apply the rotation when height resolution is odd (+ little movement) to
|
||||
avoid undesired drifting or when we are under a certain threshold for mouse
|
||||
movement */
|
||||
|
||||
if (!((m_canvas->GetHeight() % 2 != 0) && MT_abs(movement[1]) < 0.01) &&
|
||||
((movement[1] > (m_threshold[1] / 10.0)) ||
|
||||
((movement[1] * (-1.0)) > (m_threshold[1] / 10.0)))) {
|
||||
|
||||
movement[1] *= m_sensitivity[1];
|
||||
|
||||
if ((m_limit_y[0] != 0.0) && ((m_angle[1] + movement[1]) <= m_limit_y[0])) {
|
||||
movement[1] = m_limit_y[0] - m_angle[1];
|
||||
}
|
||||
|
||||
if ((m_limit_y[1] != 0.0) && ((m_angle[1] + movement[1]) >= m_limit_y[1])) {
|
||||
movement[1] = m_limit_y[1] - m_angle[1];
|
||||
}
|
||||
|
||||
m_angle[1] += movement[1];
|
||||
|
||||
switch (m_object_axis[1])
|
||||
{
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_X:
|
||||
{
|
||||
rotation = MT_Vector3(movement[1], 0.0, 0.0);
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_Y:
|
||||
{
|
||||
rotation = MT_Vector3(0.0, movement[1], 0.0);
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_Z:
|
||||
{
|
||||
rotation = MT_Vector3(0.0, 0.0, movement[1]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
parent->ApplyRotation(rotation, m_local_y);
|
||||
}
|
||||
}
|
||||
|
||||
setMousePosition(setposition[0], setposition[1]);
|
||||
|
||||
m_oldposition[0] = position[0];
|
||||
m_oldposition[1] = position[1];
|
||||
|
||||
}
|
||||
else {
|
||||
//printf("\nNo input device detected for mouse actuator\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool KX_MouseActuator::isValid(KX_MouseActuator::KX_ACT_MOUSE_MODE mode)
|
||||
{
|
||||
return ((mode > KX_ACT_MOUSE_NODEF) && (mode < KX_ACT_MOUSE_MAX));
|
||||
}
|
||||
|
||||
|
||||
CValue* KX_MouseActuator::GetReplica()
|
||||
{
|
||||
KX_MouseActuator* replica = new KX_MouseActuator(*this);
|
||||
|
||||
replica->ProcessReplica();
|
||||
return replica;
|
||||
}
|
||||
|
||||
void KX_MouseActuator::ProcessReplica()
|
||||
{
|
||||
SCA_IActuator::ProcessReplica();
|
||||
}
|
||||
|
||||
void KX_MouseActuator::getMousePosition(float* pos)
|
||||
{
|
||||
MT_assert(!m_mouse);
|
||||
const SCA_InputEvent & xevent = m_mouse->GetEventValue(SCA_IInputDevice::KX_MOUSEX);
|
||||
const SCA_InputEvent & yevent = m_mouse->GetEventValue(SCA_IInputDevice::KX_MOUSEY);
|
||||
|
||||
pos[0] = m_canvas->GetMouseNormalizedX(xevent.m_eventval);
|
||||
pos[1] = m_canvas->GetMouseNormalizedY(yevent.m_eventval);
|
||||
}
|
||||
|
||||
void KX_MouseActuator::setMousePosition(float fx, float fy)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
x = (int)(fx * m_canvas->GetWidth());
|
||||
y = (int)(fy * m_canvas->GetHeight());
|
||||
|
||||
m_canvas->SetMousePosition(x, y);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Python functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Integration hooks ------------------------------------------------------- */
|
||||
PyTypeObject KX_MouseActuator::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"KX_MouseActuator",
|
||||
sizeof(PyObjectPlus_Proxy),
|
||||
0,
|
||||
py_base_dealloc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
py_base_repr,
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
0,0,0,0,0,0,0,
|
||||
Methods,
|
||||
0,
|
||||
0,
|
||||
&SCA_IActuator::Type,
|
||||
0,0,0,0,0,0,
|
||||
py_base_new
|
||||
};
|
||||
|
||||
PyMethodDef KX_MouseActuator::Methods[] = {
|
||||
{"reset", (PyCFunction) KX_MouseActuator::sPyReset, METH_NOARGS,"reset() : undo rotation caused by actuator\n"},
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
|
||||
|
||||
PyAttributeDef KX_MouseActuator::Attributes[] = {
|
||||
KX_PYATTRIBUTE_BOOL_RW("visible", KX_MouseActuator, m_visible),
|
||||
KX_PYATTRIBUTE_BOOL_RW("use_axis_x", KX_MouseActuator, m_use_axis_x),
|
||||
KX_PYATTRIBUTE_BOOL_RW("use_axis_y", KX_MouseActuator, m_use_axis_y),
|
||||
KX_PYATTRIBUTE_FLOAT_ARRAY_RW("threshold", 0.0, 0.5, KX_MouseActuator, m_threshold, 2),
|
||||
KX_PYATTRIBUTE_BOOL_RW("reset_x", KX_MouseActuator, m_reset_x),
|
||||
KX_PYATTRIBUTE_BOOL_RW("reset_y", KX_MouseActuator, m_reset_y),
|
||||
KX_PYATTRIBUTE_INT_ARRAY_RW("object_axis", 0, 2, 1, KX_MouseActuator, m_object_axis, 2),
|
||||
KX_PYATTRIBUTE_BOOL_RW("local_x", KX_MouseActuator, m_local_x),
|
||||
KX_PYATTRIBUTE_BOOL_RW("local_y", KX_MouseActuator, m_local_y),
|
||||
KX_PYATTRIBUTE_FLOAT_ARRAY_RW("sensitivity", -FLT_MAX, FLT_MAX, KX_MouseActuator, m_sensitivity, 2),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("limit_x", KX_MouseActuator, pyattr_get_limit_x, pyattr_set_limit_x),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("limit_y", KX_MouseActuator, pyattr_get_limit_y, pyattr_set_limit_y),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("angle", KX_MouseActuator, pyattr_get_angle, pyattr_set_angle),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
PyObject* KX_MouseActuator::pyattr_get_limit_x(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_MouseActuator* self= static_cast<KX_MouseActuator*>(self_v);
|
||||
return Py_BuildValue("[f,f]", (self->m_limit_x[0] / M_PI * 180.0), (self->m_limit_x[1] / M_PI * 180.0));
|
||||
}
|
||||
|
||||
int KX_MouseActuator::pyattr_set_limit_x(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
PyObject *item1, *item2;
|
||||
KX_MouseActuator* self= static_cast<KX_MouseActuator*>(self_v);
|
||||
|
||||
if (!PyList_Check(value))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (PyList_Size(value) != 2)
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
item1 = PyList_GetItem(value, 0);
|
||||
item2 = PyList_GetItem(value, 1);
|
||||
|
||||
if (!(PyFloat_Check(item1)) || !(PyFloat_Check(item2))) {
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
else {
|
||||
self->m_limit_x[0] = (PyFloat_AsDouble(item1) * M_PI / 180.0);
|
||||
self->m_limit_x[1] = (PyFloat_AsDouble(item2) * M_PI / 180.0);
|
||||
}
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
PyObject* KX_MouseActuator::pyattr_get_limit_y(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_MouseActuator* self= static_cast<KX_MouseActuator*>(self_v);
|
||||
return Py_BuildValue("[f,f]", (self->m_limit_y[0] / M_PI * 180.0), (self->m_limit_y[1] / M_PI * 180.0));
|
||||
}
|
||||
|
||||
int KX_MouseActuator::pyattr_set_limit_y(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
PyObject *item1, *item2;
|
||||
KX_MouseActuator* self= static_cast<KX_MouseActuator*>(self_v);
|
||||
|
||||
if (!PyList_Check(value))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (PyList_Size(value) != 2)
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
item1 = PyList_GetItem(value, 0);
|
||||
item2 = PyList_GetItem(value, 1);
|
||||
|
||||
if (!(PyFloat_Check(item1)) || !(PyFloat_Check(item2))) {
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
else {
|
||||
self->m_limit_y[0] = (PyFloat_AsDouble(item1) * M_PI / 180.0);
|
||||
self->m_limit_y[1] = (PyFloat_AsDouble(item2) * M_PI / 180.0);
|
||||
}
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
PyObject* KX_MouseActuator::pyattr_get_angle(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_MouseActuator* self= static_cast<KX_MouseActuator*>(self_v);
|
||||
return Py_BuildValue("[f,f]", (self->m_angle[0] / M_PI * 180.0), (self->m_angle[1] / M_PI * 180.0));
|
||||
}
|
||||
|
||||
int KX_MouseActuator::pyattr_set_angle(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
||||
{
|
||||
PyObject *item1, *item2;
|
||||
KX_MouseActuator* self= static_cast<KX_MouseActuator*>(self_v);
|
||||
|
||||
if (!PyList_Check(value))
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
if (PyList_Size(value) != 2)
|
||||
return PY_SET_ATTR_FAIL;
|
||||
|
||||
item1 = PyList_GetItem(value, 0);
|
||||
item2 = PyList_GetItem(value, 1);
|
||||
|
||||
if (!(PyFloat_Check(item1)) || !(PyFloat_Check(item2))) {
|
||||
return PY_SET_ATTR_FAIL;
|
||||
}
|
||||
else {
|
||||
self->m_angle[0] = (PyFloat_AsDouble(item1) * M_PI / 180.0);
|
||||
self->m_angle[1] = (PyFloat_AsDouble(item2) * M_PI / 180.0);
|
||||
}
|
||||
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
PyObject* KX_MouseActuator::PyReset()
|
||||
{
|
||||
MT_Vector3 rotation;
|
||||
KX_GameObject *parent = static_cast<KX_GameObject *>(GetParent());
|
||||
|
||||
switch (m_object_axis[0]) {
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_X:
|
||||
{
|
||||
rotation = MT_Vector3(-1.0 * m_angle[0], 0.0, 0.0);
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_Y:
|
||||
{
|
||||
rotation = MT_Vector3(0.0, -1.0 * m_angle[0], 0.0);
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_Z:
|
||||
{
|
||||
rotation = MT_Vector3(0.0, 0.0, -1.0 * m_angle[0]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
parent->ApplyRotation(rotation, m_local_x);
|
||||
|
||||
switch (m_object_axis[1]) {
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_X:
|
||||
{
|
||||
rotation = MT_Vector3(-1.0 * m_angle[1], 0.0, 0.0);
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_Y:
|
||||
{
|
||||
rotation = MT_Vector3(0.0, -1.0 * m_angle[1], 0.0);
|
||||
break;
|
||||
}
|
||||
case KX_ACT_MOUSE_OBJECT_AXIS_Z:
|
||||
{
|
||||
rotation = MT_Vector3(0.0, 0.0, -1.0 * m_angle[1]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
parent->ApplyRotation(rotation, m_local_y);
|
||||
|
||||
m_angle[0] = 0.0;
|
||||
m_angle[1] = 0.0;
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
127
source/gameengine/Ketsji/KX_MouseActuator.h
Normal file
127
source/gameengine/Ketsji/KX_MouseActuator.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Contributor(s): Geoffrey Gollmer, Jorge Bernal
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __KX_MOUSEACTUATOR
|
||||
#define __KX_MOUSEACTUATOR
|
||||
|
||||
#include "SCA_IActuator.h"
|
||||
|
||||
class KX_KetsjiEngine;
|
||||
class SCA_MouseManager;
|
||||
class SCA_IInputDevice;
|
||||
class RAS_ICanvas;
|
||||
|
||||
class KX_MouseActuator : public SCA_IActuator
|
||||
{
|
||||
Py_Header
|
||||
|
||||
private:
|
||||
|
||||
KX_KetsjiEngine* m_ketsji;
|
||||
SCA_MouseManager* m_eventmgr;
|
||||
SCA_IInputDevice* m_mouse;
|
||||
RAS_ICanvas* m_canvas;
|
||||
int m_type;
|
||||
|
||||
bool m_visible;
|
||||
|
||||
bool m_use_axis_x; /* 0 for calculate axis, 1 for ignore axis */
|
||||
bool m_use_axis_y;
|
||||
float m_threshold[2];
|
||||
bool m_reset_x; /* 0=reset, 1=free */
|
||||
bool m_reset_y;
|
||||
int m_object_axis[2]; /* 0=x, 1=y, 2=z */
|
||||
bool m_local_x; /* 0=local, 1=global*/
|
||||
bool m_local_y;
|
||||
float m_sensitivity[2];
|
||||
float m_limit_x[2];
|
||||
float m_limit_y[2];
|
||||
|
||||
float m_oldposition[2];
|
||||
float m_angle[2];
|
||||
|
||||
public:
|
||||
|
||||
enum KX_ACT_MOUSE_OBJECT_AXIS {
|
||||
KX_ACT_MOUSE_OBJECT_AXIS_X = 0,
|
||||
KX_ACT_MOUSE_OBJECT_AXIS_Y,
|
||||
KX_ACT_MOUSE_OBJECT_AXIS_Z
|
||||
};
|
||||
|
||||
enum KX_ACT_MOUSE_MODE {
|
||||
KX_ACT_MOUSE_NODEF = 0,
|
||||
KX_ACT_MOUSE_VISIBILITY,
|
||||
KX_ACT_MOUSE_LOOK,
|
||||
KX_ACT_MOUSE_MAX
|
||||
};
|
||||
|
||||
KX_MouseActuator(
|
||||
SCA_IObject* gameobj,
|
||||
KX_KetsjiEngine* ketsjiEngine,
|
||||
SCA_MouseManager* eventmgr,
|
||||
int acttype,
|
||||
bool visible,
|
||||
bool* use_axis,
|
||||
float* threshold,
|
||||
bool* reset,
|
||||
int* object_axis,
|
||||
bool* local,
|
||||
float* sensitivity,
|
||||
float* limit_x,
|
||||
float* limit_y
|
||||
);
|
||||
|
||||
|
||||
~KX_MouseActuator();
|
||||
|
||||
CValue* GetReplica();
|
||||
virtual void ProcessReplica();
|
||||
|
||||
virtual bool Update();
|
||||
|
||||
/* check whether this value is valid */
|
||||
bool isValid(KX_ACT_MOUSE_MODE mode);
|
||||
|
||||
virtual void getMousePosition(float*);
|
||||
virtual void setMousePosition(float, float);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Python interface ---------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Methods */
|
||||
|
||||
KX_PYMETHOD_DOC_NOARGS(KX_MouseActuator,Reset);
|
||||
|
||||
/* Attributes */
|
||||
|
||||
static PyObject* pyattr_get_limit_x(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_limit_x(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
|
||||
static PyObject* pyattr_get_limit_y(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_limit_y(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
|
||||
static PyObject* pyattr_get_angle(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_angle(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
};
|
||||
|
||||
#endif //__KX_MOUSEACTUATOR_DOC
|
||||
@@ -87,6 +87,7 @@ extern "C" {
|
||||
#include "KX_SCA_DynamicActuator.h"
|
||||
#include "KX_SteeringActuator.h"
|
||||
#include "KX_NavMeshObject.h"
|
||||
#include "KX_MouseActuator.h"
|
||||
|
||||
#include "SCA_IInputDevice.h"
|
||||
#include "SCA_PropertySensor.h"
|
||||
@@ -1820,6 +1821,12 @@ PyObject *initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
|
||||
KX_MACRO_addTypesToDict(d, KX_ACTION_BLEND_BLEND, BL_Action::ACT_BLEND_BLEND);
|
||||
KX_MACRO_addTypesToDict(d, KX_ACTION_BLEND_ADD, BL_Action::ACT_BLEND_ADD);
|
||||
|
||||
/* Mouse Actuator object axis*/
|
||||
KX_MACRO_addTypesToDict(d, KX_ACT_MOUSE_OBJECT_AXIS_X, KX_MouseActuator::KX_ACT_MOUSE_OBJECT_AXIS_X);
|
||||
KX_MACRO_addTypesToDict(d, KX_ACT_MOUSE_OBJECT_AXIS_Y, KX_MouseActuator::KX_ACT_MOUSE_OBJECT_AXIS_Y);
|
||||
KX_MACRO_addTypesToDict(d, KX_ACT_MOUSE_OBJECT_AXIS_Z, KX_MouseActuator::KX_ACT_MOUSE_OBJECT_AXIS_Z);
|
||||
|
||||
|
||||
// Check for errors
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
#include "SCA_RandomActuator.h"
|
||||
#include "SCA_IController.h"
|
||||
#include "KX_NavMeshObject.h"
|
||||
#include "KX_MouseActuator.h"
|
||||
|
||||
static void PyType_Attr_Set(PyGetSetDef *attr_getset, PyAttributeDef *attr)
|
||||
{
|
||||
@@ -227,6 +228,7 @@ void initPyTypes(void)
|
||||
PyType_Ready_Attr(dict, KX_VehicleWrapper, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_VertexProxy, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_VisibilityActuator, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_MouseActuator, init_getset);
|
||||
PyType_Ready_Attr(dict, PyObjectPlus, init_getset);
|
||||
PyType_Ready_Attr(dict, SCA_2DFilterActuator, init_getset);
|
||||
PyType_Ready_Attr(dict, SCA_ANDController, init_getset);
|
||||
|
||||
Reference in New Issue
Block a user