Compare commits
9 Commits
temp-sampl
...
bge_compon
Author | SHA1 | Date | |
---|---|---|---|
b46d895550 | |||
6960127d26 | |||
46a9a9a1c1 | |||
ba94834c2b | |||
1a736323c3 | |||
c8b912a04a | |||
118a624f76 | |||
5baa7e5d78 | |||
e4eb9684d1 |
72
release/scripts/bge_components/camera.py
Normal file
72
release/scripts/bge_components/camera.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import bge
|
||||
from collections import OrderedDict
|
||||
|
||||
class ThirdPerson(bge.types.KX_PythonComponent):
|
||||
"""A component for a third person camera"""
|
||||
|
||||
args = OrderedDict([
|
||||
("Pivot Name", "pivot"),
|
||||
("Time Offset", 35),
|
||||
("Lens", 30),
|
||||
("Scale Max", 4.0),
|
||||
("Scale Min", 0.6),
|
||||
])
|
||||
|
||||
def start(self, args):
|
||||
# Make sure we have a camera
|
||||
if not isinstance(self.object, bge.types.KX_Camera):
|
||||
raise TypeError("This component must be attached to a camera")
|
||||
|
||||
# Apply settings
|
||||
self.object.parent.timeOffset = args['Time Offset']
|
||||
self.object.lens = args['Lens']
|
||||
|
||||
# Save scale settings
|
||||
self.scale_max = args['Scale Max']
|
||||
self.scale_min = args['Scale Min']
|
||||
|
||||
# Find the pivot
|
||||
pivot = self.object.parent
|
||||
|
||||
while pivot:
|
||||
if pivot.name == args['Pivot Name']:
|
||||
break
|
||||
|
||||
pivot = pivot.parent
|
||||
|
||||
if not pivot:
|
||||
raise ValueError("Could not find the pivot object")
|
||||
|
||||
self.pivot = pivot
|
||||
|
||||
self._target_distance = (self.object.worldPosition - pivot.worldPosition).length
|
||||
|
||||
def update(self):
|
||||
ob = self.object
|
||||
pivot = self.pivot
|
||||
|
||||
# Cast a ray and see if we hit something
|
||||
hit_pos = self.object.rayCast(
|
||||
ob.worldPosition,
|
||||
pivot.worldPosition,
|
||||
ob.localPosition[2])[1]
|
||||
|
||||
if hit_pos:
|
||||
scale = ob.getDistanceTo(hit_pos)/self._target_distance
|
||||
if scale > self.scale_max:
|
||||
scale = self.scale_max
|
||||
elif scale < self.scale_min:
|
||||
scale = self.scale_min
|
||||
else:
|
||||
scale = self.scale_max
|
||||
|
||||
# Apply the scaling
|
||||
pivot.scaling = [scale, scale, scale]
|
||||
|
||||
# Undo the scaling on the camera
|
||||
# inv_scale = 1/scale
|
||||
# ob.scaling = [inv_scale, inv_scale, inv_scale]
|
||||
|
||||
# Update the "look at"
|
||||
vec = ob.getVectTo(pivot)[1]
|
||||
ob.alignAxisToVect(vec, 1)
|
39
release/scripts/bge_components/movement.py
Normal file
39
release/scripts/bge_components/movement.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import bge
|
||||
|
||||
class ThirdPerson(bge.types.KX_PythonComponent):
|
||||
"""Basic third person controls
|
||||
|
||||
W: move forward
|
||||
A: turn left
|
||||
S: move backward
|
||||
D: turn right
|
||||
|
||||
"""
|
||||
|
||||
args = {
|
||||
"Move Speed": 10,
|
||||
"Turn Speed": 0.04
|
||||
}
|
||||
|
||||
def start(self, args):
|
||||
self.move_speed = args['Move Speed']
|
||||
self.turn_speed = args['Turn Speed']
|
||||
|
||||
def update(self):
|
||||
keyboard = bge.logic.keyboard.events
|
||||
|
||||
move = 0
|
||||
rotate = 0
|
||||
|
||||
if keyboard[bge.events.WKEY]:
|
||||
move += self.move_speed
|
||||
if keyboard[bge.events.SKEY]:
|
||||
move -= self.move_speed
|
||||
|
||||
if keyboard[bge.events.AKEY]:
|
||||
rotate += self.turn_speed
|
||||
if keyboard[bge.events.DKEY]:
|
||||
rotate -= self.turn_speed
|
||||
|
||||
self.object.setLinearVelocity((0, move, 0), True)
|
||||
self.object.applyRotation((0, 0, rotate), True)
|
116
release/scripts/bge_components/particle.py
Normal file
116
release/scripts/bge_components/particle.py
Normal file
@@ -0,0 +1,116 @@
|
||||
import bge
|
||||
import mathutils
|
||||
import math
|
||||
import random
|
||||
from collections import OrderedDict
|
||||
|
||||
X_AXIS = mathutils.Vector((1, 0, 0))
|
||||
Y_AXIS = mathutils.Vector((0, 1, 0))
|
||||
Z_AXIS = mathutils.Vector((0, 0, 1))
|
||||
|
||||
class ParticleSystem(bge.types.KX_PythonComponent):
|
||||
"""Simple particles System"""
|
||||
|
||||
args = OrderedDict([
|
||||
("Particle Name", ""),
|
||||
("Particles Per Frame", 1),
|
||||
("X Angle", 30.0),
|
||||
("Y Angle", 30.0),
|
||||
("X Size", 0.0),
|
||||
("Y Size", 0.0),
|
||||
("Starting Velocity", 500.0),
|
||||
("Velocity Variance", 0.0),
|
||||
("Particle Life", 30),
|
||||
("Life Variance", 0.0),
|
||||
("Gravity", -9.8),
|
||||
])
|
||||
|
||||
def start(self, args):
|
||||
self.valid = True
|
||||
self.particle = args['Particle Name']
|
||||
self.part_life = args['Particle Life']
|
||||
self.ppf_inv = 1/(args['Particles Per Frame'] if args['Particles Per Frame'] else 1)
|
||||
|
||||
# Save directional variance as radians
|
||||
self.x_var = math.radians(args['X Angle'])
|
||||
self.y_var = math.radians(args['Y Angle'])
|
||||
|
||||
# Save the offests
|
||||
self.x_off = args['X Size']
|
||||
self.y_off = args['Y Size']
|
||||
|
||||
# Save variances
|
||||
self.velocity_var = args['Velocity Variance']
|
||||
self.life_variance = args['Life Variance']
|
||||
|
||||
# Store a time step
|
||||
self.dt = 1/bge.logic.getLogicTicRate()
|
||||
|
||||
# Precalculate gravity*dt
|
||||
self.gravity_dt = args['Gravity']*self.dt
|
||||
|
||||
# Precalculate velocity*dt
|
||||
self.start_velocity_dt = args['Starting Velocity'] * self.dt
|
||||
|
||||
# Add the first particle into the list
|
||||
self.particle_list = [self.create_particle()]
|
||||
|
||||
def update(self):
|
||||
frame_position = self.ppf_inv
|
||||
while frame_position <= 1:
|
||||
self.particle_list.append(self.create_particle(frame_position))
|
||||
frame_position += self.ppf_inv
|
||||
|
||||
[self.update_particle(particle) for particle in self.particle_list]
|
||||
|
||||
def create_particle(self, frame_position=0):
|
||||
# Add the particle
|
||||
scene = bge.logic.getCurrentScene()
|
||||
particle = scene.addObject(self.particle, self.object, 0)
|
||||
|
||||
# Determine particle heading
|
||||
x_tilt = random.uniform(-self.x_var, self.x_var)
|
||||
y_tilt = random.uniform(-self.y_var, self.y_var)
|
||||
|
||||
# Apply x offset
|
||||
x_dir = self.object.getAxisVect(X_AXIS)
|
||||
particle.worldPosition = particle.worldPosition.copy() + x_dir * random.uniform(-self.x_off, self.x_off)
|
||||
|
||||
# Apply y offset
|
||||
y_dir = self.object.getAxisVect(Y_AXIS)
|
||||
particle.worldPosition = particle.worldPosition.copy() + y_dir * random.uniform(-self.y_off, self.y_off)
|
||||
|
||||
# Determine the particle velocity vector
|
||||
velocity = self.object.getAxisVect(Z_AXIS)
|
||||
velocity.rotate(mathutils.Euler((x_tilt, 0, 0)))
|
||||
velocity.rotate(mathutils.Euler((0, y_tilt, 0)))
|
||||
|
||||
# Assign the particle properties
|
||||
particle['life'] = self.part_life
|
||||
if self.life_variance > .0001:
|
||||
particle['life'] *= 1+random.uniform(-self.life_variance, self.life_variance)
|
||||
particle['velocity'] = velocity * self.start_velocity_dt
|
||||
if self.velocity_var > .0001:
|
||||
particle['velocity'] *= 1+random.uniform(-self.velocity_var, self.velocity_var)
|
||||
# Deal with subframe positioning
|
||||
if frame_position < 1:
|
||||
particle.worldPosition = particle.worldPosition.copy() + particle['velocity']*self.dt*frame_position
|
||||
|
||||
# Return the particle
|
||||
return particle
|
||||
|
||||
def update_particle(self, particle):
|
||||
# Update particle life
|
||||
if particle['life'] == 0:
|
||||
self.particle_list.remove(particle)
|
||||
particle.endObject()
|
||||
return
|
||||
else:
|
||||
particle['life'] -= 1
|
||||
|
||||
# Apply gravity to the particle's velocity
|
||||
particle['velocity'][2] += self.gravity_dt
|
||||
|
||||
# Update particle position
|
||||
particle.worldPosition = particle.worldPosition.copy() + particle['velocity']*self.dt
|
||||
|
128
release/scripts/bge_components/vehicle.py
Normal file
128
release/scripts/bge_components/vehicle.py
Normal file
@@ -0,0 +1,128 @@
|
||||
import bge
|
||||
from collections import OrderedDict
|
||||
|
||||
class Vehicle(bge.types.KX_PythonComponent):
|
||||
"""A component making use of the vehicle wrapper
|
||||
|
||||
Controls:
|
||||
W: Move forward
|
||||
S: Move backward
|
||||
A: Turn left
|
||||
D: Turn right
|
||||
SPACE: Brake
|
||||
|
||||
"""
|
||||
|
||||
args = OrderedDict([
|
||||
("Gas Power", 15.0),
|
||||
("Reverse Power", 10.0),
|
||||
("Brake Power", 10.0),
|
||||
("Turn Power", 0.3),
|
||||
|
||||
("Drive Type", {"Front Wheel", "Rear Wheel"}),
|
||||
("Tire Prefix", "tire_"),
|
||||
("Front Tire Radius", 0.3),
|
||||
("Rear Tire Radius", 0.3),
|
||||
("Tire Friction", 10.0),
|
||||
("Suspension Height", 0.2),
|
||||
("Suspension Compression", 6.0),
|
||||
("Suspension Damping", 1.0),
|
||||
("Suspension Stiffness", 20.0),
|
||||
("Roll Influence", 0.06),
|
||||
])
|
||||
|
||||
def start(self, args):
|
||||
|
||||
# Save power settings
|
||||
self.gas = args['Gas Power']
|
||||
self.reverse = args['Reverse Power']
|
||||
self.brake = args['Brake Power']
|
||||
self.turn = args['Turn Power']
|
||||
|
||||
# Save steering settings
|
||||
self.fwd = args['Drive Type'] == "Front Wheel"
|
||||
self.rwd = args['Drive Type'] == "Rear Wheel"
|
||||
|
||||
# Create the vehicle constraint
|
||||
constraint = bge.constraints.createConstraint(self.object.getPhysicsId(), 0, 11)
|
||||
cid = constraint.getConstraintId()
|
||||
vid = bge.constraints.getVehicleConstraint(cid)
|
||||
self.vid = vid
|
||||
|
||||
# Find the tires (they should be parented)
|
||||
tpx = args['Tire Prefix']
|
||||
tires = [None]*4
|
||||
for child in self.object.childrenRecursive:
|
||||
for i in range(4):
|
||||
if child.name.startswith(tpx+str(i+1)):
|
||||
tires[i] = child
|
||||
|
||||
# Unparent the tire so it doesn't cause the vehicle wrapper grief
|
||||
child.removeParent()
|
||||
|
||||
# Verify that we have all of the tires
|
||||
for idx, tire in enumerate(tires):
|
||||
if tire is None:
|
||||
raise ValueError("Tire "+str(idx+1)+" not found")
|
||||
|
||||
# Now setup the tires
|
||||
for i in range(4):
|
||||
# Add the wheel
|
||||
vid.addWheel(
|
||||
# Object
|
||||
tires[i],
|
||||
|
||||
# Position
|
||||
tires[i].worldPosition - self.object.worldPosition,
|
||||
|
||||
# Suspension angle
|
||||
(0, 0, -1),
|
||||
|
||||
# Suspension axis
|
||||
(-1, 0, 0),
|
||||
|
||||
# Suspension height
|
||||
args['Suspension Height'],
|
||||
|
||||
# Tire radius
|
||||
args['Front Tire Radius'] if i in (0, 1) else args['Rear Tire Radius'],
|
||||
|
||||
# Steerability
|
||||
self.fwd if i in (2, 3) else self.rwd)
|
||||
|
||||
# Advanced settings
|
||||
vid.setTyreFriction(args['Tire Friction'], i)
|
||||
vid.setSuspensionCompression(args['Suspension Compression'], i)
|
||||
vid.setSuspensionDamping(args['Suspension Damping'], i)
|
||||
vid.setSuspensionStiffness(args['Suspension Stiffness'], i)
|
||||
vid.setRollInfluence(args['Roll Influence'], i)
|
||||
|
||||
def update(self):
|
||||
keyboard = bge.logic.keyboard.events
|
||||
# Engine force
|
||||
engine_force = 0
|
||||
if keyboard[bge.events.WKEY] == bge.logic.KX_INPUT_ACTIVE:
|
||||
engine_force -= self.gas
|
||||
if keyboard[bge.events.SKEY] == bge.logic.KX_INPUT_ACTIVE:
|
||||
engine_force += self.gas
|
||||
|
||||
# Steering
|
||||
steering = 0
|
||||
if keyboard[bge.events.AKEY] == bge.logic.KX_INPUT_ACTIVE:
|
||||
steering += self.turn
|
||||
if keyboard[bge.events.DKEY] == bge.logic.KX_INPUT_ACTIVE:
|
||||
steering -= self.turn
|
||||
|
||||
# Braking
|
||||
braking = 0
|
||||
if keyboard[bge.events.SPACEKEY] == bge.logic.KX_INPUT_ACTIVE:
|
||||
braking += self.brake
|
||||
|
||||
# Apply settings
|
||||
|
||||
for i in range(4):
|
||||
self.vid.applyEngineForce(engine_force, i)
|
||||
|
||||
if (i in (0, 1) and self.fwd) or (i in (2, 3) and self.rwd):
|
||||
self.vid.applyBraking(braking, i)
|
||||
self.vid.setSteeringValue(steering, i)
|
@@ -33,7 +33,7 @@ import sys as _sys
|
||||
|
||||
import addon_utils as _addon_utils
|
||||
|
||||
_script_module_dirs = "startup", "modules"
|
||||
_script_module_dirs = "startup", "modules", "bge_components"
|
||||
|
||||
|
||||
def _test_import(module_name, loaded_modules):
|
||||
@@ -190,8 +190,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
||||
if _os.path.isdir(path):
|
||||
_sys_path_ensure(path)
|
||||
|
||||
# only add this to sys.modules, dont run
|
||||
if path_subdir == "modules":
|
||||
# only add these to sys.modules, dont run
|
||||
if path_subdir in ("modules", "bge_components"):
|
||||
continue
|
||||
|
||||
for mod in modules_from_path(path, loaded_modules):
|
||||
|
@@ -19,6 +19,40 @@
|
||||
# <pep8 compliant>
|
||||
import bpy
|
||||
|
||||
class LOGIC_PT_components(bpy.types.Panel):
|
||||
bl_space_type = 'LOGIC_EDITOR'
|
||||
bl_region_type = 'UI'
|
||||
bl_label = 'Components'
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.active_object
|
||||
return ob and ob.name
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
ob = context.active_object
|
||||
game = ob.game
|
||||
|
||||
st = context.space_data
|
||||
|
||||
row = layout.row()
|
||||
row.prop(st, "import_string", text="")
|
||||
row.operator("logic.component_add", text="Add Component")
|
||||
|
||||
for i, c in enumerate(game.components):
|
||||
box = layout.box()
|
||||
row = box.row()
|
||||
row.prop(c, "name", text="")
|
||||
row.operator("logic.component_reload", text="", icon='RECOVER_LAST').index = i
|
||||
row.operator("logic.component_remove", text="", icon='X').index = i
|
||||
|
||||
for prop in c.properties:
|
||||
row = box.row()
|
||||
row.label(text=prop.name)
|
||||
row.prop(prop, "value", text="")
|
||||
|
||||
|
||||
class LOGIC_PT_properties(bpy.types.Panel):
|
||||
bl_space_type = 'LOGIC_EDITOR'
|
||||
|
15
source/blender/blenkernel/BKE_pycomponent.h
Normal file
15
source/blender/blenkernel/BKE_pycomponent.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef BKE_PYCOMPONENT_H
|
||||
#define BKE_PYCOMPONENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct PythonComponent *new_component_from_import(char *import);
|
||||
void free_component(struct PythonComponent *pc);
|
||||
void free_components(struct ListBase *base);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*BKE_PYCOMPONENT_H*/
|
@@ -75,6 +75,7 @@
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_pycomponent.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_displist.h"
|
||||
@@ -308,6 +309,7 @@ void free_object(Object *ob)
|
||||
free_sensors(&ob->sensors);
|
||||
free_controllers(&ob->controllers);
|
||||
free_actuators(&ob->actuators);
|
||||
free_components(&ob->components);
|
||||
|
||||
free_constraints(&ob->constraints);
|
||||
|
||||
@@ -1337,6 +1339,7 @@ Object *copy_object(Object *ob)
|
||||
copy_sensors(&obn->sensors, &ob->sensors);
|
||||
copy_controllers(&obn->controllers, &ob->controllers);
|
||||
copy_actuators(&obn->actuators, &ob->actuators);
|
||||
// XXX todo copy_components(&obn->components, &ob->components);
|
||||
|
||||
if(ob->pose) {
|
||||
copy_object_pose(obn, ob);
|
||||
|
367
source/blender/blenkernel/intern/python_component.c
Normal file
367
source/blender/blenkernel/intern/python_component.c
Normal file
@@ -0,0 +1,367 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "DNA_component_types.h"
|
||||
#include "DNA_property_types.h" /* For MAX_PROPSTRING */
|
||||
#include "DNA_listBase.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_pycomponent.h"
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_types.h"
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#include "Python.h"
|
||||
#endif
|
||||
|
||||
#ifndef WITH_PYTHON
|
||||
struct PyObject;
|
||||
#endif
|
||||
|
||||
int verify_class(PyObject *cls)
|
||||
{
|
||||
#ifdef WITH_PYTHON
|
||||
PyObject *list, *item;
|
||||
char *name;
|
||||
int i;
|
||||
int comp;
|
||||
|
||||
list = PyObject_GetAttrString(cls, "__bases__");
|
||||
|
||||
for (i=0; i<PyTuple_Size(list); ++i)
|
||||
{
|
||||
item = PyObject_GetAttrString(PyTuple_GetItem(list, i), "__name__");
|
||||
name = _PyUnicode_AsString(item);
|
||||
|
||||
|
||||
// We don't want to decref until after the comprison
|
||||
comp = strcmp("KX_PythonComponent", name);
|
||||
Py_DECREF(item);
|
||||
|
||||
if (comp == 0)
|
||||
{
|
||||
Py_DECREF(list);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(list);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ComponentProperty *create_property(char *name, short type, int data, void *poin)
|
||||
{
|
||||
ComponentProperty *cprop;
|
||||
|
||||
cprop = MEM_mallocN(sizeof(ComponentProperty), "ComponentProperty");
|
||||
|
||||
if (cprop)
|
||||
{
|
||||
BLI_strncpy(cprop->name, name, sizeof(cprop->name));
|
||||
cprop->type = type;
|
||||
|
||||
cprop->data = 0;
|
||||
cprop->poin = NULL;
|
||||
cprop->poin2 = NULL;
|
||||
|
||||
if (type == CPROP_TYPE_INT)
|
||||
cprop->data = data;
|
||||
else if (type == CPROP_TYPE_FLOAT)
|
||||
*((float *)&cprop->data) = *(float*)(&data);
|
||||
else if (type == CPROP_TYPE_BOOLEAN)
|
||||
cprop->data = data;
|
||||
else if (type == CPROP_TYPE_STRING)
|
||||
cprop->poin = poin;
|
||||
else if (type == CPROP_TYPE_SET)
|
||||
{
|
||||
cprop->poin = poin;
|
||||
cprop->poin2 = ((EnumPropertyItem*)poin)->identifier;
|
||||
cprop->data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return cprop;
|
||||
}
|
||||
|
||||
void free_component_property(ComponentProperty *cprop)
|
||||
{
|
||||
if (cprop->poin) MEM_freeN(cprop->poin);
|
||||
if (cprop->poin2) MEM_freeN(cprop->poin2);
|
||||
MEM_freeN(cprop);
|
||||
}
|
||||
|
||||
void free_component_properties(ListBase *lb)
|
||||
{
|
||||
ComponentProperty *cprop;
|
||||
|
||||
while (cprop= lb->first) {
|
||||
BLI_remlink(lb, cprop);
|
||||
free_component_property(cprop);
|
||||
}
|
||||
}
|
||||
|
||||
void create_properties(PythonComponent *pycomp, PyObject *cls)
|
||||
{
|
||||
#ifdef WITH_PYTHON
|
||||
PyObject *args_dict, *key, *value, *items, *item;
|
||||
ComponentProperty *cprop;
|
||||
char name[64];
|
||||
int i=0, data;
|
||||
short type;
|
||||
void *poin=NULL;
|
||||
|
||||
args_dict = PyObject_GetAttrString(cls, "args");
|
||||
|
||||
// If there is no args dict, then we are already done
|
||||
if (args_dict == NULL || !PyDict_Check(args_dict))
|
||||
{
|
||||
Py_XDECREF(args_dict);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, parse the dict:
|
||||
// key => value
|
||||
// key = property name
|
||||
// value = default value
|
||||
// type(value) = property type
|
||||
items = PyMapping_Items(args_dict);
|
||||
|
||||
for (i=0; i<PyList_Size(items); ++i)
|
||||
{
|
||||
item = PyList_GetItem(items, i);
|
||||
key = PyTuple_GetItem(item, 0);
|
||||
value = PyTuple_GetItem(item, 1);
|
||||
|
||||
// Make sure type(key) == string
|
||||
if (!PyUnicode_Check(key))
|
||||
{
|
||||
printf("Non-string key found in the args dictionary, skipping\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
BLI_strncpy(name, _PyUnicode_AsString(key), sizeof(name));
|
||||
|
||||
// Determine the type and default value
|
||||
if (PyBool_Check(value))
|
||||
{
|
||||
type = CPROP_TYPE_BOOLEAN;
|
||||
data = PyLong_AsLong(value) != 0;
|
||||
}
|
||||
else if (PyLong_Check(value))
|
||||
{
|
||||
type = CPROP_TYPE_INT;
|
||||
data = PyLong_AsLong(value);
|
||||
}
|
||||
else if (PyFloat_Check(value))
|
||||
{
|
||||
type = CPROP_TYPE_FLOAT;
|
||||
*((float*)&data) = (float)PyFloat_AsDouble(value);
|
||||
}
|
||||
else if (PyUnicode_Check(value))
|
||||
{
|
||||
type = CPROP_TYPE_STRING;
|
||||
poin = MEM_callocN(MAX_PROPSTRING, "ComponentProperty string");
|
||||
BLI_strncpy((char*)poin, _PyUnicode_AsString(value), MAX_PROPSTRING);
|
||||
}
|
||||
else if (PySet_Check(value))
|
||||
{
|
||||
int len = PySet_Size(value), i=0;
|
||||
EnumPropertyItem *items;
|
||||
PyObject *iterator = PyObject_GetIter(value), *v=NULL;
|
||||
char *str;
|
||||
type = CPROP_TYPE_SET;
|
||||
|
||||
// Create an EnumPropertyItem array
|
||||
poin = MEM_callocN(sizeof(EnumPropertyItem)*(len+1), "ComponentProperty set");
|
||||
items = (EnumPropertyItem*)poin;
|
||||
while (v = PyIter_Next(iterator))
|
||||
{
|
||||
|
||||
str = MEM_callocN(MAX_PROPSTRING, "ComponentProperty set string");
|
||||
BLI_strncpy(str, _PyUnicode_AsString(v), MAX_PROPSTRING);
|
||||
printf("SET: %s\n", str);
|
||||
items[i].value = i;
|
||||
items[i].identifier = str;
|
||||
items[i].icon = 0;
|
||||
items[i].name = str;
|
||||
items[i].description = "";
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
data = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unsupported type
|
||||
printf("Unsupported type found for args[%s], skipping\n", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
cprop = create_property(name, type, data, poin);
|
||||
|
||||
if (cprop)
|
||||
BLI_addtail(&pycomp->properties, cprop);
|
||||
else
|
||||
// Cleanup poin if it's set
|
||||
if (poin) MEM_freeN(poin);
|
||||
}
|
||||
|
||||
#endif /* WITH_PYTHON */
|
||||
}
|
||||
|
||||
PyObject *arg_dict_from_component(PythonComponent *pc)
|
||||
{
|
||||
ComponentProperty *cprop;
|
||||
PyObject *args= NULL, *value=NULL;
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
args = PyDict_New();
|
||||
|
||||
cprop = pc->properties.first;
|
||||
|
||||
while (cprop)
|
||||
{
|
||||
if (cprop->type == CPROP_TYPE_INT)
|
||||
value = PyLong_FromLong(cprop->data);
|
||||
else if (cprop->type == CPROP_TYPE_FLOAT)
|
||||
value = PyFloat_FromDouble(*(float*)(&cprop->data));
|
||||
else if (cprop->type == CPROP_TYPE_BOOLEAN)
|
||||
value = PyBool_FromLong(cprop->data);
|
||||
else if (cprop->type == CPROP_TYPE_STRING)
|
||||
value = PyUnicode_FromString((char*)cprop->poin);
|
||||
else
|
||||
continue;
|
||||
|
||||
PyDict_SetItemString(args, cprop->name, value);
|
||||
|
||||
cprop= cprop->next;
|
||||
}
|
||||
|
||||
#endif /* WITH_PYTHON */
|
||||
return args;
|
||||
}
|
||||
|
||||
PythonComponent *new_component_from_import(char *import)
|
||||
{
|
||||
PythonComponent *pc = NULL;
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
PyObject *mod, *mod_list, *item, *py_name;
|
||||
PyGILState_STATE state;
|
||||
char *last_dot_str, *name;
|
||||
char cls[64], path[64];
|
||||
int i, last_dot;
|
||||
|
||||
// Don't bother with an empty string
|
||||
if (strcmp(import, "") == 0)
|
||||
return NULL;
|
||||
|
||||
// Split the class and module
|
||||
last_dot_str = strrchr(import, '.');
|
||||
last_dot = (int)(last_dot_str-import) + 1;
|
||||
|
||||
|
||||
if(last_dot > 0)
|
||||
{
|
||||
BLI_strncpy(path, import, last_dot);
|
||||
strcpy(cls, import+last_dot);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No component class was specified, only the module was.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state = PyGILState_Ensure();
|
||||
|
||||
// Try to load up the module
|
||||
mod = PyImport_ImportModule(path);
|
||||
|
||||
if (mod)
|
||||
{
|
||||
// Get the list of objects in the module
|
||||
mod_list = PyDict_Values(PyModule_GetDict(mod));
|
||||
|
||||
// Now iterate the list
|
||||
for (i=0; i<PyList_Size(mod_list); ++i)
|
||||
{
|
||||
item = PyList_GetItem(mod_list, i);
|
||||
|
||||
// We only want to bother checking type objects
|
||||
if (!PyType_Check(item))
|
||||
continue;
|
||||
|
||||
// Make sure the name matches
|
||||
py_name = PyObject_GetAttrString(item, "__name__");
|
||||
name = _PyUnicode_AsString(py_name);
|
||||
Py_DECREF(py_name);
|
||||
|
||||
if (strcmp(name, cls) != 0)
|
||||
continue;
|
||||
|
||||
// Check the subclass with our own function since we don't have access to the KX_PythonComponent type object
|
||||
if (!verify_class(item))
|
||||
{
|
||||
printf("A %s type was found, but it was not a valid subclass of KX_PythonComponent\n", cls);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have a valid class, make a component
|
||||
pc = MEM_callocN(sizeof(PythonComponent), "PythonComponent");
|
||||
|
||||
strcpy(pc->module, path);
|
||||
strcpy(pc->name, cls);
|
||||
|
||||
// Setup the properties
|
||||
create_properties(pc, item);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we still have a NULL component, then we didn't find a suitable class
|
||||
if (pc == NULL)
|
||||
printf("No suitable class was found for a component at %s\n", import);
|
||||
|
||||
// Take the module out of the module list so it's not cached by Python (this allows for simpler reloading of components)
|
||||
PyDict_DelItemString(PyImport_GetModuleDict(), path);
|
||||
|
||||
// Cleanup our Python objects
|
||||
Py_DECREF(mod);
|
||||
Py_DECREF(mod_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_Print();
|
||||
printf("Unable to load component from %s\n", import);
|
||||
}
|
||||
|
||||
PyGILState_Release(state);
|
||||
#endif /* WITH_PYTHON */
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
void free_component(PythonComponent *pc)
|
||||
{
|
||||
free_component_properties(&pc->properties);
|
||||
|
||||
MEM_freeN(pc);
|
||||
}
|
||||
|
||||
void free_components(ListBase *lb)
|
||||
{
|
||||
PythonComponent *pc;
|
||||
|
||||
while (pc= lb->first) {
|
||||
BLI_remlink(lb, pc);
|
||||
free_component(pc);
|
||||
}
|
||||
}
|
@@ -56,6 +56,7 @@
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_cloth_types.h"
|
||||
#include "DNA_component_types.h"
|
||||
#include "DNA_controller_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_effect_types.h"
|
||||
@@ -4164,6 +4165,8 @@ static void direct_link_object(FileData *fd, Object *ob)
|
||||
bSensor *sens;
|
||||
bController *cont;
|
||||
bActuator *act;
|
||||
PythonComponent *pc;
|
||||
ComponentProperty *cprop;
|
||||
|
||||
/* weak weak... this was only meant as draw flag, now is used in give_base_to_objects too */
|
||||
ob->flag &= ~OB_FROMGROUP;
|
||||
@@ -4324,6 +4327,20 @@ static void direct_link_object(FileData *fd, Object *ob)
|
||||
act= act->next;
|
||||
}
|
||||
|
||||
link_glob_list(fd, &ob->components);
|
||||
pc= ob->components.first;
|
||||
while(pc) {
|
||||
link_glob_list(fd, &pc->properties);
|
||||
cprop= pc->properties.first;
|
||||
while(cprop) {
|
||||
cprop->poin= newdataadr(fd, cprop->poin);
|
||||
cprop= cprop->next;
|
||||
}
|
||||
|
||||
pc= pc->next;
|
||||
}
|
||||
|
||||
|
||||
link_list(fd, &ob->hooks);
|
||||
while (ob->hooks.first) {
|
||||
ObHook *hook = ob->hooks.first;
|
||||
|
@@ -97,6 +97,7 @@ Any case: direct data is ALWAYS after the lib block
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_cloth_types.h"
|
||||
#include "DNA_component_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_controller_types.h"
|
||||
#include "DNA_genfile.h"
|
||||
@@ -1096,6 +1097,36 @@ static void write_actuators(WriteData *wd, ListBase *lb)
|
||||
}
|
||||
}
|
||||
|
||||
static void write_component_properties(WriteData *wd, ListBase *lb)
|
||||
{
|
||||
ComponentProperty *cprop;
|
||||
|
||||
cprop= lb->first;
|
||||
|
||||
while(cprop) {
|
||||
writestruct(wd, DATA, "ComponentProperty", 1, cprop);
|
||||
|
||||
if(cprop->poin)
|
||||
writedata(wd, DATA, MEM_allocN_len(cprop->poin), cprop->poin);
|
||||
|
||||
cprop= cprop->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_components(WriteData *wd, ListBase *lb)
|
||||
{
|
||||
PythonComponent *pc;
|
||||
|
||||
pc= lb->first;
|
||||
|
||||
while(pc) {
|
||||
writestruct(wd, DATA, "PythonComponent", 1, pc);
|
||||
write_component_properties(wd, &pc->properties);
|
||||
|
||||
pc= pc->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_motionpath(WriteData *wd, bMotionPath *mpath)
|
||||
{
|
||||
/* sanity checks */
|
||||
@@ -1321,6 +1352,7 @@ static void write_objects(WriteData *wd, ListBase *idbase)
|
||||
write_sensors(wd, &ob->sensors);
|
||||
write_controllers(wd, &ob->controllers);
|
||||
write_actuators(wd, &ob->actuators);
|
||||
write_components(wd, &ob->components);
|
||||
|
||||
if (ob->type == OB_ARMATURE) {
|
||||
bArmature *arm = ob->data;
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "DNA_sensor_types.h"
|
||||
#include "DNA_controller_types.h"
|
||||
#include "DNA_actuator_types.h"
|
||||
#include "DNA_component_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
@@ -43,6 +44,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_sca.h"
|
||||
#include "BKE_pycomponent.h"
|
||||
|
||||
#include "ED_logic.h"
|
||||
#include "ED_object.h"
|
||||
@@ -57,6 +59,8 @@
|
||||
|
||||
#include "logic_intern.h"
|
||||
|
||||
#include <stdio.h> /* sprintf */
|
||||
|
||||
/* ************* Generic Operator Helpers ************* */
|
||||
static int edit_sensor_poll(bContext *C)
|
||||
{
|
||||
@@ -687,6 +691,149 @@ static void LOGIC_OT_actuator_move(wmOperatorType *ot)
|
||||
RNA_def_enum(ot->srna, "direction", logicbricks_move_direction, 1, "Direction", "Move Up or Down");
|
||||
}
|
||||
|
||||
/* Component operators */
|
||||
static int component_add_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
|
||||
SpaceLogic *slogic= CTX_wm_space_logic(C);
|
||||
PythonComponent *pycomp;
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
char import[sizeof(slogic->import_string)];
|
||||
|
||||
if (!ob)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* We always want to clear the import_string after this operator is called */
|
||||
BLI_strncpy(import, slogic->import_string, sizeof(import));
|
||||
BLI_strncpy(slogic->import_string, "", sizeof(slogic->import_string));
|
||||
|
||||
pycomp = new_component_from_import(import);
|
||||
|
||||
if(!pycomp)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
BLI_addtail(&ob->components, pycomp);
|
||||
WM_event_add_notifier(C, NC_LOGIC, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void LOGIC_OT_component_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Add Component";
|
||||
ot->description= "Add Component";
|
||||
ot->idname= "LOGIC_OT_component_add";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= component_add_exec;
|
||||
ot->poll= ED_operator_object_active_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int component_remove_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
PythonComponent *pc= NULL;
|
||||
int index= RNA_int_get(op->ptr, "index");
|
||||
|
||||
if(!ob)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
pc= BLI_findlink(&ob->components, index);
|
||||
|
||||
if(!pc)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
BLI_remlink(&ob->components, pc);
|
||||
free_component(pc);
|
||||
|
||||
WM_event_add_notifier(C,NC_LOGIC, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void LOGIC_OT_component_remove(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Remove Component";
|
||||
ot->description= "Remove Component";
|
||||
ot->idname= "LOGIC_OT_component_remove";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= component_remove_exec;
|
||||
ot->poll= ED_operator_object_active_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Component index to remove", 0, INT_MAX);
|
||||
}
|
||||
|
||||
static int component_reload_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_active_object(C);
|
||||
PythonComponent *pc= NULL, *new_pc=NULL, *prev_pc=NULL;
|
||||
int index= RNA_int_get(op->ptr, "index");
|
||||
char import[64];
|
||||
|
||||
if(!ob)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
prev_pc= BLI_findlink(&ob->components, index-1);
|
||||
pc = prev_pc->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pc is at the head */
|
||||
pc = BLI_findlink(&ob->components, index);
|
||||
}
|
||||
|
||||
if(!pc)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* Try to create a new component */
|
||||
sprintf(import, "%s.%s", pc->module, pc->name);
|
||||
new_pc = new_component_from_import(import);
|
||||
|
||||
/* If creation failed, leave the old one along */
|
||||
if(!new_pc)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* Otherwise swap and destroy the old one */
|
||||
BLI_remlink(&ob->components, pc);
|
||||
free_component(pc);
|
||||
|
||||
if (prev_pc)
|
||||
BLI_insertlink(&ob->components, prev_pc, new_pc);
|
||||
else
|
||||
BLI_addhead(&ob->components, new_pc);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void LOGIC_OT_component_reload(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Reload Component";
|
||||
ot->description= "Reload Component";
|
||||
ot->idname= "LOGIC_OT_component_reload";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= component_reload_exec;
|
||||
ot->poll= ED_operator_object_active_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Component index to remove", 0, INT_MAX);
|
||||
}
|
||||
|
||||
void ED_operatortypes_logic(void)
|
||||
{
|
||||
@@ -699,4 +846,8 @@ void ED_operatortypes_logic(void)
|
||||
WM_operatortype_append(LOGIC_OT_actuator_remove);
|
||||
WM_operatortype_append(LOGIC_OT_actuator_add);
|
||||
WM_operatortype_append(LOGIC_OT_actuator_move);
|
||||
|
||||
WM_operatortype_append(LOGIC_OT_component_add);
|
||||
WM_operatortype_append(LOGIC_OT_component_remove);
|
||||
WM_operatortype_append(LOGIC_OT_component_reload);
|
||||
}
|
||||
|
28
source/blender/makesdna/DNA_component_types.h
Normal file
28
source/blender/makesdna/DNA_component_types.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef DNA_COMPONENT_TYPES_H
|
||||
#define DNA_COMPONENT_TYPES_H
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
typedef struct ComponentProperty {
|
||||
struct ComponentProperty *next, *prev;
|
||||
char name[32];
|
||||
short type, pad;
|
||||
int data;
|
||||
void *poin, *poin2;
|
||||
} ComponentProperty;
|
||||
|
||||
typedef struct PythonComponent {
|
||||
struct PythonComponent *next, *prev;
|
||||
ListBase properties;
|
||||
char name[64];
|
||||
char module[64];
|
||||
} PythonComponent;
|
||||
|
||||
|
||||
/* ComponentProperty.type */
|
||||
#define CPROP_TYPE_INT 0
|
||||
#define CPROP_TYPE_FLOAT 1
|
||||
#define CPROP_TYPE_STRING 2
|
||||
#define CPROP_TYPE_BOOLEAN 3
|
||||
#define CPROP_TYPE_SET 4
|
||||
#endif /*DNA_COMPONENT_TYPES_H*/
|
@@ -201,6 +201,7 @@ typedef struct Object {
|
||||
ListBase sensors;
|
||||
ListBase controllers;
|
||||
ListBase actuators;
|
||||
ListBase components;
|
||||
|
||||
float bbsize[3];
|
||||
short index; /* custom index, for renderpasses */
|
||||
|
@@ -430,6 +430,8 @@ typedef struct SpaceLogic {
|
||||
|
||||
short flag, scaflag;
|
||||
int pad;
|
||||
|
||||
char import_string[64];
|
||||
|
||||
struct bGPdata *gpd; /* grease-pencil data */
|
||||
} SpaceLogic;
|
||||
|
@@ -132,6 +132,7 @@ const char *includefiles[] = {
|
||||
"DNA_anim_types.h",
|
||||
"DNA_boid_types.h",
|
||||
"DNA_smoke_types.h",
|
||||
"DNA_component_types.h",
|
||||
|
||||
// empty string to indicate end of includefiles
|
||||
""
|
||||
@@ -1196,4 +1197,5 @@ int main(int argc, char ** argv)
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_boid_types.h"
|
||||
#include "DNA_smoke_types.h"
|
||||
#include "DNA_component_types.h"
|
||||
/* end of list */
|
||||
|
@@ -376,6 +376,7 @@ extern StructRNA RNA_PropertyGroupItem;
|
||||
extern StructRNA RNA_PropertySensor;
|
||||
extern StructRNA RNA_PythonConstraint;
|
||||
extern StructRNA RNA_PythonController;
|
||||
extern StructRNA RNA_PythonComponent;
|
||||
extern StructRNA RNA_RGBANodeSocket;
|
||||
extern StructRNA RNA_RadarSensor;
|
||||
extern StructRNA RNA_RandomSensor;
|
||||
|
@@ -68,6 +68,7 @@ set(DEFSRC
|
||||
rna_particle.c
|
||||
rna_pose.c
|
||||
rna_property.c
|
||||
rna_pycomponent.c
|
||||
rna_render.c
|
||||
rna_rna.c
|
||||
rna_scene.c
|
||||
|
@@ -2453,6 +2453,7 @@ static RNAProcessItem PROCESS_ITEMS[]= {
|
||||
{"rna_particle.c", NULL, RNA_def_particle},
|
||||
{"rna_pose.c", "rna_pose_api.c", RNA_def_pose},
|
||||
{"rna_property.c", NULL, RNA_def_gameproperty},
|
||||
{"rna_pycomponent.c", NULL, RNA_def_py_component},
|
||||
{"rna_render.c", NULL, RNA_def_render},
|
||||
{"rna_scene.c", "rna_scene_api.c", RNA_def_scene},
|
||||
{"rna_screen.c", NULL, RNA_def_screen},
|
||||
|
@@ -159,6 +159,7 @@ void RNA_def_object_force(struct BlenderRNA *brna);
|
||||
void RNA_def_packedfile(struct BlenderRNA *brna);
|
||||
void RNA_def_particle(struct BlenderRNA *brna);
|
||||
void RNA_def_pose(struct BlenderRNA *brna);
|
||||
void RNA_def_py_component(struct BlenderRNA *brna);
|
||||
void RNA_def_render(struct BlenderRNA *brna);
|
||||
void RNA_def_rna(struct BlenderRNA *brna);
|
||||
void RNA_def_scene(struct BlenderRNA *brna);
|
||||
|
@@ -38,6 +38,7 @@
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_component_types.h"
|
||||
#include "DNA_controller_types.h"
|
||||
#include "DNA_group_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
@@ -134,6 +135,7 @@ EnumPropertyItem object_type_curve_items[] = {
|
||||
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_bullet.h"
|
||||
#include "BKE_pycomponent.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
@@ -922,6 +924,16 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value)
|
||||
}
|
||||
}
|
||||
|
||||
static PythonComponent *rna_py_components_add(Object *ob, ReportList *reports, const char *path)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rna_py_components_remove(Object *ob, ReportList *reports, PythonComponent *pycomp)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static PointerRNA rna_Object_active_particle_system_get(PointerRNA *ptr)
|
||||
{
|
||||
Object *ob= (Object*)ptr->id.data;
|
||||
@@ -1327,6 +1339,35 @@ static void rna_def_material_slot(BlenderRNA *brna)
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
}
|
||||
|
||||
/* object.components */
|
||||
static void rna_def_py_components(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "Components");
|
||||
srna= RNA_def_struct(brna, "Components", NULL);
|
||||
RNA_def_struct_sdna(srna, "Object");
|
||||
RNA_def_struct_ui_text(srna, "Components", "Collection of components");
|
||||
|
||||
func= RNA_def_function(srna, "add", "rna_py_components_add");
|
||||
RNA_def_function_ui_description(func, "Add a component to an object");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
parm= RNA_def_string(func, "pypath", "", 64, "", "The import string for the component");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
|
||||
parm= RNA_def_pointer(func, "component", "PythonComponent", "", "The newly created component");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func= RNA_def_function(srna, "remove", "rna_py_components_remove");
|
||||
RNA_def_function_ui_description(func, "Remove a component from an object");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
parm= RNA_def_pointer(func, "component", "PythonComponent", "", "The component to remove");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
|
||||
}
|
||||
|
||||
static void rna_def_object_game_settings(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -1367,6 +1408,12 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
|
||||
RNA_def_property_struct_type(prop, "GameProperty"); /* rna_property.c */
|
||||
RNA_def_property_ui_text(prop, "Properties", "Game engine properties");
|
||||
|
||||
prop= RNA_def_property(srna, "components", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "components", NULL);
|
||||
RNA_def_property_struct_type(prop, "PythonComponent"); /* rna_pycomponent.c */
|
||||
RNA_def_property_ui_text(prop, "Components", "Game engine components");
|
||||
rna_def_py_components(brna, prop);
|
||||
|
||||
prop= RNA_def_property(srna, "show_sensors", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", OB_SHOWSENS);
|
||||
RNA_def_property_ui_text(prop, "Show Sensors", "Shows sensors for this object in the user interface");
|
||||
|
202
source/blender/makesrna/intern/rna_pycomponent.c
Normal file
202
source/blender/makesrna/intern/rna_pycomponent.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* $Id: rna_controller.c 32883 2010-11-05 07:35:21Z campbellbarton $
|
||||
*
|
||||
* ***** 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): Blender Foundation (2008).
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "rna_internal.h"
|
||||
#include "DNA_component_types.h"
|
||||
#include "DNA_property_types.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
//#include "BKE_pycomponent.h"
|
||||
|
||||
static StructRNA* rna_ComponentProperty_refine(struct PointerRNA *ptr)
|
||||
{
|
||||
ComponentProperty *cprop= (ComponentProperty*)ptr->data;
|
||||
|
||||
switch(cprop->type) {
|
||||
case CPROP_TYPE_BOOLEAN:
|
||||
return &RNA_ComponentBooleanProperty;
|
||||
case CPROP_TYPE_INT:
|
||||
return &RNA_ComponentIntProperty;
|
||||
case CPROP_TYPE_FLOAT:
|
||||
return &RNA_ComponentFloatProperty;
|
||||
case CPROP_TYPE_STRING:
|
||||
return &RNA_ComponentStringProperty;
|
||||
case CPROP_TYPE_SET:
|
||||
return &RNA_ComponentSetProperty;
|
||||
default:
|
||||
return &RNA_ComponentProperty;
|
||||
}
|
||||
}
|
||||
|
||||
static float rna_ComponentFloatProperty_value_get(PointerRNA *ptr)
|
||||
{
|
||||
ComponentProperty *cprop= (ComponentProperty*)(ptr->data);
|
||||
return *(float*)(&cprop->data);
|
||||
}
|
||||
|
||||
static void rna_ComponentFloatProperty_value_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
ComponentProperty *cprop= (ComponentProperty*)(ptr->data);
|
||||
*(float*)(&cprop->data)= value;
|
||||
}
|
||||
static int rna_ComponentSetProperty_get(struct PointerRNA *ptr)
|
||||
{
|
||||
ComponentProperty *cprop= (ComponentProperty*)(ptr->data);
|
||||
return cprop->data;
|
||||
}
|
||||
|
||||
static void rna_ComponentSetProperty_set(struct PointerRNA *ptr, int value)
|
||||
{
|
||||
ComponentProperty *cprop= (ComponentProperty*)(ptr->data);
|
||||
cprop->data = value;
|
||||
cprop->poin2 = (((EnumPropertyItem*)cprop->poin)+value)->identifier;
|
||||
}
|
||||
|
||||
EnumPropertyItem *rna_ComponentSetProperty_itemf(bContext *C, PointerRNA *ptr, int *free)
|
||||
{
|
||||
|
||||
ComponentProperty *cprop= (ComponentProperty*)(ptr->data);
|
||||
|
||||
*free = 0;
|
||||
return (EnumPropertyItem*)cprop->poin;
|
||||
}
|
||||
#else
|
||||
|
||||
void rna_def_py_component(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* Python Component */
|
||||
srna= RNA_def_struct(brna, "PythonComponent", NULL);
|
||||
RNA_def_struct_sdna(srna, "PythonComponent");
|
||||
RNA_def_struct_ui_text(srna, "Python Component", "");
|
||||
|
||||
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "name");
|
||||
RNA_def_property_ui_text(prop, "Name", "");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "properties", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "properties", NULL);
|
||||
RNA_def_property_struct_type(prop, "ComponentProperty");
|
||||
RNA_def_property_ui_text(prop, "Properties", "Component properties");
|
||||
}
|
||||
|
||||
void rna_def_py_component_property(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem empty_items[] = {
|
||||
{0, "EMPTY", 0, "Empty", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
/* Base Python Component Property */
|
||||
srna= RNA_def_struct(brna, "ComponentProperty", NULL);
|
||||
RNA_def_struct_sdna(srna, "ComponentProperty");
|
||||
RNA_def_struct_ui_text(srna, "Python Component Property", "A property of a Python Component");
|
||||
RNA_def_struct_refine_func(srna, "rna_ComponentProperty_refine");
|
||||
|
||||
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "name");
|
||||
RNA_def_property_ui_text(prop, "Name", "");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
/* Boolean */
|
||||
srna= RNA_def_struct(brna, "ComponentBooleanProperty", "ComponentProperty");
|
||||
RNA_def_struct_sdna(srna, "ComponentProperty");
|
||||
RNA_def_struct_ui_text(srna, "Python Component Boolean Property", "A boolean property of a Python Component");
|
||||
|
||||
prop= RNA_def_property(srna, "value", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "data", 1);
|
||||
RNA_def_property_ui_text(prop, "Value", "Property value");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
/* Int */
|
||||
srna= RNA_def_struct(brna, "ComponentIntProperty", "ComponentProperty");
|
||||
RNA_def_struct_sdna(srna, "ComponentProperty");
|
||||
RNA_def_struct_ui_text(srna, "Python Component Integer Property", "An integer property of a Python Component");
|
||||
|
||||
prop= RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "data");
|
||||
RNA_def_property_ui_text(prop, "Value", "Property value");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
/* Float */
|
||||
srna= RNA_def_struct(brna, "ComponentFloatProperty", "ComponentProperty");
|
||||
RNA_def_struct_sdna(srna, "ComponentProperty");
|
||||
RNA_def_struct_ui_text(srna, "Python Component Float Property", "A float property of a Python Component");
|
||||
|
||||
prop= RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Value", "Property value");
|
||||
RNA_def_property_float_funcs(prop, "rna_ComponentFloatProperty_value_get", "rna_ComponentFloatProperty_value_set", NULL);
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
/* String */
|
||||
srna= RNA_def_struct(brna, "ComponentStringProperty", "ComponentProperty");
|
||||
RNA_def_struct_sdna(srna, "ComponentProperty");
|
||||
RNA_def_struct_ui_text(srna, "Python Component String Property", "A string property of a Python Component");
|
||||
|
||||
prop= RNA_def_property(srna, "value", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "poin");
|
||||
RNA_def_property_string_maxlength(prop, MAX_PROPSTRING);
|
||||
RNA_def_property_ui_text(prop, "Value", "Property value");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
|
||||
/* Set */
|
||||
//#if 0
|
||||
srna= RNA_def_struct(brna, "ComponentSetProperty", "ComponentProperty");
|
||||
RNA_def_struct_sdna(srna, "ComponentProperty");
|
||||
RNA_def_struct_ui_text(srna, "Python Component Set Property", "A set property of a Python Component");
|
||||
|
||||
prop= RNA_def_property(srna, "value", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, empty_items);
|
||||
RNA_def_property_enum_funcs(prop, "rna_ComponentSetProperty_get", "rna_ComponentSetProperty_set", "rna_ComponentSetProperty_itemf");
|
||||
RNA_def_property_enum_default(prop, 0);
|
||||
//RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_ComponentSetProperty_itemf");
|
||||
RNA_def_property_ui_text(prop, "Value", "Property value");
|
||||
RNA_def_property_update(prop, NC_LOGIC, NULL);
|
||||
//#endif
|
||||
|
||||
}
|
||||
|
||||
void RNA_def_py_component(BlenderRNA *brna)
|
||||
{
|
||||
rna_def_py_component(brna);
|
||||
rna_def_py_component_property(brna);
|
||||
}
|
||||
|
||||
#endif /* RNA_RUNTIME */
|
@@ -2506,6 +2506,12 @@ static void rna_def_space_logic(BlenderRNA *brna)
|
||||
RNA_def_struct_sdna(srna, "SpaceLogic");
|
||||
RNA_def_struct_ui_text(srna, "Space Logic Editor", "Logic editor space data");
|
||||
|
||||
/* Properties */
|
||||
prop= RNA_def_property(srna, "import_string", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "import_string");
|
||||
RNA_def_property_ui_text(prop, "Import String", "Import string used to find the component when adding a new component");
|
||||
|
||||
|
||||
/* sensors */
|
||||
prop= RNA_def_property(srna, "show_sensors_selected_objects", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_SENS_SEL);
|
||||
|
@@ -60,6 +60,8 @@
|
||||
#include "../generic/blf_py_api.h"
|
||||
#include "../mathutils/mathutils.h"
|
||||
|
||||
#include "../../../gameengine/Ketsji/KX_PythonInitTypes.h"
|
||||
|
||||
PyObject *bpy_package_py= NULL;
|
||||
|
||||
PyDoc_STRVAR(bpy_script_paths_doc,
|
||||
@@ -251,6 +253,9 @@ void BPy_init_modules(void)
|
||||
/* stand alone utility modules not related to blender directly */
|
||||
IDProp_Init_Types(); /* not actually a submodule, just types */
|
||||
|
||||
/* Setup a dummy BGE module so we can import BGE classes for introspection */
|
||||
initPyTypes();
|
||||
PyRun_SimpleString("sys = __import__('sys');mod = sys.modules['bge'] = type(sys)('bge');mod.__dict__.update({'logic':'', 'render':'', 'events':'', 'constraints':'', 'types':__import__('GameTypes'), 'texture':''});");
|
||||
mod= PyModule_New("_bpy");
|
||||
|
||||
/* add the module so we can import it */
|
||||
|
@@ -102,6 +102,8 @@
|
||||
#include "KX_KetsjiEngine.h"
|
||||
#include "KX_BlenderSceneConverter.h"
|
||||
|
||||
#include "KX_PyConstraintBinding.h"
|
||||
|
||||
/* This little block needed for linking to Blender... */
|
||||
#ifdef WIN32
|
||||
#include "BLI_winstuff.h"
|
||||
@@ -2712,6 +2714,9 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
converter->RegisterWorldInfo(worldinfo);
|
||||
kxscene->SetWorldInfo(worldinfo);
|
||||
|
||||
// Set the physics environment so KX_PythonComponent.start() can use bge.constraints
|
||||
PHY_SetActiveEnvironment(kxscene->GetPhysicsEnvironment());
|
||||
|
||||
#define CONVERT_LOGIC
|
||||
#ifdef CONVERT_LOGIC
|
||||
// convert logic bricks, sensors, controllers and actuators
|
||||
@@ -2742,12 +2747,13 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
|
||||
gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
|
||||
}
|
||||
// apply the initial state to controllers, only on the active objects as this registers the sensors
|
||||
// also, to avoid another loop, we initialze components here
|
||||
for ( i=0;i<objectlist->GetCount();i++)
|
||||
{
|
||||
KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i));
|
||||
gameobj->ResetState();
|
||||
gameobj->InitComponents();
|
||||
}
|
||||
|
||||
#endif //CONVERT_LOGIC
|
||||
|
||||
logicbrick_conversionlist->Release();
|
||||
|
@@ -98,6 +98,7 @@ set(SRC
|
||||
KX_PositionInterpolator.cpp
|
||||
KX_PyConstraintBinding.cpp
|
||||
KX_PyMath.cpp
|
||||
KX_PythonComponent.cpp
|
||||
KX_PythonInit.cpp
|
||||
KX_PythonInitTypes.cpp
|
||||
KX_PythonSeq.cpp
|
||||
@@ -175,6 +176,7 @@ set(SRC
|
||||
KX_PositionInterpolator.h
|
||||
KX_PyConstraintBinding.h
|
||||
KX_PyMath.h
|
||||
KX_PythonComponent.h
|
||||
KX_PythonInit.h
|
||||
KX_PythonInitTypes.h
|
||||
KX_PythonSeq.h
|
||||
|
@@ -45,11 +45,11 @@ typedef unsigned long uint_ptr;
|
||||
#pragma warning( disable : 4786 )
|
||||
#endif
|
||||
|
||||
|
||||
#define KX_INERTIA_INFINITE 10000
|
||||
#include "RAS_IPolygonMaterial.h"
|
||||
#include "KX_BlenderMaterial.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "KX_PythonComponent.h"
|
||||
#include "KX_Camera.h" // only for their ::Type
|
||||
#include "KX_Light.h" // only for their ::Type
|
||||
#include "KX_FontObject.h" // only for their ::Type
|
||||
@@ -83,6 +83,9 @@ typedef unsigned long uint_ptr;
|
||||
|
||||
#include "BLI_math.h"
|
||||
|
||||
/* Component stuff */
|
||||
#include "DNA_component_types.h"
|
||||
|
||||
static MT_Point3 dummy_point= MT_Point3(0.0, 0.0, 0.0);
|
||||
static MT_Vector3 dummy_scaling = MT_Vector3(1.0, 1.0, 1.0);
|
||||
static MT_Matrix3x3 dummy_orientation = MT_Matrix3x3( 1.0, 0.0, 0.0,
|
||||
@@ -160,6 +163,15 @@ KX_GameObject::~KX_GameObject()
|
||||
/* Py_CLEAR: Py_DECREF's and NULL's */
|
||||
Py_CLEAR(m_attr_dict);
|
||||
}
|
||||
|
||||
ComponentList::iterator it;
|
||||
for (it=m_components.begin(); it != m_components.end(); ++it)
|
||||
{
|
||||
Py_DECREF(*it);
|
||||
}
|
||||
|
||||
m_components.clear();
|
||||
|
||||
#endif // WITH_PYTHON
|
||||
}
|
||||
|
||||
@@ -360,6 +372,8 @@ void KX_GameObject::ProcessReplica()
|
||||
m_attr_dict= PyDict_Copy(m_attr_dict);
|
||||
#endif
|
||||
|
||||
// Reinitialize any components
|
||||
InitComponents();
|
||||
}
|
||||
|
||||
static void setGraphicController_recursive(SG_Node* node)
|
||||
@@ -1221,6 +1235,137 @@ CListValue* KX_GameObject::GetChildrenRecursive()
|
||||
return list;
|
||||
}
|
||||
|
||||
ComponentList &KX_GameObject::GetComponents()
|
||||
{
|
||||
return m_components;
|
||||
}
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
PyObject *arg_dict_from_component(PythonComponent *pc)
|
||||
{
|
||||
ComponentProperty *cprop;
|
||||
PyObject *args= NULL, *value=NULL;
|
||||
|
||||
args = PyDict_New();
|
||||
|
||||
cprop = (ComponentProperty*)pc->properties.first;
|
||||
|
||||
while (cprop)
|
||||
{
|
||||
if (cprop->type == CPROP_TYPE_INT)
|
||||
value = PyLong_FromLong(cprop->data);
|
||||
else if (cprop->type == CPROP_TYPE_FLOAT)
|
||||
value = PyFloat_FromDouble(*(float*)(&cprop->data));
|
||||
else if (cprop->type == CPROP_TYPE_BOOLEAN)
|
||||
value = PyBool_FromLong(cprop->data);
|
||||
else if (cprop->type == CPROP_TYPE_STRING)
|
||||
value = PyUnicode_FromString((char*)cprop->poin);
|
||||
else if (cprop->type == CPROP_TYPE_SET)
|
||||
value = PyUnicode_FromString((char*)cprop->poin2);
|
||||
else
|
||||
{
|
||||
cprop= cprop->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
PyDict_SetItemString(args, cprop->name, value);
|
||||
|
||||
cprop= cprop->next;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
#endif /* WITH_PYTHON */
|
||||
|
||||
void KX_GameObject::InitComponents()
|
||||
{
|
||||
#ifdef WITH_PYTHON
|
||||
PythonComponent *pc = (PythonComponent*)GetBlenderObject()->components.first;
|
||||
PyObject *arg_dict=NULL, *args=NULL, *mod=NULL, *cls=NULL, *pycomp;
|
||||
|
||||
while (pc)
|
||||
{
|
||||
// Make sure to clean out anything from previous loops
|
||||
Py_XDECREF(args);
|
||||
Py_XDECREF(arg_dict);
|
||||
Py_XDECREF(mod);
|
||||
Py_XDECREF(cls);
|
||||
args = mod = cls = NULL;
|
||||
|
||||
// Grab the module
|
||||
mod = PyImport_ImportModule(pc->module);
|
||||
|
||||
if (mod == NULL)
|
||||
{
|
||||
if (PyErr_Occurred()) PyErr_Print();
|
||||
printf("Coulding import the module '%s'\n", pc->module);
|
||||
pc = pc->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Clear the module from sys.modules
|
||||
//PyDict_DelItemString(PyImport_GetModuleDict(), pc->module);
|
||||
|
||||
// Grab the class object
|
||||
cls = PyObject_GetAttrString(mod, pc->name);
|
||||
if (cls == NULL)
|
||||
{
|
||||
if (PyErr_Occurred()) PyErr_Print();
|
||||
printf("Python module found, but failed to find the compoent '%s'\n", pc->name);
|
||||
pc = pc->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Lastly make sure we have a class and it's an appropriate sub type
|
||||
if (!PyType_Check(cls) || !PyObject_IsSubclass(cls, (PyObject*)&KX_PythonComponent::Type))
|
||||
{
|
||||
printf("%s.%s is not a KX_PythonComponent subclass\n", pc->module, pc->name);
|
||||
pc = pc->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Every thing checks out, now generate the args dictionary and init the component
|
||||
arg_dict = arg_dict_from_component(pc);
|
||||
args = PyTuple_New(1);
|
||||
PyTuple_SetItem(args, 0, GetProxy());
|
||||
|
||||
pycomp = PyObject_Call(cls, args, NULL);
|
||||
|
||||
PyObject_CallMethod(pycomp, "start", "O", arg_dict);
|
||||
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
// The component is invalid, drop it
|
||||
PyErr_Print();
|
||||
Py_XDECREF(pycomp);
|
||||
}
|
||||
else
|
||||
m_components.push_back(pycomp);
|
||||
|
||||
pc = pc->next;
|
||||
}
|
||||
|
||||
|
||||
Py_XDECREF(args);
|
||||
Py_XDECREF(arg_dict);
|
||||
Py_XDECREF(mod);
|
||||
Py_XDECREF(cls);
|
||||
|
||||
#endif // WITH_PYTHON
|
||||
}
|
||||
|
||||
void KX_GameObject::UpdateComponents()
|
||||
{
|
||||
#ifdef WITH_PYTHON
|
||||
for (size_t i=0; i<m_components.size(); ++i)
|
||||
{
|
||||
if (!PyObject_CallMethod(m_components[i], "update", ""))
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
#endif // WITH_PYTHON
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* Some stuff taken from the header
|
||||
* --------------------------------------------------------------------- */
|
||||
@@ -1536,6 +1681,7 @@ PyAttributeDef KX_GameObject::Attributes[] = {
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("childrenRecursive", KX_GameObject, pyattr_get_children_recursive),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("attrDict", KX_GameObject, pyattr_get_attrDict),
|
||||
KX_PYATTRIBUTE_RW_FUNCTION("color", KX_GameObject, pyattr_get_obcolor, pyattr_set_obcolor),
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("components", KX_GameObject, pyattr_get_components),
|
||||
|
||||
/* Experemental, dont rely on these yet */
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("sensors", KX_GameObject, pyattr_get_sensors),
|
||||
@@ -2220,6 +2366,11 @@ int KX_GameObject::pyattr_set_obcolor(void *self_v, const KX_PYATTRIBUTE_DEF *at
|
||||
return PY_SET_ATTR_SUCCESS;
|
||||
}
|
||||
|
||||
PyObject* KX_GameObject::pyattr_get_components(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
return KX_PythonSeq_CreatePyObject((static_cast<KX_GameObject*>(self_v))->m_proxy, KX_PYGENSEQ_OB_TYPE_COMPONENTS);
|
||||
}
|
||||
|
||||
/* These are experimental! */
|
||||
PyObject* KX_GameObject::pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
@@ -3029,7 +3180,7 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
|
||||
}
|
||||
|
||||
if (PyUnicode_Check(value)) {
|
||||
*object = (KX_GameObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String( _PyUnicode_AsString(value) ));
|
||||
*object = (KX_GameObject*)KX_GetActiveScene()->GetLogicManager()->GetGameObjectByName(STR_String( _PyUnicode_AsString(value) ));
|
||||
|
||||
if (*object) {
|
||||
return true;
|
||||
|
@@ -74,6 +74,8 @@ bool ConvertPythonToGameObject(PyObject * value, KX_GameObject **object, bool py
|
||||
void KX_GameObject_Mathutils_Callback_Init(void);
|
||||
#endif
|
||||
|
||||
typedef std::vector<PyObject*> ComponentList;
|
||||
|
||||
/**
|
||||
* KX_GameObject is the main class for dynamic objects.
|
||||
*/
|
||||
@@ -112,6 +114,10 @@ protected:
|
||||
SG_Node* m_pSGNode;
|
||||
|
||||
MT_CmMatrix4x4 m_OpenGL_4x4Matrix;
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
ComponentList m_components;
|
||||
#endif
|
||||
|
||||
public:
|
||||
bool m_isDeformable;
|
||||
@@ -801,6 +807,21 @@ public:
|
||||
CListValue* GetChildren();
|
||||
CListValue* GetChildrenRecursive();
|
||||
|
||||
/**
|
||||
* Returns the component list
|
||||
*/
|
||||
ComponentList &GetComponents();
|
||||
|
||||
/**
|
||||
* Initializes the components
|
||||
*/
|
||||
void InitComponents();
|
||||
|
||||
/**
|
||||
* Updates the components
|
||||
*/
|
||||
void UpdateComponents();
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
/**
|
||||
* @section Python interface functions.
|
||||
@@ -901,6 +922,7 @@ public:
|
||||
static PyObject* pyattr_get_attrDict(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_obcolor(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static int pyattr_set_obcolor(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static PyObject* pyattr_get_components(void *selv_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
/* Experemental! */
|
||||
static PyObject* pyattr_get_sensors(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
162
source/gameengine/Ketsji/KX_PythonComponent.cpp
Normal file
162
source/gameengine/Ketsji/KX_PythonComponent.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
#include "KX_PythonComponent.h"
|
||||
#include "KX_GameObject.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Native functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
KX_PythonComponent::KX_PythonComponent(char *name)
|
||||
: PyObjectPlus(),
|
||||
m_gameobj(NULL),
|
||||
m_name(name)
|
||||
{
|
||||
}
|
||||
|
||||
KX_PythonComponent::~KX_PythonComponent()
|
||||
{
|
||||
}
|
||||
|
||||
STR_String& KX_PythonComponent::GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
KX_GameObject* KX_PythonComponent::GetGameobject()
|
||||
{
|
||||
return m_gameobj;
|
||||
}
|
||||
|
||||
void KX_PythonComponent::SetGameobject(KX_GameObject *gameobj)
|
||||
{
|
||||
m_gameobj = gameobj;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Python functions */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
PyObject *KX_PythonComponent::py_component_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObjectPlus_Proxy *self;
|
||||
char name[64];
|
||||
|
||||
self = (PyObjectPlus_Proxy*)type->tp_alloc(type, 0);
|
||||
|
||||
if (self)
|
||||
{
|
||||
BLI_strncpy(name, Py_TYPE(self)->tp_name, sizeof(name));
|
||||
|
||||
self->ptr = NULL;
|
||||
self->ref = new KX_PythonComponent(name);
|
||||
self->py_owns = true;
|
||||
self->py_ref = true;
|
||||
}
|
||||
|
||||
return (PyObject*)self;
|
||||
}
|
||||
|
||||
int KX_PythonComponent::py_component_init(PyObjectPlus_Proxy *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
KX_GameObject *gameobj;
|
||||
KX_PythonComponent *kxpycomp;
|
||||
PyObject *pyobj;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &pyobj))
|
||||
return -1;
|
||||
|
||||
if (!PyObject_IsInstance(pyobj, (PyObject*)&KX_GameObject::Type))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "expected a KX_GameObject for first argument");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gameobj = static_cast<KX_GameObject*>(BGE_PROXY_REF(pyobj));
|
||||
kxpycomp = static_cast<KX_PythonComponent*>(BGE_PROXY_REF(self));
|
||||
|
||||
kxpycomp->SetGameobject(gameobj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Integration hooks ------------------------------------------------------- */
|
||||
PyTypeObject KX_PythonComponent::Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"KX_PythonComponent",
|
||||
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,
|
||||
&PyObjectPlus::Type,
|
||||
0,0,0,0,
|
||||
(initproc)py_component_init,
|
||||
0,
|
||||
py_component_new
|
||||
};
|
||||
|
||||
PyMethodDef KX_PythonComponent::Methods[] = {
|
||||
KX_PYMETHODTABLE_O(KX_PythonComponent, start),
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
PyAttributeDef KX_PythonComponent::Attributes[] = {
|
||||
KX_PYATTRIBUTE_RO_FUNCTION("object", KX_PythonComponent, pyattr_get_object),
|
||||
{ NULL } //Sentinel
|
||||
};
|
||||
|
||||
PyObject* KX_PythonComponent::pyattr_get_object(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
|
||||
{
|
||||
KX_PythonComponent* self= static_cast<KX_PythonComponent*>(self_v);
|
||||
KX_GameObject *gameobj = self->GetGameobject();
|
||||
|
||||
if (gameobj)
|
||||
return gameobj->GetProxy();
|
||||
else
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
KX_PYMETHODDEF_DOC_O(KX_PythonComponent, start,
|
||||
"start(args)\n"
|
||||
"initializes the component")
|
||||
{
|
||||
printf("base start\n");
|
||||
// We leave this empty, derived classes should define their own if they need it
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
#endif
|
60
source/gameengine/Ketsji/KX_PythonComponent.h
Normal file
60
source/gameengine/Ketsji/KX_PythonComponent.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
* ***** 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): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __KX_PYCOMPONENT
|
||||
#define __KX_PYCOMPONENT
|
||||
#ifndef DISABLE_PYTHON
|
||||
|
||||
#include "PyObjectPlus.h"
|
||||
|
||||
class KX_PythonComponent : public PyObjectPlus
|
||||
{
|
||||
Py_Header;
|
||||
private:
|
||||
// member vars
|
||||
class KX_GameObject *m_gameobj;
|
||||
STR_String m_name;
|
||||
|
||||
public:
|
||||
KX_PythonComponent(char *name);
|
||||
virtual ~KX_PythonComponent();
|
||||
|
||||
STR_String& GetName();
|
||||
|
||||
class KX_GameObject *GetGameobject();
|
||||
void SetGameobject(class KX_GameObject*);
|
||||
|
||||
static PyObject *py_component_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
||||
static int py_component_init(PyObjectPlus_Proxy *self, PyObject *args, PyObject *kwds);
|
||||
|
||||
// Methods
|
||||
KX_PYMETHOD_DOC_O(KX_PythonComponent, start);
|
||||
|
||||
// Attributes
|
||||
static PyObject* pyattr_get_object(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
|
||||
};
|
||||
|
||||
#endif //ndef DISABLE_PYTHON
|
||||
#endif //__KX_PYCOMPONENT
|
||||
|
@@ -63,6 +63,7 @@
|
||||
#include "KX_PolyProxy.h"
|
||||
#include "KX_PolygonMaterial.h"
|
||||
#include "KX_PythonSeq.h"
|
||||
#include "KX_PythonComponent.h"
|
||||
#include "KX_SCA_AddObjectActuator.h"
|
||||
#include "KX_SCA_EndObjectActuator.h"
|
||||
#include "KX_SCA_ReplaceMeshActuator.h"
|
||||
@@ -164,7 +165,7 @@ static void PyType_Ready_ADD(PyObject *dict, PyTypeObject *tp, PyAttributeDef *a
|
||||
#define PyType_Ready_Attr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, NULL, i)
|
||||
#define PyType_Ready_AttrPtr(d, n, i) PyType_Ready_ADD(d, &n::Type, n::Attributes, n::AttributesPtr, i)
|
||||
|
||||
void initPyTypes(void)
|
||||
extern "C" void initPyTypes(void)
|
||||
{
|
||||
|
||||
/*
|
||||
@@ -210,6 +211,7 @@ void initPyTypes(void)
|
||||
PyType_Ready_Attr(dict, KX_PhysicsObjectWrapper, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_PolyProxy, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_PolygonMaterial, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_PythonComponent, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_RadarSensor, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_RaySensor, init_getset);
|
||||
PyType_Ready_Attr(dict, KX_SCA_AddObjectActuator, init_getset);
|
||||
|
@@ -35,7 +35,18 @@
|
||||
#define _adr_py_init_types_h_ // even if multiply included
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void initPyTypes(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include "SCA_ISensor.h"
|
||||
#include "SCA_IController.h"
|
||||
#include "SCA_IActuator.h"
|
||||
#include "KX_PythonComponent.h"
|
||||
|
||||
|
||||
PyObject *KX_PythonSeq_CreatePyObject( PyObject *base, short type )
|
||||
@@ -91,6 +92,8 @@ static Py_ssize_t KX_PythonSeq_len( PyObject * self )
|
||||
return ((KX_GameObject *)self_plus)->GetControllers().size();
|
||||
case KX_PYGENSEQ_OB_TYPE_ACTUATORS:
|
||||
return ((KX_GameObject *)self_plus)->GetActuators().size();
|
||||
case KX_PYGENSEQ_OB_TYPE_COMPONENTS:
|
||||
return ((KX_GameObject *)self_plus)->GetComponents().size();
|
||||
case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS:
|
||||
return ((BL_ArmatureObject *)self_plus)->GetConstraintNumber();
|
||||
case KX_PYGENSEQ_OB_TYPE_CHANNELS:
|
||||
@@ -162,6 +165,17 @@ static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index)
|
||||
}
|
||||
return linkedactuators[index]->GetProxy();
|
||||
}
|
||||
case KX_PYGENSEQ_OB_TYPE_COMPONENTS:
|
||||
{
|
||||
ComponentList& components= ((KX_GameObject *)self_plus)->GetComponents();
|
||||
if(index<0) index += components.size();
|
||||
if(index<0 || index>= components.size()) {
|
||||
PyErr_SetString(PyExc_IndexError, "seq[i]: index out of range");
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(components[index]);
|
||||
return components[index];
|
||||
}
|
||||
case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS:
|
||||
{
|
||||
int nb_constraint = ((BL_ArmatureObject *)self_plus)->GetConstraintNumber();
|
||||
@@ -252,6 +266,17 @@ static PyObjectPlus * KX_PythonSeq_subscript__internal(PyObject *self, char *key
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KX_PYGENSEQ_OB_TYPE_COMPONENTS:
|
||||
{
|
||||
ComponentList& components= ((KX_GameObject *)self_plus)->GetComponents();
|
||||
PyObject *comp;
|
||||
for (unsigned int index=0;index<components.size();index++) {
|
||||
comp = components[index];
|
||||
if (strcmp(Py_TYPE(comp)->tp_name, key) == 0)
|
||||
return (PyObjectPlus*)comp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KX_PYGENSEQ_OB_TYPE_CONSTRAINTS:
|
||||
{
|
||||
return ((BL_ArmatureObject*)self_plus)->GetConstraint(key);
|
||||
@@ -283,6 +308,11 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key)
|
||||
PyObjectPlus *ret = KX_PythonSeq_subscript__internal(self, name);
|
||||
|
||||
if(ret) {
|
||||
if (((KX_PythonSeq *)self)->type == KX_PYGENSEQ_OB_TYPE_COMPONENTS)
|
||||
{
|
||||
Py_INCREF((PyObject*)ret);
|
||||
return (PyObject*)ret;
|
||||
}
|
||||
return ret->GetProxy();
|
||||
} else {
|
||||
PyErr_Format( PyExc_KeyError, "requested item \"%s\" does not exist", name);
|
||||
@@ -326,7 +356,14 @@ PyObject* KX_PythonSeq_get(PyObject * self, PyObject *args)
|
||||
return NULL;
|
||||
|
||||
if((ret_plus = KX_PythonSeq_subscript__internal(self, key)))
|
||||
{
|
||||
if (((KX_PythonSeq*)self)->type == KX_PYGENSEQ_OB_TYPE_COMPONENTS)
|
||||
{
|
||||
Py_INCREF((PyObject*)ret_plus);
|
||||
return (PyObject*)ret_plus;
|
||||
}
|
||||
return ret_plus->GetProxy();
|
||||
}
|
||||
|
||||
Py_INCREF(def);
|
||||
return def;
|
||||
|
@@ -46,6 +46,7 @@ enum KX_PYGENSEQ_TYPE {
|
||||
KX_PYGENSEQ_OB_TYPE_SENSORS,
|
||||
KX_PYGENSEQ_OB_TYPE_CONTROLLERS,
|
||||
KX_PYGENSEQ_OB_TYPE_ACTUATORS,
|
||||
KX_PYGENSEQ_OB_TYPE_COMPONENTS,
|
||||
KX_PYGENSEQ_OB_TYPE_CONSTRAINTS,
|
||||
KX_PYGENSEQ_OB_TYPE_CHANNELS,
|
||||
};
|
||||
|
@@ -1506,6 +1506,9 @@ void KX_Scene::LogicBeginFrame(double curtime)
|
||||
|
||||
void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
|
||||
{
|
||||
// Update object components
|
||||
for (int i=0; i<m_objectlist->GetCount(); ++i)
|
||||
((KX_GameObject*)m_objectlist->GetValue(i))->UpdateComponents();
|
||||
m_logicmgr->UpdateFrame(curtime, frame);
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,99 @@
|
||||
<<<<<<< .working
|
||||
# $Id$
|
||||
# ***** 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.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2006, Blender Foundation
|
||||
# All rights reserved.
|
||||
#
|
||||
# The Original Code is: all of this file.
|
||||
#
|
||||
# Contributor(s): Jacques Beaurain.
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
../../../source/gameengine/Ketsji
|
||||
../../../source/gameengine/Expressions
|
||||
../../../source/gameengine/GameLogic
|
||||
../../../source/gameengine/SceneGraph
|
||||
../../../source/gameengine/Rasterizer
|
||||
../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
|
||||
../../../source/gameengine/BlenderRoutines
|
||||
../../../source/blender/blenlib
|
||||
../../../source/blender/blenkernel
|
||||
../../../source/blender/makesdna
|
||||
../../../source/blender/editors/include
|
||||
../../../source/blender/imbuf
|
||||
../../../source/blender/python
|
||||
../../../source/blender/python/generic
|
||||
../../../source/blender/gpu
|
||||
../../../intern/container
|
||||
../../../intern/string
|
||||
../../../intern/moto/include
|
||||
../../../intern/guardedalloc
|
||||
${GLEW_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
Exception.cpp
|
||||
FilterBase.cpp
|
||||
FilterBlueScreen.cpp
|
||||
FilterColor.cpp
|
||||
FilterNormal.cpp
|
||||
FilterSource.cpp
|
||||
ImageBase.cpp
|
||||
ImageBuff.cpp
|
||||
ImageMix.cpp
|
||||
ImageRender.cpp
|
||||
ImageViewport.cpp
|
||||
PyTypeList.cpp
|
||||
Texture.cpp
|
||||
VideoBase.cpp
|
||||
VideoFFmpeg.cpp
|
||||
blendVideoTex.cpp
|
||||
|
||||
BlendType.h
|
||||
Common.h
|
||||
Exception.h
|
||||
FilterBase.h
|
||||
FilterBlueScreen.h
|
||||
FilterColor.h
|
||||
FilterNormal.h
|
||||
FilterSource.h
|
||||
ImageBase.h
|
||||
ImageBuff.h
|
||||
ImageMix.h
|
||||
ImageRender.h
|
||||
ImageViewport.h
|
||||
PyTypeList.h
|
||||
Texture.h
|
||||
VideoBase.h
|
||||
VideoFFmpeg.h
|
||||
)
|
||||
|
||||
if(WITH_CODEC_FFMPEG)
|
||||
set(INC ${INC} ${FFMPEG_INC} ${PTHREADS_INC})
|
||||
add_definitions(-DWITH_FFMPEG)
|
||||
add_definitions(-D__STDC_CONSTANT_MACROS)
|
||||
endif()
|
||||
|
||||
blender_add_lib(ge_videotex "${SRC}" "${INC}")
|
||||
=======
|
||||
# $Id$
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
@@ -99,3 +195,4 @@ if(WITH_CODEC_FFMPEG)
|
||||
endif()
|
||||
|
||||
blender_add_lib(ge_videotex "${SRC}" "${INC}" "${INC_SYS}")
|
||||
>>>>>>> .merge-right.r38806
|
||||
|
Reference in New Issue
Block a user