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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Converter')
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp805
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.h126
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp149
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.h79
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp1227
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.h54
-rw-r--r--source/gameengine/Converter/BL_DeformableGameObject.cpp62
-rw-r--r--source/gameengine/Converter/BL_DeformableGameObject.h66
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.cpp165
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.h72
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp187
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h98
-rw-r--r--source/gameengine/Converter/BL_SkinMeshObject.cpp152
-rw-r--r--source/gameengine/Converter/BL_SkinMeshObject.h184
-rw-r--r--source/gameengine/Converter/BlenderWorldInfo.cpp215
-rw-r--r--source/gameengine/Converter/BlenderWorldInfo.h95
-rw-r--r--source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp81
-rw-r--r--source/gameengine/Converter/KX_BlenderScalarInterpolator.h70
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp416
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.h120
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp909
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.h48
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp179
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.h51
-rw-r--r--source/gameengine/Converter/KX_ConvertProperties.cpp134
-rw-r--r--source/gameengine/Converter/KX_ConvertProperties.h41
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp658
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.h47
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.cpp559
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.h54
-rw-r--r--source/gameengine/Converter/Makefile60
31 files changed, 7163 insertions, 0 deletions
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
new file mode 100644
index 00000000000..cbe0dd2263c
--- /dev/null
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -0,0 +1,805 @@
+/**
+* $Id$
+*
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+*/
+
+#include "SCA_LogicManager.h"
+#include "BL_ActionActuator.h"
+#include "BL_ArmatureObject.h"
+#include "BL_SkinDeformer.h"
+#include "KX_GameObject.h"
+#include "STR_HashedString.h"
+#include "DNA_action_types.h"
+#include "DNA_actuator_types.h"
+#include "BKE_action.h"
+#include "DNA_armature_types.h"
+#include "MEM_guardedalloc.h"
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "MT_Matrix4x4.h"
+#include "BKE_utildefines.h"
+
+BL_ActionActuator::~BL_ActionActuator()
+{
+ if (m_pose) {
+ clear_pose(m_pose);
+ MEM_freeN(m_pose);
+ m_pose = NULL;
+ };
+
+ if (m_userpose){
+ clear_pose(m_userpose);
+ MEM_freeN(m_userpose);
+ m_userpose=NULL;
+ }
+ if (m_blendpose) {
+ clear_pose(m_blendpose);
+ MEM_freeN(m_blendpose);
+ m_blendpose = NULL;
+ };
+
+}
+
+void BL_ActionActuator::ProcessReplica(){
+ bPose *oldpose = m_pose;
+ bPose *oldbpose = m_blendpose;
+
+ m_pose = NULL;
+ m_blendpose = NULL;
+ m_localtime=m_starttime;
+ m_lastUpdate=-1;
+
+}
+
+void BL_ActionActuator::SetBlendTime (float newtime){
+ m_blendframe = newtime;
+}
+
+CValue* BL_ActionActuator::GetReplica() {
+ BL_ActionActuator* replica = new BL_ActionActuator(*this);//m_float,GetName());
+ replica->ProcessReplica();
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+bool BL_ActionActuator::Update(double curtime,double deltatime)
+{
+ bool bNegativeEvent = false;
+ bool bPositiveEvent = false;
+ int numevents = m_events.size();
+ bool keepgoing = true;
+ bool wrap = false;
+ bool apply=true;
+ int priority;
+ float newweight;
+
+ // result = true if animation has to be continued, false if animation stops
+ // maybe there are events for us in the queue !
+
+ for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());)
+ {
+ i--;
+ if ((*i)->GetNumber() == 0.0f)
+ {
+ int ka=0;
+ bNegativeEvent = true;
+ }
+ else
+ bPositiveEvent= true;
+ (*i)->Release();
+ m_events.pop_back();
+ }
+
+ /* We know that action actuators have been discarded from all non armature objects:
+ if we're being called, we're attached to a BL_ArmatureObject */
+ BL_ArmatureObject *obj = (BL_ArmatureObject*)GetParent();
+ int length = m_endtime - m_starttime;
+
+ priority = m_priority;
+
+ /* Determine pre-incrementation behaviour and set appropriate flags */
+ switch (m_playtype){
+ case ACT_ACTION_MOTION:
+ if (bNegativeEvent){
+ keepgoing=false;
+ apply=false;
+ };
+ break;
+ case ACT_ACTION_FROM_PROP:
+ if (bNegativeEvent){
+ apply=false;
+ keepgoing=false;
+ }
+ break;
+ case ACT_ACTION_LOOP_END:
+ if (bPositiveEvent){
+ if (!(m_flag & ACT_FLAG_LOCKINPUT)){
+ m_flag &= ~ACT_FLAG_KEYUP;
+ m_flag &= ~ACT_FLAG_REVERSE;
+ m_flag |= ACT_FLAG_LOCKINPUT;
+ m_localtime = m_starttime;
+ }
+ }
+ if (bNegativeEvent){
+ m_flag |= ACT_FLAG_KEYUP;
+ }
+ break;
+ case ACT_ACTION_LOOP_STOP:
+ if (bPositiveEvent){
+ if (!(m_flag & ACT_FLAG_LOCKINPUT)){
+ m_flag &= ~ACT_FLAG_REVERSE;
+ }
+ }
+ if (bNegativeEvent){
+ keepgoing=false;
+ apply=false;
+ }
+ break;
+ case ACT_ACTION_FLIPPER:
+ if (bPositiveEvent){
+ if (!(m_flag & ACT_FLAG_LOCKINPUT)){
+ m_flag &= ~ACT_FLAG_REVERSE;
+ }
+ }
+ else if (bNegativeEvent){
+ m_flag |= ACT_FLAG_REVERSE;
+ }
+ break;
+ case ACT_ACTION_PLAY:
+ if (bPositiveEvent){
+ if (!(m_flag & ACT_FLAG_LOCKINPUT)){
+ m_flag &= ~ACT_FLAG_REVERSE;
+ m_localtime = m_starttime;
+ m_flag |= ACT_FLAG_LOCKINPUT;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Perform increment */
+ if (keepgoing){
+ if (m_playtype == ACT_ACTION_MOTION){
+ MT_Point3 newpos;
+ MT_Point3 deltapos;
+
+ newpos = obj->NodeGetWorldPosition();
+
+ /* Find displacement */
+ deltapos = newpos-m_lastpos;
+ m_localtime += (length/m_stridelength) * deltapos.length();
+ m_lastpos = newpos;
+ }
+ else{
+ if (m_flag & ACT_FLAG_REVERSE)
+ m_localtime -= deltatime* KX_FIXED_FRAME_PER_SEC;
+ else
+ m_localtime += deltatime* KX_FIXED_FRAME_PER_SEC;
+ }
+ }
+
+ /* Check if a wrapping response is needed */
+ if (length){
+ if (m_flag & ACT_FLAG_REVERSE){
+ if (m_localtime < m_starttime){
+ m_localtime = m_endtime+(
+ (int)((m_localtime - m_starttime)/length)
+ *(int)length);
+ wrap = true;
+ }
+ }
+ else{
+ if (m_localtime > m_endtime){
+ m_localtime = m_starttime+(
+ (int)((m_localtime - m_endtime)/length)
+ *(int)length);
+ wrap = true;
+ }
+ }
+
+ }
+ else
+ m_localtime = m_starttime;
+
+ /* Perform post-increment tasks */
+ switch (m_playtype){
+ case ACT_ACTION_FROM_PROP:
+ {
+ CValue* propval = GetParent()->GetProperty(m_propname);
+ if (propval) {
+ m_localtime = propval->GetNumber();
+ };
+
+ if (bNegativeEvent){
+ keepgoing=false;
+ }
+ }
+ break;
+ case ACT_ACTION_MOTION:
+ break;
+ case ACT_ACTION_LOOP_STOP:
+ break;
+ case ACT_ACTION_FLIPPER:
+ if (wrap){
+ if (!(m_flag & ACT_FLAG_REVERSE)){
+ m_localtime=m_endtime;
+ keepgoing = false;
+ }
+ else {
+ m_localtime=m_starttime;
+ keepgoing = false;
+ }
+ }
+ break;
+ case ACT_ACTION_LOOP_END:
+ if (wrap){
+ if (m_flag & ACT_FLAG_KEYUP){
+ keepgoing = false;
+ m_localtime = m_endtime;
+ m_flag &= ~ACT_FLAG_LOCKINPUT;
+ }
+ }
+ break;
+ case ACT_ACTION_PLAY:
+ if (wrap){
+ m_localtime = m_endtime;
+ keepgoing = false;
+ m_flag &= ~ACT_FLAG_LOCKINPUT;
+ }
+ break;
+ default:
+ keepgoing = false;
+ break;
+ }
+
+
+ if (bNegativeEvent){
+ m_blendframe=0.0;
+
+ }
+
+
+ /* Apply the pose if necessary*/
+ if (apply){
+
+ /* Priority test */
+ if (obj->SetActiveAction(this, priority, curtime)){
+
+ /* Get the underlying pose from the armature */
+ obj->GetPose(&m_pose);
+
+ /* Override the necessary channels with ones from the action */
+ get_pose_from_action(&m_pose, m_action, m_localtime);
+
+ /* Perform the user override (if any) */
+ if (m_userpose){
+ get_pose_from_pose(&m_pose, m_userpose);
+ clear_pose(m_userpose);
+ MEM_freeN(m_userpose);
+ m_userpose = NULL;
+ }
+#if 1
+ /* Handle blending */
+ if (m_blendin && (m_blendframe<m_blendin)){
+ /* If this is the start of a blending sequence... */
+ if ((m_blendframe==0.0) || (!m_blendpose)){
+ obj->GetMRDPose(&m_blendpose);
+ }
+
+ /* Find percentages */
+ newweight = (m_blendframe/(float)m_blendin);
+ blend_poses(m_pose, m_blendpose, 1.0 - newweight, POSE_BLEND);
+
+ /* Increment current blending percentage */
+ m_blendframe+=(deltatime*KX_FIXED_FRAME_PER_SEC);
+ if (m_blendframe>m_blendin)
+ m_blendframe = m_blendin;
+
+ }
+#endif
+ m_lastUpdate = m_localtime;
+ obj->SetPose (m_pose);
+ }
+ else{
+ m_blendframe = 0.0;
+ }
+ }
+
+ if (!keepgoing){
+ m_blendframe = 0.0;
+ }
+ return keepgoing;
+};
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+
+PyTypeObject BL_ActionActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "BL_ActionActuator",
+ sizeof(BL_ActionActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject BL_ActionActuator::Parents[] = {
+ &BL_ActionActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef BL_ActionActuator::Methods[] = {
+ {"setAction", (PyCFunction) BL_ActionActuator::sPySetAction, METH_VARARGS, SetAction_doc},
+ {"setStart", (PyCFunction) BL_ActionActuator::sPySetStart, METH_VARARGS, SetStart_doc},
+ {"setEnd", (PyCFunction) BL_ActionActuator::sPySetEnd, METH_VARARGS, SetEnd_doc},
+ {"setBlendin", (PyCFunction) BL_ActionActuator::sPySetBlendin, METH_VARARGS, SetBlendin_doc},
+ {"setPriority", (PyCFunction) BL_ActionActuator::sPySetPriority, METH_VARARGS, SetPriority_doc},
+ {"setFrame", (PyCFunction) BL_ActionActuator::sPySetFrame, METH_VARARGS, SetFrame_doc},
+ {"setProperty", (PyCFunction) BL_ActionActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"setBlendtime", (PyCFunction) BL_ActionActuator::sPySetBlendtime, METH_VARARGS, SetBlendtime_doc},
+
+ {"getAction", (PyCFunction) BL_ActionActuator::sPyGetAction, METH_VARARGS, GetAction_doc},
+ {"getStart", (PyCFunction) BL_ActionActuator::sPyGetStart, METH_VARARGS, GetStart_doc},
+ {"getEnd", (PyCFunction) BL_ActionActuator::sPyGetEnd, METH_VARARGS, GetEnd_doc},
+ {"getBlendin", (PyCFunction) BL_ActionActuator::sPyGetBlendin, METH_VARARGS, GetBlendin_doc},
+ {"getPriority", (PyCFunction) BL_ActionActuator::sPyGetPriority, METH_VARARGS, GetPriority_doc},
+ {"getFrame", (PyCFunction) BL_ActionActuator::sPyGetFrame, METH_VARARGS, GetFrame_doc},
+ {"getProperty", (PyCFunction) BL_ActionActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
+ {"setChannel", (PyCFunction) BL_ActionActuator::sPySetChannel, METH_VARARGS, SetChannel_doc},
+// {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_VARARGS},
+
+ {NULL,NULL} //Sentinel
+};
+
+PyObject* BL_ActionActuator::_getattr(char* attr) {
+ _getattr_up(SCA_IActuator);
+}
+
+/* setStart */
+char BL_ActionActuator::GetAction_doc[] =
+"getAction()\n"
+"\tReturns a string containing the name of the current action.\n";
+
+PyObject* BL_ActionActuator::PyGetAction(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ if (m_action){
+ result = Py_BuildValue("s", m_action->id.name+2);
+ }
+ else{
+ Py_INCREF(Py_None);
+ result = Py_None;
+ }
+
+ return result;
+}
+
+/* getProperty */
+char BL_ActionActuator::GetProperty_doc[] =
+"getProperty()\n"
+"\tReturns the name of the property to be used in FromProp mode.\n";
+
+PyObject* BL_ActionActuator::PyGetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("s", m_propname);
+
+ return result;
+}
+
+/* getFrame */
+char BL_ActionActuator::GetFrame_doc[] =
+"getFrame()\n"
+"\tReturns the current frame number.\n";
+
+PyObject* BL_ActionActuator::PyGetFrame(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("f", m_localtime);
+
+ return result;
+}
+
+/* getEnd */
+char BL_ActionActuator::GetEnd_doc[] =
+"getEnd()\n"
+"\tReturns the last frame of the action.\n";
+
+PyObject* BL_ActionActuator::PyGetEnd(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("f", m_endtime);
+
+ return result;
+}
+
+/* getStart */
+char BL_ActionActuator::GetStart_doc[] =
+"getStart()\n"
+"\tReturns the starting frame of the action.\n";
+
+PyObject* BL_ActionActuator::PyGetStart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("f", m_starttime);
+
+ return result;
+}
+
+/* getBlendin */
+char BL_ActionActuator::GetBlendin_doc[] =
+"getBlendin()\n"
+"\tReturns the number of interpolation animation frames to be\n"
+"\tgenerated when this actuator is triggered.\n";
+
+PyObject* BL_ActionActuator::PyGetBlendin(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("f", m_blendin);
+
+ return result;
+}
+
+/* getPriority */
+char BL_ActionActuator::GetPriority_doc[] =
+"getPriority()\n"
+"\tReturns the priority for this actuator. Actuators with lower\n"
+"\tPriority numbers will override actuators with higher numbers.\n";
+
+PyObject* BL_ActionActuator::PyGetPriority(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ PyObject *result;
+
+ result = Py_BuildValue("i", m_priority);
+
+ return result;
+}
+
+/* setAction */
+char BL_ActionActuator::SetAction_doc[] =
+"setAction(action, (reset))\n"
+"\t - action : The name of the action to set as the current action.\n"
+"\t - reset : Optional parameter indicating whether to reset the\n"
+"\t blend timer or not. A value of 1 indicates that the\n"
+"\t timer should be reset. A value of 0 will leave it\n"
+"\t unchanged. If reset is not specified, the timer will"
+"\t be reset.\n";
+
+PyObject* BL_ActionActuator::PySetAction(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *string;
+ int reset = 1;
+
+ if (PyArg_ParseTuple(args,"s|i",&string, &reset))
+ {
+ bAction *action;
+
+ action = (bAction*)SCA_ILogicBrick::m_sCurrentLogicManager->GetActionByName(STR_String(string));
+
+ if (!action){
+ /* NOTE! Throw an exception or something */
+ // printf ("setAction failed: Action not found\n", string);
+ }
+ else{
+ m_action=action;
+ if (reset)
+ m_blendframe = 0;
+ }
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setStart */
+char BL_ActionActuator::SetStart_doc[] =
+"setStart(start)\n"
+"\t - start : Specifies the starting frame of the animation.\n";
+
+PyObject* BL_ActionActuator::PySetStart(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float start;
+
+ if (PyArg_ParseTuple(args,"f",&start))
+ {
+ m_starttime = start;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setEnd */
+char BL_ActionActuator::SetEnd_doc[] =
+"setEnd(end)\n"
+"\t - end : Specifies the ending frame of the animation.\n";
+
+PyObject* BL_ActionActuator::PySetEnd(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float end;
+
+ if (PyArg_ParseTuple(args,"f",&end))
+ {
+ m_endtime = end;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setBlendin */
+char BL_ActionActuator::SetBlendin_doc[] =
+"setBlendin(blendin)\n"
+"\t - blendin : Specifies the number of frames of animation to generate\n"
+"\t when making transitions between actions.\n";
+
+PyObject* BL_ActionActuator::PySetBlendin(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float blendin;
+
+ if (PyArg_ParseTuple(args,"f",&blendin))
+ {
+ m_blendin = blendin;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setBlendtime */
+char BL_ActionActuator::SetBlendtime_doc[] =
+"setBlendtime(blendtime)\n"
+"\t - blendtime : Allows the script to directly modify the internal timer\n"
+"\t used when generating transitions between actions. This\n"
+"\t parameter must be in the range from 0.0 to 1.0.\n";
+
+PyObject* BL_ActionActuator::PySetBlendtime(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float blendframe;
+
+ if (PyArg_ParseTuple(args,"f",&blendframe))
+ {
+ m_blendframe = blendframe * m_blendin;
+ if (m_blendframe<0)
+ m_blendframe = 0;
+ if (m_blendframe>m_blendin)
+ m_blendframe = m_blendin;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setPriority */
+char BL_ActionActuator::SetPriority_doc[] =
+"setPriority(priority)\n"
+"\t - priority : Specifies the new priority. Actuators will lower\n"
+"\t priority numbers will override actuators with higher\n"
+"\t numbers.\n";
+
+PyObject* BL_ActionActuator::PySetPriority(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int priority;
+
+ if (PyArg_ParseTuple(args,"i",&priority))
+ {
+ m_priority = priority;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setFrame */
+char BL_ActionActuator::SetFrame_doc[] =
+"setFrame(frame)\n"
+"\t - frame : Specifies the new current frame for the animation\n";
+
+PyObject* BL_ActionActuator::PySetFrame(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float frame;
+
+ if (PyArg_ParseTuple(args,"f",&frame))
+ {
+ m_localtime = frame;
+ if (m_localtime<m_starttime)
+ m_localtime=m_starttime;
+ else if (m_localtime>m_endtime)
+ m_localtime=m_endtime;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* setProperty */
+char BL_ActionActuator::SetProperty_doc[] =
+"setProperty(prop)\n"
+"\t - prop : A string specifying the property name to be used in\n"
+"\t FromProp playback mode.\n";
+
+PyObject* BL_ActionActuator::PySetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *string;
+
+ if (PyArg_ParseTuple(args,"s",&string))
+ {
+ m_propname = string;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/*
+PyObject* BL_ActionActuator::PyGetChannel(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *string;
+
+ if (PyArg_ParseTuple(args,"s",&string))
+ {
+ m_propname = string;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+*/
+
+/* setChannel */
+char BL_ActionActuator::SetChannel_doc[] =
+"setChannel(channel, matrix)\n"
+"\t - channel : A string specifying the name of the bone channel.\n"
+"\t - matrix : A 4x4 matrix specifying the overriding transformation\n"
+"\t as an offset from the bone's rest position.\n";
+
+PyObject* BL_ActionActuator::PySetChannel(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float matrix[4][4];
+ char *string;
+ PyObject* pylist;
+ bool error = false;
+ int row,col;
+ int mode = 0; /* 0 for bone space, 1 for armature/world space */
+
+ PyArg_ParseTuple(args,"sO|i", &string, &pylist, &mode);
+
+ if (pylist->ob_type == &CListValue::Type)
+ {
+ CListValue* listval = (CListValue*) pylist;
+ if (listval->GetCount() == 4)
+ {
+ for (row=0;row<4;row++) // each row has a 4-vector [x,y,z, w]
+ {
+ CListValue* vecval = (CListValue*)listval->GetValue(row);
+ for (col=0;col<4;col++)
+ {
+ matrix[row][col] = vecval->GetValue(col)->GetNumber();
+
+ }
+ }
+ }
+ else
+ {
+ error = true;
+ }
+ }
+ else
+ {
+ // assert the list is long enough...
+ int numitems = PyList_Size(pylist);
+ if (numitems == 4)
+ {
+ for (row=0;row<4;row++) // each row has a 4-vector [x,y,z, w]
+ {
+
+ PyObject* veclist = PyList_GetItem(pylist,row); // here we have a vector4 list
+ for (col=0;col<4;col++)
+ {
+ matrix[row][col] = PyFloat_AsDouble(PyList_GetItem(veclist,col));
+
+ }
+ }
+ }
+ else
+ {
+ error = true;
+ }
+ }
+
+ if (!error)
+ {
+
+/* DO IT HERE */
+ bPoseChannel *pchan;
+
+ pchan = (bPoseChannel*) MEM_callocN(sizeof(bPoseChannel), "userChannel");
+ strcpy(pchan->name, string);
+ Mat4ToQuat(matrix, pchan->quat);
+ Mat4ToSize(matrix, pchan->size);
+ VECCOPY (pchan->loc, matrix[3]);
+
+ pchan->flag |= POSE_ROT|POSE_LOC|POSE_SIZE;
+
+ if (!m_userpose){
+ m_userpose = (bPose*)MEM_callocN(sizeof(bPose), "userPose");
+ }
+
+ verify_pose_channel(m_userpose, string);
+ set_pose_channel(m_userpose, pchan);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
new file mode 100644
index 00000000000..49485cb324d
--- /dev/null
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -0,0 +1,126 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BL_ACTIONACTUATOR
+#define BL_ACTIONACTUATOR
+
+#include "SCA_IActuator.h"
+#include "MT_Point3.h"
+
+class BL_ActionActuator : public SCA_IActuator
+{
+public:
+ Py_Header;
+ BL_ActionActuator(SCA_IObject* gameobj,
+ const STR_String& propname,
+ float starttime,
+ float endtime,
+ struct bAction *action,
+ short playtype,
+ short blendin,
+ short priority,
+ float stride,
+ PyTypeObject* T=&Type)
+ : SCA_IActuator(gameobj,T),
+ m_starttime (starttime),
+ m_endtime(endtime) ,
+ m_localtime(starttime),
+ m_lastUpdate(-1),
+ m_propname(propname),
+ m_action(action),
+ m_playtype(playtype),
+ m_flag(0),
+ m_blendin(blendin),
+ m_blendframe(0),
+ m_pose(NULL),
+ m_userpose(NULL),
+ m_blendpose(NULL),
+ m_priority(priority),
+ m_stridelength(stride),
+ m_lastpos(0, 0, 0)
+ {
+ };
+ virtual ~BL_ActionActuator();
+ virtual bool Update(double curtime,double deltatime);
+ CValue* GetReplica();
+ void ProcessReplica();
+
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetAction);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetBlendin);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetPriority);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetStart);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetEnd);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetFrame);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetProperty);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetBlendtime);
+ KX_PYMETHOD_DOC(BL_ActionActuator,SetChannel);
+
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetAction);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetBlendin);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetPriority);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetStart);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetEnd);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetFrame);
+ KX_PYMETHOD_DOC(BL_ActionActuator,GetProperty);
+// KX_PYMETHOD(BL_ActionActuator,GetChannel);
+
+
+ virtual PyObject* _getattr(char* attr);
+ void SetBlendTime (float newtime);
+
+protected:
+ float m_blendframe;
+ MT_Point3 m_lastpos;
+ int m_flag;
+ float m_starttime;
+ float m_endtime;
+ float m_localtime;
+ float m_lastUpdate;
+ short m_playtype;
+ float m_blendin;
+ short m_priority;
+ float m_stridelength;
+ struct bPose* m_pose;
+ struct bPose* m_blendpose;
+ struct bPose* m_userpose;
+ STR_String m_propname;
+ struct bAction *m_action;
+
+};
+
+enum {
+ ACT_FLAG_REVERSE = 0x00000001,
+ ACT_FLAG_LOCKINPUT = 0x00000002,
+ ACT_FLAG_KEYUP = 0x00000004
+};
+#endif
+
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
new file mode 100644
index 00000000000..1668cd522a3
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -0,0 +1,149 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "BL_ArmatureObject.h"
+#include "BL_ActionActuator.h"
+#include "BLI_blenlib.h"
+#include "BKE_action.h"
+#include "BKE_armature.h"
+#include "GEN_Map.h"
+#include "GEN_HashedPtr.h"
+#include "MEM_guardedalloc.h"
+#include "DNA_action_types.h"
+
+CValue* BL_ArmatureObject::GetReplica()
+{
+ BL_ArmatureObject* replica = new BL_ArmatureObject(*this);
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ ProcessReplica(replica);
+ return replica;
+}
+
+void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica)
+{
+ KX_GameObject::ProcessReplica(replica);
+
+}
+
+BL_ArmatureObject::~BL_ArmatureObject()
+{
+ if (m_mrdPose){
+ clear_pose(m_mrdPose);
+ MEM_freeN(m_mrdPose);
+ }
+}
+
+void BL_ArmatureObject::ApplyPose()
+{
+ if (m_pose){
+ apply_pose_armature(m_armature, m_pose, 1);
+ if (!m_mrdPose)
+ copy_pose (&m_mrdPose, m_pose, 0);
+ else
+ get_pose_from_pose(&m_mrdPose, m_pose);
+ }
+}
+
+void BL_ArmatureObject::SetPose(bPose *pose)
+{
+ m_pose = pose;
+}
+
+bool BL_ArmatureObject::SetActiveAction(BL_ActionActuator *act, short priority, double curtime)
+{
+ if (curtime != m_lastframe){
+ m_activePriority = 9999;
+ m_lastframe= curtime;
+ m_activeAct = NULL;
+ }
+
+ if (priority<=m_activePriority)
+ {
+ if (m_activeAct && (m_activeAct!=act))
+ m_activeAct->SetBlendTime(0.0); /* Reset the blend timer */
+ m_activeAct = act;
+ m_activePriority = priority;
+ m_lastframe = curtime;
+
+ return true;
+ }
+ else{
+ act->SetBlendTime(0.0);
+ return false;
+ }
+
+}
+
+BL_ActionActuator * BL_ArmatureObject::GetActiveAction()
+{
+ return m_activeAct;
+}
+
+void BL_ArmatureObject::GetPose(bPose **pose)
+{
+ /* If the caller supplies a null pose, create a new one. */
+ /* Otherwise, copy the armature's pose channels into the caller-supplied pose */
+ if (!*pose)
+ copy_pose(pose, m_pose, 0);
+ else
+ get_pose_from_pose(pose, m_pose);
+
+}
+
+void BL_ArmatureObject::GetMRDPose(bPose **pose)
+{
+ /* If the caller supplies a null pose, create a new one. */
+ /* Otherwise, copy the armature's pose channels into the caller-supplied pose */
+
+ if (!m_mrdPose){
+ copy_pose (&m_mrdPose, m_pose, 0);
+ }
+
+ if (!*pose)
+ copy_pose(pose, m_mrdPose, 0);
+ else
+ get_pose_from_pose(pose, m_mrdPose);
+
+}
+
+short BL_ArmatureObject::GetActivePriority()
+{
+ return m_activePriority;
+}
+
+double BL_ArmatureObject::GetLastFrame()
+{
+ return m_lastframe;
+}
diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h
new file mode 100644
index 00000000000..a438eced5d2
--- /dev/null
+++ b/source/gameengine/Converter/BL_ArmatureObject.h
@@ -0,0 +1,79 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BL_ARMATUREOBJECT
+#define BL_ARMATUREOBJECT
+
+#include "KX_GameObject.h"
+
+#include "SG_IObject.h"
+
+class BL_ActionActuator;
+
+class BL_ArmatureObject : public KX_GameObject
+{
+public:
+ double GetLastFrame ();
+ short GetActivePriority();
+ virtual void ProcessReplica(BL_ArmatureObject *replica);
+ class BL_ActionActuator * GetActiveAction();
+ BL_ArmatureObject(void* sgReplicationInfo, SG_Callbacks callbacks,
+ struct bArmature *arm,
+ struct bPose *pose) :
+ KX_GameObject(sgReplicationInfo,callbacks),
+ m_pose(pose),
+ m_mrdPose(NULL),
+ m_armature(arm),
+ m_activeAct(NULL),
+ m_activePriority(999)
+ {}
+
+ virtual CValue* GetReplica();
+ virtual ~BL_ArmatureObject();
+ void GetMRDPose(bPose **pose);
+ void GetPose(struct bPose **pose);
+ void SetPose (struct bPose *pose);
+ void ApplyPose();
+ bool SetActiveAction(class BL_ActionActuator *act, short priority, double curtime);
+ struct bArmature * GetArmature(){return m_armature;};
+
+protected:
+ struct bArmature *m_armature;
+ struct bPose *m_pose;
+ struct bPose *m_mrdPose;
+ double m_lastframe;
+ class BL_ActionActuator *m_activeAct;
+ short m_activePriority;
+};
+
+#endif
+
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
new file mode 100644
index 00000000000..68d45044fff
--- /dev/null
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -0,0 +1,1227 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Convert blender data to ketsji
+ */
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif
+
+#include "BL_BlenderDataConversion.h"
+#include "KX_BlenderGL.h"
+#include "KX_BlenderScalarInterpolator.h"
+
+#include "RAS_IPolygonMaterial.h"
+
+// Expressions
+#include "ListValue.h"
+#include "IntValue.h"
+// Collision & Fuzzics LTD
+
+#include "PHY_Pro.h"
+
+
+#include "KX_Scene.h"
+#include "KX_GameObject.h"
+#include "RAS_FramingManager.h"
+#include "RAS_MeshObject.h"
+
+#include "KX_ConvertActuators.h"
+#include "KX_ConvertControllers.h"
+#include "KX_ConvertSensors.h"
+
+#include "KX_GameObject.h"
+#include "SCA_LogicManager.h"
+#include "SCA_EventManager.h"
+#include "SCA_TimeEventManager.h"
+#include "KX_Light.h"
+#include "KX_Camera.h"
+#include "KX_EmptyObject.h"
+#include "MT_Point3.h"
+#include "MT_Transform.h"
+#include "SCA_IInputDevice.h"
+#include "RAS_TexMatrix.h"
+#include "RAS_ICanvas.h"
+#include "RAS_MaterialBucket.h"
+//#include "KX_BlenderPolyMaterial.h"
+#include "RAS_Polygon.h"
+#include "RAS_TexVert.h"
+#include "RAS_BucketManager.h"
+#include "RAS_IRenderTools.h"
+
+#include "DNA_action_types.h"
+#include "BKE_main.h"
+#include "BL_SkinMeshObject.h"
+#include "BL_SkinDeformer.h"
+#include "BL_MeshDeformer.h"
+//#include "BL_ArmatureController.h"
+
+#include "BlenderWorldInfo.h"
+
+#include "KX_KetsjiEngine.h"
+#include "KX_BlenderSceneConverter.h"
+
+#include"SND_Scene.h"
+#include "SND_SoundListener.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+/* This list includes only data type definitions */
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_group_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_property_types.h"
+#include "DNA_text_types.h"
+#include "DNA_sensor_types.h"
+#include "DNA_controller_types.h"
+#include "DNA_actuator_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_key_types.h"
+
+
+#include "MEM_guardedalloc.h"
+#include "BKE_utildefines.h"
+#include "BKE_key.h"
+#include "BKE_mesh.h"
+#include "MT_Point3.h"
+
+
+#include "BKE_material.h" /* give_current_material */
+/* end of blender include block */
+
+#include "KX_BlenderInputDevice.h"
+#include "KX_ConvertProperties.h"
+#include "KX_HashedPtr.h"
+
+
+#include "KX_ScalarInterpolator.h"
+
+#include "KX_IpoConvert.h"
+#include "SYS_System.h"
+
+#include "SG_Node.h"
+
+#include "KX_ConvertPhysicsObject.h"
+
+
+// This file defines relationships between parents and children
+// in the game engine.
+
+#include "KX_SG_NodeRelationships.h"
+
+#include "BL_ArmatureObject.h"
+#include "BL_DeformableGameObject.h"
+
+static unsigned int KX_rgbaint2uint_new(unsigned int icol)
+{
+ unsigned int temp=0;
+ unsigned char *cp= (unsigned char *)&temp;
+ unsigned char *src= (unsigned char *)&icol;
+ cp[3]= src[0];//alpha
+ cp[2]= src[1];//blue
+ cp[1]= src[2];//green
+ cp[0]= src[3];//red
+ return temp;
+}
+
+/* Now the real converting starts... */
+static unsigned int KX_Mcol2uint_new(MCol col)
+{
+ /* color has to be converted without endian sensitivity. So no shifting! */
+ unsigned int temp=0;
+ unsigned char *cp= (unsigned char *)&temp;
+ cp[3]=255;
+ cp[2]= col.r;
+ cp[1]= col.g;
+ cp[0]= col.b;
+ return temp;
+}
+
+RAS_MeshObject* BL_ConvertMesh(Mesh* mesh,Object* blenderobj,RAS_IRenderTools* rendertools,KX_Scene* scene,KX_BlenderSceneConverter *converter)
+{
+ RAS_MeshObject *meshobj;
+ bool skinMesh = false;
+
+ int lightlayer = blenderobj->lay;
+
+ // Determine if we need to make a skinned mesh
+ if (mesh->dvert){
+ meshobj = new BL_SkinMeshObject(lightlayer);
+ skinMesh = true;
+ }
+ else {
+ meshobj = new RAS_MeshObject(lightlayer);
+ }
+
+ meshobj->SetName(mesh->id.name);
+
+
+ MFace* mface = static_cast<MFace*>(mesh->mface);
+ TFace* tface = static_cast<TFace*>(mesh->tface);
+
+
+ MCol* mmcol = mesh->mcol;
+
+
+ meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
+
+ for (int f=0;f<mesh->totface;f++,mface++,tface++)
+ {
+
+ bool collider = true;
+
+ // only add valid polygons
+ if (mface->v3)
+ {
+
+ MT_Vector3 no0(0.0,0.0,0.0),no1(0.0,0.0,0.0),no2(0.0,0.0,0.0),no3(0.0,0.0,0.0);
+ MT_Point3 pt0,pt1,pt2,pt3;
+
+ MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
+ // rgb3 is set from the adjoint face in a square
+ unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
+ pt0 = MT_Point3( mesh->mvert[mface->v1].co[0],
+ mesh->mvert[mface->v1].co[1],
+ mesh->mvert[mface->v1].co[2]);
+ no0 = MT_Vector3(
+ mesh->mvert[mface->v1].no[0]/32767.0,
+ mesh->mvert[mface->v1].no[1]/32767.0,
+ mesh->mvert[mface->v1].no[2]/32767.0
+ );
+
+ pt1 = MT_Point3( mesh->mvert[mface->v2].co[0],
+ mesh->mvert[mface->v2].co[1],
+ mesh->mvert[mface->v2].co[2]);
+
+ no1 = MT_Vector3(
+ mesh->mvert[mface->v2].no[0]/32767.0,
+ mesh->mvert[mface->v2].no[1]/32767.0,
+ mesh->mvert[mface->v2].no[2]/32767.0
+ );
+
+ pt2 = MT_Point3( mesh->mvert[mface->v3].co[0],
+ mesh->mvert[mface->v3].co[1],
+ mesh->mvert[mface->v3].co[2]);
+
+ no2 = MT_Vector3(
+ mesh->mvert[mface->v3].no[0]/32767.0,
+ mesh->mvert[mface->v3].no[1]/32767.0,
+ mesh->mvert[mface->v3].no[2]/32767.0
+ );
+
+ if (mface->v4)
+ {
+ pt3 = MT_Point3( mesh->mvert[mface->v4].co[0],
+ mesh->mvert[mface->v4].co[1],
+ mesh->mvert[mface->v4].co[2]);
+ no3 = MT_Vector3(
+ mesh->mvert[mface->v4].no[0]/32767.0,
+ mesh->mvert[mface->v4].no[1]/32767.0,
+ mesh->mvert[mface->v4].no[2]/32767.0
+ );
+ }
+
+
+
+ if((!mface->flag & ME_SMOOTH))
+ {
+ MT_Vector3 norm = ((pt1-pt0).cross(pt2-pt0)).safe_normalized();
+ norm[0] = ((int) (10*norm[0]))/10.0;
+ norm[1] = ((int) (10*norm[1]))/10.0;
+ norm[2] = ((int) (10*norm[2]))/10.0;
+ no0=no1=no2=no3= norm;
+
+ }
+
+ {
+ Image* bima = ((mesh->tface && tface) ? (Image*) tface->tpage : NULL);
+
+ STR_String imastr =
+ ((mesh->tface && tface) ?
+ (bima? (bima)->id.name : "" ) : "" );
+
+ char transp=0;
+ short mode=0, tile=0;
+ int tilexrep=4,tileyrep = 4;
+
+ if (bima)
+ {
+ tilexrep = bima->xrep;
+ tileyrep = bima->yrep;
+
+ }
+
+
+ bool polyvisible = true;
+ if (mesh->tface && tface)
+ {
+ // Use texface colors if available
+ //TF_DYNAMIC means the polygon is a collision face
+ collider = (tface->mode & TF_DYNAMIC != 0);
+ transp = tface->transp;
+ tile = tface->tile;
+ mode = tface->mode;
+
+ polyvisible = !((tface->flag & TF_HIDE)||(tface->mode & TF_INVISIBLE));
+
+ uv0 = MT_Point2(tface->uv[0]);
+ uv1 = MT_Point2(tface->uv[1]);
+ uv2 = MT_Point2(tface->uv[2]);
+ rgb0 = KX_rgbaint2uint_new(tface->col[0]);
+ rgb1 = KX_rgbaint2uint_new(tface->col[1]);
+ rgb2 = KX_rgbaint2uint_new(tface->col[2]);
+
+ if (mface->v4)
+ {
+ uv3 = MT_Point2(tface->uv[3]);
+ rgb3 = KX_rgbaint2uint_new(tface->col[3]);
+ } else {
+ }
+
+
+ } else
+ {
+ //
+ if (mmcol)
+ {
+ // Use vertex colours
+ rgb0 = KX_Mcol2uint_new(mmcol[0]);
+ rgb1 = KX_Mcol2uint_new(mmcol[1]);
+ rgb2 = KX_Mcol2uint_new(mmcol[2]);
+
+
+ if (mface->v4)
+ {
+ rgb3 = KX_Mcol2uint_new(mmcol[3]);
+
+ }
+
+ mmcol += 4;
+ }
+ else{
+ // If there are no vertex colors OR texfaces,
+ // Initialize face to white and set COLLSION true and everything else FALSE
+ rgb0 = KX_rgbaint2uint_new(0xFFFFFFFF);
+ rgb1 = KX_rgbaint2uint_new(0xFFFFFFFF);
+ rgb2 = KX_rgbaint2uint_new(0xFFFFFFFF);
+
+ if (mface->v4)
+ rgb3 = KX_rgbaint2uint_new(0xFFFFFFFF);
+
+ mode = TF_DYNAMIC;
+ transp = TF_SOLID;
+ tile = 0;
+ }
+ }
+
+
+ Material* ma = give_current_material(blenderobj, 1);
+ const char* matnameptr = (ma ? ma->id.name : "");
+
+
+ bool istriangle = (mface->v4==0);
+
+ RAS_IPolyMaterial* polymat = rendertools->CreateBlenderPolyMaterial(imastr,false,matnameptr,tile,tilexrep,tileyrep,mode,transp, lightlayer,istriangle,blenderobj,tface);
+
+ if (ma)
+ {
+ polymat->m_specular = MT_Vector3(ma->spec * ma->specr,ma->spec * ma->specg,ma->spec * ma->specb);
+ polymat->m_shininess = (float)ma->har;
+
+ } else
+ {
+ polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
+ polymat->m_shininess = 35.0;
+ }
+
+
+ // this is needed to free up memory afterwards
+ converter->RegisterPolyMaterial(polymat);
+
+ RAS_MaterialBucket* bucket = scene->FindBucket(polymat);
+
+ int nverts = mface->v4?4:3;
+ int vtxarray = meshobj->FindVertexArray(nverts,polymat);
+ RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
+ if (skinMesh) {
+ int d1, d2, d3, d4;
+ bool flat;
+
+ /* If the face is set to solid, all fnors are the same */
+ if (mface->flag & ME_SMOOTH)
+ flat = false;
+ else
+ flat = true;
+
+ d1=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v1, &mesh->dvert[mface->v1], polymat);
+ d2=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v2, &mesh->dvert[mface->v2], polymat);
+ d3=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v3, &mesh->dvert[mface->v3], polymat);
+ if (nverts==4)
+ d4=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v4, &mesh->dvert[mface->v4], polymat);
+ poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,d1,flat, polymat));
+ poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,d2,flat, polymat));
+ poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,d3,flat, polymat));
+ if (nverts==4)
+ poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,d4, flat,polymat));
+ }
+ else
+ {
+ poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,rgb0,no0,polymat,mface->v1));
+ poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,rgb1,no1,polymat,mface->v2));
+ poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,rgb2,no2,polymat,mface->v3));
+ if (nverts==4)
+ poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,rgb3,no3,polymat,mface->v4));
+ }
+ meshobj->AddPolygon(poly);
+ if (poly->IsCollider())
+ {
+ RAS_TriangleIndex idx;
+ idx.m_index[0] = mface->v1;
+ idx.m_index[1] = mface->v2;
+ idx.m_index[2] = mface->v3;
+ idx.m_collider = collider;
+ meshobj->m_triangle_indices.push_back(idx);
+ if (nverts==4)
+ {
+ idx.m_index[0] = mface->v1;
+ idx.m_index[1] = mface->v3;
+ idx.m_index[2] = mface->v4;
+ idx.m_collider = collider;
+ meshobj->m_triangle_indices.push_back(idx);
+ }
+ }
+
+ poly->SetVisibleWireframeEdges(mface->edcode);
+ poly->SetCollider(collider);
+ }
+ }
+ }
+ meshobj->UpdateMaterialList();
+
+ return meshobj;
+}
+
+static PHY_MaterialProps g_materialProps = {
+ 1.0, // restitution
+ 2.0, // friction
+ 0.0, // fh spring constant
+ 0.0, // fh damping
+ 0.0, // fh distance
+ false // sliding material?
+};
+
+
+
+static PHY_MaterialProps *CreateMaterialFromBlenderObject(struct Object* blenderobject,
+ KX_Scene *kxscene)
+{
+ PHY_MaterialProps *materialProps = new PHY_MaterialProps;
+
+ assert(materialProps);
+
+ Material* blendermat = give_current_material(blenderobject, 0);
+
+ if (blendermat)
+ {
+ assert(0.0f <= blendermat->reflect && blendermat->reflect <= 1.0f);
+
+ materialProps->m_restitution = blendermat->reflect;
+ materialProps->m_friction = blendermat->friction;
+ materialProps->m_fh_spring = blendermat->fh;
+ materialProps->m_fh_damping = blendermat->xyfrict;
+ materialProps->m_fh_distance = blendermat->fhdist;
+ materialProps->m_fh_normal = (blendermat->dynamode & MA_FH_NOR) != 0;
+ }
+ else {
+ *materialProps = g_materialProps;
+ }
+
+ return materialProps;
+}
+
+static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blenderobject,
+ KX_Scene *kxscene)
+{
+ PHY_ShapeProps *shapeProps = new PHY_ShapeProps;
+
+ assert(shapeProps);
+
+ shapeProps->m_mass = blenderobject->mass;
+
+// This needs to be fixed in blender. For now, we use:
+
+// in Blender, inertia stands for the size value which is equivalent to
+// the sphere radius
+ shapeProps->m_inertia = blenderobject->formfactor * blenderobject->mass * blenderobject->inertia * blenderobject->inertia;
+
+ assert(0.0f <= blenderobject->damping && blenderobject->damping <= 1.0f);
+ assert(0.0f <= blenderobject->rdamping && blenderobject->rdamping <= 1.0f);
+
+ shapeProps->m_lin_drag = 1.0 - blenderobject->damping;
+ shapeProps->m_ang_drag = 1.0 - blenderobject->rdamping;
+
+ shapeProps->m_friction_scaling[0] = blenderobject->anisotropicFriction[0];
+ shapeProps->m_friction_scaling[1] = blenderobject->anisotropicFriction[1];
+ shapeProps->m_friction_scaling[2] = blenderobject->anisotropicFriction[2];
+ shapeProps->m_do_anisotropic = ((blenderobject->gameflag & OB_ANISOTROPIC_FRICTION) != 0);
+
+ shapeProps->m_do_fh = (blenderobject->gameflag & OB_DO_FH) != 0;
+ shapeProps->m_do_rot_fh = (blenderobject->gameflag & OB_ROT_FH) != 0;
+
+ return shapeProps;
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////
+
+
+
+
+void my_boundbox_mesh(Mesh *me, float *loc, float *size)
+ {
+ MVert *mvert;
+ BoundBox *bb;
+ float min[3], max[3];
+ float mloc[3], msize[3];
+ int a;
+
+ if(me->bb==0) me->bb= (struct BoundBox *)MEM_callocN(sizeof(BoundBox), "boundbox");
+ bb= me->bb;
+
+ INIT_MINMAX(min, max);
+
+ if (!loc) loc= mloc;
+ if (!size) size= msize;
+
+ mvert= me->mvert;
+ for(a=0; a<me->totvert; a++, mvert++) {
+ DO_MINMAX(mvert->co, min, max);
+ }
+
+ if(me->totvert) {
+ loc[0]= (min[0]+max[0])/2.0;
+ loc[1]= (min[1]+max[1])/2.0;
+ loc[2]= (min[2]+max[2])/2.0;
+
+ size[0]= (max[0]-min[0])/2.0;
+ size[1]= (max[1]-min[1])/2.0;
+ size[2]= (max[2]-min[2])/2.0;
+ }
+ else {
+ loc[0]= loc[1]= loc[2]= 0.0;
+ size[0]= size[1]= size[2]= 0.0;
+ }
+
+ bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0];
+ bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0];
+
+ bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1];
+ bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1];
+
+ bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2];
+ bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2];
+ }
+
+
+
+
+void my_tex_space_mesh(Mesh *me)
+ {
+ KeyBlock *kb;
+ float *fp, loc[3], size[3], min[3], max[3];
+ int a;
+
+ my_boundbox_mesh(me, loc, size);
+
+ if(me->texflag & AUTOSPACE) {
+ if(me->key) {
+ kb= me->key->refkey;
+ if (kb) {
+
+ INIT_MINMAX(min, max);
+
+ fp= (float *)kb->data;
+ for(a=0; a<kb->totelem; a++, fp+=3) {
+ DO_MINMAX(fp, min, max);
+ }
+ if(kb->totelem) {
+ loc[0]= (min[0]+max[0])/2.0; loc[1]= (min[1]+max[1])/2.0; loc[2]= (min[2]+max[2])/2.0;
+ size[0]= (max[0]-min[0])/2.0; size[1]= (max[1]-min[1])/2.0; size[2]= (max[2]-min[2])/2.0;
+ }
+ else {
+ loc[0]= loc[1]= loc[2]= 0.0;
+ size[0]= size[1]= size[2]= 0.0;
+ }
+
+ }
+ }
+
+ VECCOPY(me->loc, loc);
+ VECCOPY(me->size, size);
+ me->rot[0]= me->rot[1]= me->rot[2]= 0.0;
+
+ if(me->size[0]==0.0) me->size[0]= 1.0;
+ else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001;
+ else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001;
+
+ if(me->size[1]==0.0) me->size[1]= 1.0;
+ else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001;
+ else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001;
+
+ if(me->size[2]==0.0) me->size[2]= 1.0;
+ else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001;
+ else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001;
+ }
+
+}
+
+void my_get_local_bounds(Object *ob, float *centre, float *size)
+ {
+ BoundBox *bb= NULL;
+ /* uses boundbox, function used by Ketsji */
+
+ if(ob->type==OB_MESH) {
+ bb= ( (Mesh *)ob->data )->bb;
+ if(bb==0) {
+ my_tex_space_mesh((struct Mesh *)ob->data);
+ bb= ( (Mesh *)ob->data )->bb;
+ }
+ }
+ else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
+ centre[0]= centre[1]= centre[2]= 0.0;
+ size[0] = size[1]=size[2]=0.0;
+ }
+ else if(ob->type==OB_MBALL) {
+ bb= ob->bb;
+ }
+ if(bb==NULL) {
+ centre[0]= centre[1]= centre[2]= 0.0;
+ size[0] = size[1]=size[2]=0.0;
+ }
+ else {
+ size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
+ size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
+ size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
+
+ centre[0]= (bb->vec[0][0] + bb->vec[4][0])/2.0;
+ centre[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0;
+ centre[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0;
+ }
+}
+
+
+
+
+//////////////////////////////////////////////////////
+
+
+
+
+
+void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
+ struct Object* blenderobject,
+ RAS_MeshObject* meshobj,
+ KX_Scene* kxscene,
+ int activeLayerBitInfo,
+ e_PhysicsEngine physics_engine,
+ KX_BlenderSceneConverter *converter
+ )
+
+ {
+
+
+ SYS_SystemHandle syshandle = SYS_GetSystem();
+ //int userigidbody = SYS_GetCommandLineInt(syshandle,"norigidbody",0);
+ //bool bRigidBody = (userigidbody == 0);
+
+ PHY_ShapeProps* shapeprops =
+ CreateShapePropsFromBlenderObject(blenderobject,
+ kxscene);
+
+
+ PHY_MaterialProps* smmaterial =
+ CreateMaterialFromBlenderObject(blenderobject, kxscene);
+
+ KX_ObjectProperties objprop;
+ objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
+ //mmm, for now, taks this for the size of the dynamicobject
+ // Blender uses inertia for radius of dynamic object
+ objprop.m_radius = blenderobject->inertia;
+ objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
+ objprop.m_in_active_layer = (blenderobject->lay & activeLayerBitInfo) != 0;
+ objprop.m_ghost = (blenderobject->gameflag & OB_GHOST) != 0;
+ objprop.m_dynamic_parent=NULL;
+ objprop.m_isdeformable = ((blenderobject->gameflag2 & 2)) != 0;
+ objprop.m_implicitsphere = false;
+ objprop.m_implicitbox = false;
+
+ if (blenderobject->dtx & OB_BOUNDBOX)
+ {
+ objprop.m_implicitsphere = (blenderobject->boundtype == OB_BOUND_SPHERE);
+ objprop.m_implicitbox = (blenderobject->boundtype == OB_BOUND_BOX);
+ }
+
+ // get Root Parent of blenderobject
+ struct Object* parent= blenderobject->parent;
+ while(parent && parent->parent) {
+ parent= parent->parent;
+ }
+
+ if (parent && (parent->gameflag & OB_DYNAMIC)) {
+
+ KX_GameObject *parentgameobject = converter->FindGameObject(parent);
+ objprop.m_dynamic_parent = parentgameobject;
+
+ }
+
+ objprop.m_isactor = (blenderobject->gameflag & OB_ACTOR)!=0;
+ objprop.m_concave = (blenderobject->boundtype & 4) != 0;
+
+
+ my_get_local_bounds(blenderobject,objprop.m_boundingbox.m_center,objprop.m_boundingbox.m_extends);
+ //mmm, has to be divided by 2 to be proper extends
+ objprop.m_boundingbox.m_extends[0]*=2.f;
+ objprop.m_boundingbox.m_extends[1]*=2.f;
+ objprop.m_boundingbox.m_extends[2]*=2.f;
+
+ switch (physics_engine)
+ {
+ case UseSumo:
+ {
+
+#ifdef USE_SUMO_SOLID
+ KX_ConvertSumoObject( gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
+#endif
+ break;
+ }
+ case UseODE:
+ {
+
+#ifdef USE_ODE
+ KX_ConvertODEEngineObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
+#endif //USE_ODE
+
+
+ break;
+ }
+ case UseDynamo:
+ {
+ //KX_ConvertDynamoObject(gameobj,meshobj,kxscene,shapeprops, smmaterial, &objprop);
+ break;
+ }
+ case UseNone:
+ default:
+ {
+ }
+
+}
+
+}
+
+
+
+
+
+static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
+ RAS_LightObject lightobj;
+ KX_LightObject *gamelight;
+
+ lightobj.m_att1 = la->att1;
+ lightobj.m_red = la->r;
+ lightobj.m_green = la->g;
+ lightobj.m_blue = la->b;
+ lightobj.m_distance = la->dist;
+ lightobj.m_energy = la->energy;
+ lightobj.m_layer = layerflag;
+ lightobj.m_spotblend = la->spotblend;
+ lightobj.m_spotsize = la->spotsize;
+
+ if (la->type==LA_SUN) {
+ lightobj.m_type = RAS_LightObject::LIGHT_SUN;
+ } else if (la->type==LA_SPOT) {
+ lightobj.m_type = RAS_LightObject::LIGHT_SPOT;
+ } else {
+ lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
+ }
+
+ gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj);
+ BL_ConvertLampIpos(la, gamelight, converter);
+
+ return gamelight;
+}
+
+static KX_Camera *gamecamera_from_bcamera(Camera *ca, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
+ RAS_CameraData camdata;
+ KX_Camera *gamecamera;
+
+ camdata.m_lens= ca->lens;
+ camdata.m_clipend= ca->clipend;
+ camdata.m_clipstart= ca->clipsta;
+
+ gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
+ gamecamera->SetName(ca->id.name + 2);
+
+ BL_ConvertCameraIpos(ca, gamecamera, converter);
+
+ return gamecamera;
+}
+
+static KX_GameObject *gameobject_from_blenderobject(
+ Object *ob,
+ KX_Scene *kxscene,
+ RAS_IRenderTools *rendertools,
+ KX_BlenderSceneConverter *converter,
+ Scene *blenderscene)
+{
+ KX_GameObject *gameobj = NULL;
+
+ switch(ob->type)
+ {
+ case OB_LAMP:
+ {
+ KX_LightObject* gamelight= gamelight_from_blamp(static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
+ gameobj = gamelight;
+
+ gamelight->AddRef();
+ kxscene->GetLightList()->Add(gamelight);
+
+ break;
+ }
+
+ case OB_CAMERA:
+ {
+ KX_Camera* gamecamera = gamecamera_from_bcamera(static_cast<Camera*>(ob->data), kxscene, converter);
+ gameobj = gamecamera;
+
+ gamecamera->AddRef();
+ kxscene->AddCamera(gamecamera);
+
+ break;
+ }
+
+ case OB_MESH:
+ {
+ Mesh* mesh = static_cast<Mesh*>(ob->data);
+ RAS_MeshObject* meshobj = converter->FindGameMesh(mesh, ob->lay);
+
+ if (!meshobj) {
+ meshobj = BL_ConvertMesh(mesh,ob,rendertools,kxscene,converter);
+ converter->RegisterGameMesh(meshobj, mesh);
+ }
+
+ // needed for python scripting
+ kxscene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
+
+ gameobj = new BL_DeformableGameObject(kxscene,KX_Scene::m_callbacks);
+
+ // set transformation
+ gameobj->AddMesh(meshobj);
+
+ // for all objects: check whether they want to
+ // respond to updates
+ bool ignoreActivityCulling =
+ ((ob->gameflag2 & OB_NEVER_DO_ACTIVITY_CULLING)!=0);
+ gameobj->SetIgnoreActivityCulling(ignoreActivityCulling);
+
+ // If this is a skin object, make Skin Controller
+ if (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && ((Mesh*)ob->data)->dvert){
+ BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj);
+ ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
+ }
+ else if (((Mesh*)ob->data)->dvert){
+ BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj);
+ ((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
+ }
+
+ break;
+ }
+
+ case OB_ARMATURE:
+ {
+ gameobj = new BL_ArmatureObject (kxscene, KX_Scene::m_callbacks,
+ (bArmature*)ob->data,
+ ob->pose);
+
+ /* Get the current pose from the armature object and apply it as the rest pose */
+ break;
+ }
+
+ case OB_EMPTY:
+ {
+ gameobj = new KX_EmptyObject(kxscene,KX_Scene::m_callbacks);
+ // set transformation
+ break;
+ }
+ }
+
+ return gameobj;
+}
+
+struct parentChildLink {
+ struct Object* m_blenderchild;
+ SG_Node* m_gamechildnode;
+};
+
+ /**
+ * Find the specified scene by name, or the first
+ * scene if nothing matches (shouldn't happen).
+ */
+static struct Scene *GetSceneForName(struct Main *maggie, const STR_String& scenename) {
+ Scene *sce;
+
+ for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
+ if (scenename == (sce->id.name+2))
+ return sce;
+
+ return (Scene*) maggie->scene.first;
+}
+
+// convert blender objects into ketsji gameobjects
+void BL_ConvertBlenderObjects(struct Main* maggie,
+ const STR_String& scenename,
+ KX_Scene* kxscene,
+ KX_KetsjiEngine* ketsjiEngine,
+ e_PhysicsEngine physics_engine,
+ PyObject* pythondictionary,
+ SCA_IInputDevice* keydev,
+ RAS_IRenderTools* rendertools,
+ RAS_ICanvas* canvas,
+ KX_BlenderSceneConverter* converter,
+ bool alwaysUseExpandFraming
+ )
+{
+ Scene *blenderscene = GetSceneForName(maggie, scenename);
+
+ // Get the frame settings of the canvas.
+ // Get the aspect ratio of the canvas as designed by the user.
+
+ RAS_FrameSettings::RAS_FrameType frame_type;
+ int aspect_width;
+ int aspect_height;
+
+ if (alwaysUseExpandFraming) {
+ frame_type = RAS_FrameSettings::e_frame_extend;
+ aspect_width = canvas->GetWidth();
+ aspect_height = canvas->GetHeight();
+ } else {
+ if (blenderscene->framing.type == SCE_GAMEFRAMING_BARS) {
+ frame_type = RAS_FrameSettings::e_frame_bars;
+ } else if (blenderscene->framing.type == SCE_GAMEFRAMING_EXTEND) {
+ frame_type = RAS_FrameSettings::e_frame_extend;
+ } else {
+ frame_type = RAS_FrameSettings::e_frame_scale;
+ }
+
+ aspect_width = blenderscene->r.xsch;
+ aspect_height = blenderscene->r.ysch;
+ }
+
+ RAS_FrameSettings frame_settings(
+ frame_type,
+ blenderscene->framing.col[0],
+ blenderscene->framing.col[1],
+ blenderscene->framing.col[2],
+ aspect_width,
+ aspect_height
+ );
+ kxscene->SetFramingType(frame_settings);
+
+ kxscene->SetGravity(MT_Vector3(0,0,(blenderscene->world != NULL) ? -blenderscene->world->gravity : -9.8));
+
+ /* set activity culling parameters */
+ if (blenderscene->world) {
+ kxscene->SetActivityCulling( (blenderscene->world->mode & WO_ACTIVITY_CULLING) != 0);
+ kxscene->SetActivityCullingRadius(blenderscene->world->activityBoxRadius);
+ } else {
+ kxscene->SetActivityCulling(false);
+ }
+
+ int activeLayerBitInfo = blenderscene->lay;
+
+ // templist to find Root Parents (object with no parents)
+ CListValue* templist = new CListValue();
+ CListValue* sumolist = new CListValue();
+
+ vector<parentChildLink> vec_parent_child;
+
+ CListValue* objectlist = kxscene->GetObjectList();
+ CListValue* parentlist = kxscene->GetRootParentList();
+
+ SCA_LogicManager* logicmgr = kxscene->GetLogicManager();
+ SCA_TimeEventManager* timemgr = kxscene->GetTimeEventManager();
+
+ CListValue* logicbrick_conversionlist = new CListValue();
+
+ // Convert actions to actionmap
+ bAction *curAct;
+ for (curAct = (bAction*)maggie->action.first; curAct; curAct=(bAction*)curAct->id.next)
+ {
+ logicmgr->RegisterActionName(curAct->id.name, curAct);
+ }
+
+ Base *base = static_cast<Base*>(blenderscene->base.first);
+ while(base)
+ {
+ Object* blenderobject = base->object;
+ KX_GameObject* gameobj = gameobject_from_blenderobject(
+ base->object,
+ kxscene,
+ rendertools,
+ converter,
+ blenderscene);
+
+ if (gameobj)
+ {
+ MT_Point3 pos = MT_Point3(
+ blenderobject->loc[0]+blenderobject->dloc[0],
+ blenderobject->loc[1]+blenderobject->dloc[1],
+ blenderobject->loc[2]+blenderobject->dloc[2]
+ );
+ MT_Vector3 eulxyz = MT_Vector3(
+ blenderobject->rot[0],
+ blenderobject->rot[1],
+ blenderobject->rot[2]
+ );
+ MT_Vector3 scale = MT_Vector3(
+ blenderobject->size[0],
+ blenderobject->size[1],
+ blenderobject->size[2]
+ );
+
+ gameobj->NodeSetLocalPosition(pos);
+ gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
+ gameobj->NodeSetLocalScale(scale);
+ gameobj->NodeUpdateGS(0,true);
+
+ BL_ConvertIpos(blenderobject,gameobj,converter);
+
+ bool isInActiveLayer = (blenderobject->lay & activeLayerBitInfo) !=0;
+
+ sumolist->Add(gameobj->AddRef());
+
+ BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
+
+
+ gameobj->SetName(blenderobject->id.name);
+
+ // templist to find Root Parents (object with no parents)
+ templist->Add(gameobj->AddRef());
+
+ // update children/parent hierarchy
+ if (blenderobject->parent != 0)
+ {
+ // blender has an additional 'parentinverse' offset in each object
+ SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
+
+ // define a normal parent relationship for this node.
+ KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
+ parentinversenode->SetParentRelation(parent_relation);
+
+ parentChildLink pclink;
+ pclink.m_blenderchild = blenderobject;
+ pclink.m_gamechildnode = parentinversenode;
+ vec_parent_child.push_back(pclink);
+
+ float* fl = (float*) blenderobject->parentinv;
+ MT_Transform parinvtrans(fl);
+ parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
+ parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
+ parentinversenode->AddChild(gameobj->GetSGNode());
+ }
+
+ // needed for python scripting
+ logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
+
+ converter->RegisterGameObject(gameobj, blenderobject);
+
+ // this was put in rapidly, needs to be looked at more closely
+ // only draw/use objects in active 'blender' layers
+
+ logicbrick_conversionlist->Add(gameobj->AddRef());
+
+ if (isInActiveLayer)
+ {
+ objectlist->Add(gameobj->AddRef());
+
+ gameobj->NodeUpdateGS(0,true);
+ gameobj->Bucketize();
+
+ }
+ }
+
+ base = base->next;
+ }
+
+ if (blenderscene->camera) {
+ KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
+
+ kxscene->SetActiveCamera(gamecamera);
+ }
+
+ // Set up armatures
+ for (base = static_cast<Base*>(blenderscene->base.first); base; base=base->next){
+ if (base->object->type==OB_MESH){
+ Mesh *me = (Mesh*)base->object->data;
+
+ if (me->dvert){
+ KX_GameObject *obj = converter->FindGameObject(base->object);
+
+ if (base->object->parent && base->object->parent->type==OB_ARMATURE && base->object->partype==PARSKEL){
+ KX_GameObject *par = converter->FindGameObject(base->object->parent);
+ if (par)
+ ((BL_SkinDeformer*)(((BL_DeformableGameObject*)obj)->m_pDeformer))->SetArmature((BL_ArmatureObject*) par);
+ }
+ }
+ }
+ }
+
+ // create hierarchy information
+ int i;
+ vector<parentChildLink>::iterator pcit;
+
+ for (pcit = vec_parent_child.begin();!(pcit==vec_parent_child.end());++pcit)
+ {
+
+ struct Object* blenderchild = pcit->m_blenderchild;
+ if (blenderchild->partype == PARVERT1)
+ {
+ // creat a new vertex parent relationship for this node.
+ KX_VertexParentRelation * vertex_parent_relation = KX_VertexParentRelation::New();
+ pcit->m_gamechildnode->SetParentRelation(vertex_parent_relation);
+ } else
+ if (blenderchild->partype == PARSLOW)
+ {
+ // creat a new slow parent relationship for this node.
+ KX_SlowParentRelation * slow_parent_relation = KX_SlowParentRelation::New(blenderchild->sf);
+ pcit->m_gamechildnode->SetParentRelation(slow_parent_relation);
+ }
+
+ struct Object* blenderparent = blenderchild->parent;
+ KX_GameObject* parentobj = converter->FindGameObject(blenderparent);
+ if (parentobj)
+ {
+ parentobj-> GetSGNode()->AddChild(pcit->m_gamechildnode);
+ }
+ }
+ vec_parent_child.clear();
+
+ // find 'root' parents (object that has not parents in SceneGraph)
+ for (i=0;i<templist->GetCount();++i)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) templist->GetValue(i);
+ if (gameobj->GetSGNode()->GetSGParent() == 0)
+ {
+ parentlist->Add(gameobj->AddRef());
+ gameobj->NodeUpdateGS(0,true);
+ }
+ }
+
+ // create physics information
+ for (i=0;i<sumolist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) sumolist->GetValue(i);
+ struct Object* blenderobject = converter->FindBlenderObject(gameobj);
+ int nummeshes = gameobj->GetMeshCount();
+ RAS_MeshObject* meshobj = 0;
+
+ if (nummeshes > 0)
+ {
+ meshobj = gameobj->GetMesh(0);
+ }
+
+ BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter);
+
+ }
+
+ templist->Release();
+ sumolist->Release();
+
+
+ int executePriority=0; /* incremented by converter routines */
+
+ // convert global sound stuff
+
+ /* XXX, glob is the very very wrong place for this
+ * to be, re-enable once the listener has been moved into
+ * the scene. */
+#if 0
+ SND_Scene* soundscene = kxscene->GetSoundScene();
+ SND_SoundListener* listener = soundscene->GetListener();
+ if (listener && glob->listener)
+ {
+ listener->SetDopplerFactor(glob->listener->dopplerfactor);
+ listener->SetDopplerVelocity(glob->listener->dopplervelocity);
+ listener->SetGain(glob->listener->gain);
+ }
+#endif
+
+ // convert world
+ KX_WorldInfo* worldinfo = new BlenderWorldInfo(blenderscene->world);
+ converter->RegisterWorldInfo(worldinfo);
+ kxscene->SetWorldInfo(worldinfo);
+
+ // convert logic bricks, sensors, controllers and actuators
+ for (i=0;i<logicbrick_conversionlist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
+ struct Object* blenderobj = converter->FindBlenderObject(gameobj);
+ bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
+ BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, activeLayerBitInfo,isInActiveLayer,rendertools,converter);
+ }
+ for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
+ struct Object* blenderobj = converter->FindBlenderObject(gameobj);
+ bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
+ BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,activeLayerBitInfo,isInActiveLayer,converter);
+ }
+ for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
+ struct Object* blenderobj = converter->FindBlenderObject(gameobj);
+ bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
+ BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter);
+ }
+ logicbrick_conversionlist->Release();
+}
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.h b/source/gameengine/Converter/BL_BlenderDataConversion.h
new file mode 100644
index 00000000000..1ed6a866269
--- /dev/null
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.h
@@ -0,0 +1,54 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __BLENDER_CONVERT
+#define __BLENDER_CONVERT
+
+#include "STR_String.h"
+#include "KX_Python.h"
+#include "KX_PhysicsEngineEnums.h"
+
+class RAS_MeshObject* BL_ConvertMesh(struct Mesh* mesh,struct Object* lightobj,class RAS_IRenderTools* rendertools,class KX_Scene* scene, class KX_BlenderSceneConverter *converter);
+
+void BL_ConvertBlenderObjects(struct Main* maggie,
+ const STR_String& scenename,
+ class KX_Scene* kxscene,
+ class KX_KetsjiEngine* ketsjiEngine,
+ e_PhysicsEngine physics_engine,
+ PyObject* pythondictionary,
+ class SCA_IInputDevice* keydev,
+ class RAS_IRenderTools* rendertools,
+ class RAS_ICanvas* canvas,
+ class KX_BlenderSceneConverter* sceneconverter,
+ bool alwaysUseExpandFraming
+ );
+
+#endif // __BLENDER_CONVERT
diff --git a/source/gameengine/Converter/BL_DeformableGameObject.cpp b/source/gameengine/Converter/BL_DeformableGameObject.cpp
new file mode 100644
index 00000000000..d6830380b00
--- /dev/null
+++ b/source/gameengine/Converter/BL_DeformableGameObject.cpp
@@ -0,0 +1,62 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "BL_DeformableGameObject.h"
+
+BL_DeformableGameObject::~BL_DeformableGameObject()
+{
+ if (m_pDeformer)
+ delete m_pDeformer; // __NLA : Temporary until we decide where to put this
+}
+
+void BL_DeformableGameObject::ProcessReplica(KX_GameObject* replica)
+{
+ KX_GameObject::ProcessReplica(replica);
+
+ if (m_pDeformer){
+ ((BL_DeformableGameObject*)replica)->m_pDeformer = m_pDeformer->GetReplica();
+ }
+
+}
+
+CValue* BL_DeformableGameObject::GetReplica()
+{
+
+ BL_DeformableGameObject* replica = new BL_DeformableGameObject(*this);//m_float,GetName());
+
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+
+ ProcessReplica(replica);
+ return replica;
+
+}
diff --git a/source/gameengine/Converter/BL_DeformableGameObject.h b/source/gameengine/Converter/BL_DeformableGameObject.h
new file mode 100644
index 00000000000..1f05d2fcbcc
--- /dev/null
+++ b/source/gameengine/Converter/BL_DeformableGameObject.h
@@ -0,0 +1,66 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BL_DEFORMABLEGAMEOBJECT
+#define BL_DEFORMABLEGAMEOBJECT
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+#include "KX_GameObject.h"
+#include "RAS_Deformer.h"
+
+class BL_DeformableGameObject : public KX_GameObject
+{
+public:
+
+ RAS_Deformer *m_pDeformer;
+ CValue* GetReplica();
+ virtual void Relink(GEN_Map<GEN_HashedPtr, void*>*map)
+ {
+ if (m_pDeformer)
+ m_pDeformer->Relink (map);
+ };
+ void ProcessReplica(KX_GameObject* replica);
+
+ BL_DeformableGameObject(void* sgReplicationInfo, SG_Callbacks callbacks) :
+ KX_GameObject(sgReplicationInfo,callbacks),
+ m_pDeformer(NULL)
+{
+ };
+ virtual ~BL_DeformableGameObject();
+
+};
+
+#endif
+
diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp
new file mode 100644
index 00000000000..3aa4287478d
--- /dev/null
+++ b/source/gameengine/Converter/BL_MeshDeformer.cpp
@@ -0,0 +1,165 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Simple deformation controller that restores a mesh to its rest position
+ */
+
+#ifdef WIN32
+// This warning tells us about truncation of __long__ stl-generated names.
+// It can occasionally cause DevStudio to have internal compiler warnings.
+#pragma warning( disable : 4786 )
+#endif
+
+#include "RAS_IPolygonMaterial.h"
+#include "BL_MeshDeformer.h"
+#include "BL_SkinMeshObject.h"
+#include "DNA_mesh_types.h"
+#include "BLI_arithb.h"
+
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+
+
+bool BL_MeshDeformer::Apply(RAS_IPolyMaterial *mat)
+{
+ int i, j, index;
+ vecVertexArray array;
+ vecIndexArrays mvarray;
+ vecIndexArrays diarray;
+ float co[3];
+
+ RAS_TexVert *tv;
+ MVert *mvert;
+
+ // For each material
+ array = m_pMeshObject->GetVertexCache(mat);
+ mvarray = m_pMeshObject->GetMVertCache(mat);
+ diarray = m_pMeshObject->GetDIndexCache(mat);
+
+ // For each array
+ for (i=0; i<array.size(); i++){
+ // For each vertex
+ for (j=0; j<array[i]->size(); j++){
+ tv = &((*array[i])[j]);
+ MT_Point3 pt = tv->xyz();
+
+ index = ((*diarray[i])[j]);
+
+ mvert = &(m_bmesh->mvert[((*mvarray[i])[index])]);
+ // Do the nasty (in this case, copy the untransformed data from the blender mesh)
+ co[0]=mvert->co[0];
+ co[1]=mvert->co[1];
+ co[2]=mvert->co[2];
+
+ pt[0] = co[0];
+ pt[1] = co[1];
+ pt[2] = co[2];
+
+ tv->SetXYZ(pt);
+ }
+ }
+ return true;
+}
+
+BL_MeshDeformer::~BL_MeshDeformer()
+{
+ if (m_transverts)
+ delete []m_transverts;
+ if (m_transnors)
+ delete []m_transnors;
+};
+
+void BL_MeshDeformer::RecalcNormals()
+{
+ int v, f;
+ float fnor[3], co1[3], co2[3], co3[3], co4[3];
+
+ /* Clear all vertex normal accumulators */
+ for (v =0; v<m_bmesh->totvert; v++){
+ m_transnors[v]=MT_Point3(0,0,0);
+ }
+
+ /* Find the face normals */
+ for (f = 0; f<m_bmesh->totface; f++){
+ // Make new face normal based on the transverts
+ MFace *mf= &((MFace*)m_bmesh->mface)[f];
+
+ if (mf->v3) {
+ for (int vl=0; vl<3; vl++){
+ co1[vl]=m_transverts[mf->v1][vl];
+ co2[vl]=m_transverts[mf->v2][vl];
+ co3[vl]=m_transverts[mf->v3][vl];
+ if (mf->v4)
+ co4[vl]=m_transverts[mf->v4][vl];
+ }
+
+ /* FIXME: Use moto */
+ if (mf->v4)
+ CalcNormFloat4(co1, co2, co3, co4, fnor);
+ else
+ CalcNormFloat(co1, co2, co3, fnor);
+
+ /* Decide which normals are affected by this face's normal */
+ m_transnors[mf->v1]+=MT_Point3(fnor);
+ m_transnors[mf->v2]+=MT_Point3(fnor);
+ m_transnors[mf->v3]+=MT_Point3(fnor);
+ if (mf->v4)
+ m_transnors[mf->v4]+=MT_Point3(fnor);
+
+ }
+
+ }
+
+ for (v =0; v<m_bmesh->totvert; v++){
+ float nor[3];
+
+ m_transnors[v]=m_transnors[v].safe_normalized();
+ nor[0]=m_transnors[v][0];
+ nor[1]=m_transnors[v][1];
+ nor[2]=m_transnors[v][2];
+
+ };
+}
+
+void BL_MeshDeformer::VerifyStorage()
+{
+ /* Ensure that we have the right number of verts assigned */
+ if (m_tvtot!=m_bmesh->totvert+m_bmesh->totface){
+ if (m_transverts)
+ delete []m_transverts;
+ if (m_transnors)
+ delete []m_transnors;
+
+ m_transnors =new MT_Point3[m_bmesh->totvert+m_bmesh->totface];
+ m_transverts=new MT_Point3[m_bmesh->totvert];
+ m_tvtot = m_bmesh->totvert;
+ }
+}
+ \ No newline at end of file
diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h
new file mode 100644
index 00000000000..9880725a2d0
--- /dev/null
+++ b/source/gameengine/Converter/BL_MeshDeformer.h
@@ -0,0 +1,72 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BL_MESHDEFORMER
+#define BL_MESHDEFORMER
+
+#include "RAS_Deformer.h"
+#include "DNA_object_types.h"
+#include "MT_Point3.h"
+#include <stdlib.h>
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+class BL_MeshDeformer : public RAS_Deformer
+{
+public:
+ void VerifyStorage();
+ void RecalcNormals();
+ virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map){};
+ BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj):
+ m_transverts(NULL),
+ m_tvtot(0),
+ m_transnors(NULL),
+ m_pMeshObject(meshobj),
+ m_bmesh((struct Mesh*)(obj->data)){};
+ virtual ~BL_MeshDeformer();
+ virtual void SetSimulatedTime(double time){};
+ virtual bool Apply(class RAS_IPolyMaterial *mat);
+ virtual void Update(void){};
+ virtual RAS_Deformer* GetReplica(){return NULL;};
+ // virtual void InitDeform(double time){};
+protected:
+ class BL_SkinMeshObject *m_pMeshObject;
+ struct Mesh *m_bmesh;
+ MT_Point3 *m_transnors;
+ MT_Point3 *m_transverts;
+ int m_tvtot;
+
+};
+
+#endif
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
new file mode 100644
index 00000000000..4eb2b849c3c
--- /dev/null
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -0,0 +1,187 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#include "GEN_Map.h"
+#include "STR_HashedString.h"
+#include "RAS_IPolygonMaterial.h"
+#include "BL_SkinMeshObject.h"
+
+//#include "BL_ArmatureController.h"
+#include "BL_SkinDeformer.h"
+#include "DNA_armature_types.h"
+#include "DNA_action_types.h"
+#include "DNA_mesh_types.h"
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "MT_Point3.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#define __NLA_DEFNORMALS
+//#undef __NLA_DEFNORMALS
+
+BL_SkinDeformer::~BL_SkinDeformer()
+{
+};
+
+bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
+{
+ int i, j, index;
+ vecVertexArray array;
+#ifdef __NLA_OLDDEFORM
+ vecMVertArray mvarray;
+#else
+ vecIndexArrays mvarray;
+#endif
+ vecMDVertArray dvarray;
+ vecIndexArrays diarray;
+
+ RAS_TexVert *tv;
+#ifdef __NLA_OLDDEFORM
+ MVert *mvert;
+ MDeformVert *dvert;
+#endif
+ MT_Point3 pt;
+// float co[3];
+
+ if (!m_armobj)
+ return false;
+
+ Update();
+
+ array = m_pMeshObject->GetVertexCache(mat);
+#ifdef __NLA_OLDDEFORM
+ dvarray = m_pMeshObject->GetDVertCache(mat);
+#endif
+ mvarray = m_pMeshObject->GetMVertCache(mat);
+ diarray = m_pMeshObject->GetDIndexCache(mat);
+
+
+ // For each array
+ for (i=0; i<array.size(); i++){
+ // For each vertex
+ for (j=0; j<array[i]->size(); j++){
+
+ tv = &((*array[i])[j]);
+
+ index = ((*diarray[i])[j]);
+#ifdef __NLA_OLDDEFORM
+ pt = tv->xyz();
+ mvert = ((*mvarray[i])[index]);
+ dvert = ((*dvarray[i])[index]);
+#endif
+
+ // Copy the untransformed data from the original mvert
+#ifdef __NLA_OLDDEFORM
+ co[0]=mvert->co[0];
+ co[1]=mvert->co[1];
+ co[2]=mvert->co[2];
+
+ // Do the deformation
+ GB_calc_armature_deform(co, dvert);
+ tv->SetXYZ(co);
+#else
+ // Set the data
+ tv->SetXYZ(m_transverts[((*mvarray[i])[index])]);
+#ifdef __NLA_DEFNORMALS
+
+ tv->SetNormal(m_transnors[((*mvarray[i])[index])]);
+#endif
+#endif
+ }
+ }
+
+ return true;
+}
+
+RAS_Deformer *BL_SkinDeformer::GetReplica()
+{
+ BL_SkinDeformer *result;
+
+ result = new BL_SkinDeformer(*this);
+ result->ProcessReplica();
+ return result;
+}
+
+void BL_SkinDeformer::ProcessReplica()
+{
+}
+
+void BL_SkinDeformer::Update(void)
+{
+
+ /* See if the armature has been updated for this frame */
+ if (m_lastUpdate!=m_armobj->GetLastFrame()){
+
+ /* Do all of the posing necessary */
+ GB_init_armature_deform (m_defbase, m_premat, m_postmat);
+ m_armobj->ApplyPose();
+ precalc_armature_posemats (m_armobj->GetArmature());
+ for (Bone *curBone=(Bone*)m_armobj->GetArmature()->bonebase.first; curBone; curBone=(Bone*)curBone->next)
+ precalc_bone_defmat(curBone);
+
+ VerifyStorage();
+
+ /* Transform the verts & store locally */
+ for (int v =0; v<m_bmesh->totvert; v++){
+ float co[3];
+
+ co[0]=m_bmesh->mvert[v].co[0];
+ co[1]=m_bmesh->mvert[v].co[1];
+ co[2]=m_bmesh->mvert[v].co[2];
+ GB_calc_armature_deform(co, &m_bmesh->dvert[v]);
+
+ m_transverts[v]=MT_Point3(co);
+ }
+
+ RecalcNormals();
+
+
+ /* Update the current frame */
+ m_lastUpdate=m_armobj->GetLastFrame();
+ }
+}
+
+void BL_SkinDeformer::SetArmature(BL_ArmatureObject *armobj)
+{
+ m_armobj = armobj;
+
+ for (bDeformGroup *dg=(bDeformGroup*)m_defbase->first; dg; dg=(bDeformGroup*)dg->next)
+ dg->data = (void*)get_named_bone(m_armobj->GetArmature(), dg->name);
+
+ GB_validate_defgroups(m_bmesh, m_defbase);
+}
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
new file mode 100644
index 00000000000..25c3654d269
--- /dev/null
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -0,0 +1,98 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BL_SKINDEFORMER
+#define BL_SKINDEFORMER
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+#include "BL_MeshDeformer.h"
+#include "BL_ArmatureObject.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "BKE_armature.h"
+
+#include "RAS_Deformer.h"
+
+
+class BL_SkinDeformer : public BL_MeshDeformer
+{
+public:
+// void SetArmatureController (BL_ArmatureController *cont);
+ virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
+ {
+ void **h_obj = (*map)[m_armobj];
+ if (h_obj){
+ SetArmature( (BL_ArmatureObject*)(*h_obj) );
+ }
+ else
+ m_armobj=NULL;
+ }
+ void SetArmature (class BL_ArmatureObject *armobj);
+ BL_SkinDeformer( struct Object *bmeshobj,
+ class BL_SkinMeshObject *mesh)
+ :BL_MeshDeformer(bmeshobj, mesh),
+ m_armobj(NULL),
+ m_defbase(&bmeshobj->defbase),
+ m_lastUpdate(-1)
+ {
+ /* Build all precalculatable matrices for bones */
+
+ GB_build_mats(bmeshobj->parent->obmat, bmeshobj->obmat, m_premat, m_postmat);
+ GB_validate_defgroups((Mesh*)bmeshobj->data, m_defbase);
+ // Validate bone data in bDeformGroups
+/*
+ for (bDeformGroup *dg=(bDeformGroup*)m_defbase->first; dg; dg=(bDeformGroup*)dg->next)
+ dg->data = (void*)get_named_bone(barm, dg->name);
+*/
+ };
+
+ virtual void ProcessReplica();
+ virtual RAS_Deformer *GetReplica();
+ virtual ~BL_SkinDeformer();
+ void Update (void);
+ bool Apply (class RAS_IPolyMaterial *polymat);
+
+protected:
+ BL_ArmatureObject *m_armobj; // Our parent object
+ float m_premat[4][4];
+ float m_postmat[4][4];
+ float m_time;
+ double m_lastUpdate;
+ ListBase *m_defbase;
+};
+
+#endif
+
diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp
new file mode 100644
index 00000000000..859b495b9d5
--- /dev/null
+++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp
@@ -0,0 +1,152 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Deformer that supports armature skinning
+ */
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+#include "RAS_IPolygonMaterial.h"
+#include "BL_SkinMeshObject.h"
+#include "BL_DeformableGameObject.h"
+#include "DNA_mesh_types.h"
+#include "KX_GameObject.h"
+#include "RAS_BucketManager.h"
+
+void BL_SkinMeshObject::AddPolygon(RAS_Polygon* poly)
+{
+ /* We're overriding this so that we can eventually associate faces with verts somehow */
+
+ // For vertIndex in poly:
+ // find the appropriate normal
+
+ RAS_MeshObject::AddPolygon(poly);
+}
+
+#ifdef __NLA_OLDDEFORM
+int BL_SkinMeshObject::FindOrAddDeform(int vtxarray, struct MVert *mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat)
+#else
+int BL_SkinMeshObject::FindOrAddDeform(int vtxarray, int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat)
+#endif
+{
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ int numvert = ao->m_MvertArrayCache1[vtxarray]->size();
+
+ /* Check to see if this has already been pushed */
+ for (int i=0; i<ao->m_MvertArrayCache1[vtxarray]->size(); i++){
+ if (mv == (*ao->m_MvertArrayCache1[vtxarray])[i])
+ return i;
+ }
+
+ ao->m_MvertArrayCache1[vtxarray]->push_back(mv);
+ ao->m_DvertArrayCache1[vtxarray]->push_back(dv);
+
+ return numvert;
+};
+
+int BL_SkinMeshObject::FindVertexArray(int numverts,RAS_IPolyMaterial* polymat)
+{
+ int array=-1;
+
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(polymat);
+
+
+ for (int i=0;i<ao->m_VertexArrayCache1.size();i++)
+ {
+ if ( (ao->m_TriangleArrayCount[i] + (numverts-2)) < BUCKET_MAX_TRIANGLES)
+ {
+ if((ao->m_VertexArrayCache1[i]->size()+numverts < BUCKET_MAX_INDICES))
+ {
+ array = i;
+ ao->m_TriangleArrayCount[array]+=numverts-2;
+ break;
+ }
+ }
+ }
+
+
+ if (array == -1)
+ {
+ array = ao->m_VertexArrayCache1.size();
+
+ vector<RAS_TexVert>* va = new vector<RAS_TexVert>;
+ ao->m_VertexArrayCache1.push_back(va);
+
+ KX_IndexArray *ia = new KX_IndexArray();
+ ao->m_IndexArrayCache1.push_back(ia);
+
+#ifdef __NLA_OLDDEFORM
+ BL_MVertArray *bva = new BL_MVertArray();
+#else
+ KX_IndexArray *bva = new KX_IndexArray();
+#endif
+ ao->m_MvertArrayCache1.push_back(bva);
+
+ BL_DeformVertArray *dva = new BL_DeformVertArray();
+ ao->m_DvertArrayCache1.push_back(dva);
+
+ KX_IndexArray *da = new KX_IndexArray();
+ ao->m_DIndexArrayCache1.push_back(da);
+
+ ao->m_TriangleArrayCount.push_back(numverts-2);
+
+ }
+
+
+ return array;
+}
+
+
+//void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,RAS_BucketManager* bucketmgr)
+void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec)
+{
+
+ KX_MeshSlot ms;
+ ms.m_clientObj = clientobj;
+ ms.m_mesh = this;
+ ms.m_OpenGLMatrix = oglmatrix;
+ ms.m_bObjectColor = useObjectColor;
+ ms.m_RGBAcolor = rgbavec;
+ ms.m_pDeformer = ((BL_DeformableGameObject*)clientobj)->m_pDeformer;
+
+ for (BucketMaterialSet::iterator it = m_materials.begin();it!=m_materials.end();it++)
+ {
+
+ RAS_MaterialBucket* materialbucket = (*it);
+
+ KX_ArrayOptimizer* oa = GetArrayOptimizer(materialbucket->GetPolyMaterial());
+ materialbucket->SetMeshSlot(ms);
+ }
+
+}
+
+
+
diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h
new file mode 100644
index 00000000000..5ac95b48a35
--- /dev/null
+++ b/source/gameengine/Converter/BL_SkinMeshObject.h
@@ -0,0 +1,184 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef __BL_SKINMESHOBJECT
+#define __BL_SKINMESHOBJECT
+
+#ifdef WIN32
+#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
+#endif //WIN32
+
+#include "RAS_MeshObject.h"
+#include "RAS_Deformer.h"
+#include "RAS_IPolygonMaterial.h"
+
+#include "BL_MeshDeformer.h"
+
+#include "DNA_mesh_types.h"
+
+typedef vector<struct MVert*> BL_MVertArray;
+typedef vector<struct MDeformVert*> BL_DeformVertArray;
+typedef vector<class BL_TexVert> BL_VertexArray;
+
+
+typedef vector<vector<struct MDeformVert*>*> vecMDVertArray;
+typedef vector<vector<class BL_TexVert>*> vecBVertexArray;
+
+class BL_SkinArrayOptimizer : public KX_ArrayOptimizer
+{
+public:
+ BL_SkinArrayOptimizer(int index)
+ :KX_ArrayOptimizer (index) {};
+ virtual ~BL_SkinArrayOptimizer(){
+
+ for (vector<KX_IndexArray*>::iterator itv = m_MvertArrayCache1.begin();
+ !(itv == m_MvertArrayCache1.end());itv++)
+ {
+ delete (*itv);
+ }
+ for (vector<BL_DeformVertArray*>::iterator itd = m_DvertArrayCache1.begin();
+ !(itd == m_DvertArrayCache1.end());itd++)
+ {
+ delete (*itd);
+ }
+ for (vector<KX_IndexArray*>::iterator iti = m_DIndexArrayCache1.begin();
+ !(iti == m_DIndexArrayCache1.end());iti++)
+ {
+ delete (*iti);
+ }
+
+ m_MvertArrayCache1.clear();
+ m_DvertArrayCache1.clear();
+ m_DIndexArrayCache1.clear();
+ };
+
+ vector<KX_IndexArray*> m_MvertArrayCache1;
+ vector<BL_DeformVertArray*> m_DvertArrayCache1;
+ vector<KX_IndexArray*> m_DIndexArrayCache1;
+
+};
+
+class BL_SkinMeshObject : public RAS_MeshObject
+{
+
+ enum { BUCKET_MAX_INDICES = 2048};//2048};//8192};
+ enum { BUCKET_MAX_TRIANGLES = 1024};
+
+ KX_ArrayOptimizer* GetArrayOptimizer(RAS_IPolyMaterial* polymat)
+ {
+ KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]);
+ if (aop)
+ return *aop;
+ int numelements = m_matVertexArrayS.size();
+ m_sortedMaterials.push_back(polymat);
+
+ BL_SkinArrayOptimizer* ao = new BL_SkinArrayOptimizer(numelements);
+ m_matVertexArrayS.insert(*polymat,ao);
+ return ao;
+ }
+
+protected:
+public:
+ void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec);
+// void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,class RAS_BucketManager* bucketmgr);
+
+ int FindVertexArray(int numverts,RAS_IPolyMaterial* polymat);
+ BL_SkinMeshObject(int lightlayer) : RAS_MeshObject (lightlayer)
+ {};
+
+ virtual ~BL_SkinMeshObject(){
+ };
+
+ const vecIndexArrays& GetDIndexCache (RAS_IPolyMaterial* mat)
+ {
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ return ao->m_DIndexArrayCache1;
+ }
+ const vecMDVertArray& GetDVertCache (RAS_IPolyMaterial* mat)
+ {
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ return ao->m_DvertArrayCache1;
+ }
+ const vecIndexArrays& GetMVertCache (RAS_IPolyMaterial* mat)
+ {
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ return ao->m_MvertArrayCache1;
+ }
+
+ void AddPolygon(RAS_Polygon* poly);
+ int FindOrAddDeform(int vtxarray, int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat);
+ int FindOrAddVertex(int vtxarray,const MT_Point3& xyz,
+ const MT_Point2& uv,
+ const unsigned int rgbacolor,
+ const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat)
+ {
+ short newnormal[3];
+ newnormal[0]=(short)(normal[0] * 32767.0);
+ newnormal[1]=(short)(normal[1] * 32767.0);
+ newnormal[2]=(short)(normal[2] * 32767.0);
+
+ RAS_TexVert tempvert(xyz,uv,rgbacolor,newnormal,flat ? TV_CALCFACENORMAL : 0);
+
+ // KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+
+ int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray];
+
+ int index=-1;
+
+ for (int i=0;i<numverts;i++)
+ {
+ const RAS_TexVert& vtx = (*ao->m_VertexArrayCache1[vtxarray])[i];
+ if (tempvert.closeTo(&vtx))
+ {
+ index = i;
+ break;
+ }
+
+ }
+ if (index >= 0)
+ return index;
+
+ // no vertex found, add one
+ ao->m_VertexArrayCache1[vtxarray]->push_back(tempvert);
+ ao->m_DIndexArrayCache1[vtxarray]->push_back(defnr);
+
+ return numverts;
+
+
+ }
+
+};
+
+
+#endif
+
diff --git a/source/gameengine/Converter/BlenderWorldInfo.cpp b/source/gameengine/Converter/BlenderWorldInfo.cpp
new file mode 100644
index 00000000000..5dd41a317aa
--- /dev/null
+++ b/source/gameengine/Converter/BlenderWorldInfo.cpp
@@ -0,0 +1,215 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdio.h> // printf()
+
+
+#include "BlenderWorldInfo.h"
+#include "KX_BlenderGL.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+/* This list includes only data type definitions */
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_group_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_property_types.h"
+#include "DNA_text_types.h"
+#include "DNA_sensor_types.h"
+#include "DNA_controller_types.h"
+#include "DNA_actuator_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
+#include "DNA_screen_types.h"
+
+#include "BKE_global.h"
+/* end of blender include block */
+
+
+BlenderWorldInfo::BlenderWorldInfo(struct World* blenderworld)
+{
+ if (blenderworld)
+ {
+ m_hasworld = true;
+
+ // do we have mist?
+ if ((blenderworld->mode) & WO_MIST)
+ {
+ m_hasmist = true;
+ m_miststart = blenderworld->miststa;
+ m_mistdistance = blenderworld->mistdist;
+ m_mistred = blenderworld->horr;
+ m_mistgreen = blenderworld->horg;
+ m_mistblue = blenderworld->horb;
+ }
+ else
+ {
+ m_hasmist = false;
+ m_miststart = 0.0;
+ m_mistdistance = 0.0;
+ m_mistred = 0.0;
+ m_mistgreen = 0.0;
+ m_mistblue = 0.0;
+ }
+
+ m_backgroundred = blenderworld->horr;
+ m_backgroundgreen = blenderworld->horg;
+ m_backgroundblue = blenderworld->horb;
+ }
+ else
+ {
+ m_hasworld = false;
+ }
+}
+
+
+
+BlenderWorldInfo::~BlenderWorldInfo()
+{
+
+}
+
+
+bool BlenderWorldInfo::hasWorld()
+{
+ return m_hasworld;
+}
+
+
+
+bool BlenderWorldInfo::hasMist()
+{
+ return m_hasmist;
+}
+
+
+
+float BlenderWorldInfo::getBackColorRed()
+{
+ return m_backgroundred;
+}
+
+
+
+float BlenderWorldInfo::getBackColorGreen()
+{
+ return m_backgroundgreen;
+}
+
+
+
+float BlenderWorldInfo::getBackColorBlue()
+{
+ return m_backgroundblue;
+}
+
+
+
+float BlenderWorldInfo::getMistStart()
+{
+ return m_miststart;
+}
+
+
+
+float BlenderWorldInfo::getMistDistance()
+{
+ return m_mistdistance;
+}
+
+
+
+float BlenderWorldInfo::getMistColorRed()
+{
+ return m_mistred;
+}
+
+
+
+float BlenderWorldInfo::getMistColorGreen()
+{
+ return m_mistgreen;
+}
+
+
+
+float BlenderWorldInfo::getMistColorBlue()
+{
+ return m_mistblue;
+}
+
+
+ void
+BlenderWorldInfo::setMistStart(
+ float d
+) {
+ m_miststart = d;
+}
+
+
+ void
+BlenderWorldInfo::setMistDistance(
+ float d
+) {
+ m_mistdistance = d;
+}
+
+
+ void
+BlenderWorldInfo::setMistColorRed(
+ float d
+) {
+ m_mistred = d;
+}
+
+
+ void
+BlenderWorldInfo::setMistColorGreen(
+ float d
+) {
+ m_mistgreen = d;
+}
+
+
+ void
+BlenderWorldInfo::setMistColorBlue(
+ float d
+) {
+ m_mistblue = d;
+}
diff --git a/source/gameengine/Converter/BlenderWorldInfo.h b/source/gameengine/Converter/BlenderWorldInfo.h
new file mode 100644
index 00000000000..1defd41bc72
--- /dev/null
+++ b/source/gameengine/Converter/BlenderWorldInfo.h
@@ -0,0 +1,95 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __BLENDERWORLDINFO_H
+#define __BLENDERWORLDINFO_H
+#include "MT_CmMatrix4x4.h"
+#include "KX_WorldInfo.h"
+#include "KX_BlenderGL.h"
+
+
+class BlenderWorldInfo : public KX_WorldInfo
+{
+ bool m_hasworld;
+ float m_backgroundred;
+ float m_backgroundgreen;
+ float m_backgroundblue;
+
+ bool m_hasmist;
+ float m_miststart;
+ float m_mistdistance;
+ float m_mistred;
+ float m_mistgreen;
+ float m_mistblue;
+
+public:
+ BlenderWorldInfo(struct World* blenderworld);
+ ~BlenderWorldInfo();
+
+ bool hasWorld();
+ bool hasMist();
+ float getBackColorRed();
+ float getBackColorGreen();
+ float getBackColorBlue();
+
+ float getMistStart();
+ float getMistDistance();
+ float getMistColorRed();
+ float getMistColorGreen();
+ float getMistColorBlue();
+
+ void
+ setMistStart(
+ float d
+ );
+
+ void
+ setMistDistance(
+ float d
+ );
+
+ void
+ setMistColorRed(
+ float d
+ );
+
+ void
+ setMistColorGreen(
+ float d
+ );
+
+ void
+ setMistColorBlue(
+ float d
+ );
+};
+
+#endif //__BLENDERWORLDINFO_H
diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
new file mode 100644
index 00000000000..c75a6e5b4e7
--- /dev/null
+++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
@@ -0,0 +1,81 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "KX_BlenderScalarInterpolator.h"
+
+extern "C" int IPO_GetChannels(struct Ipo *ipo, short *channels);
+extern "C" float IPO_GetFloatValue(struct Ipo *ipo, /*IPO_Channel*/ short channel, float ctime);
+
+
+static const int BL_MAX_CHANNELS = 32;
+
+float BL_ScalarInterpolator::GetValue(float currentTime) const {
+ return IPO_GetFloatValue(m_blender_ipo, m_channel, currentTime);
+}
+
+typedef short IPO_Channel;
+
+BL_InterpolatorList::BL_InterpolatorList(struct Ipo *ipo) {
+ IPO_Channel channels[BL_MAX_CHANNELS];
+
+ int num_channels = IPO_GetChannels(ipo, channels);
+
+ int i;
+
+ for (i = 0; i != num_channels; ++i) {
+ BL_ScalarInterpolator *new_ipo =
+ new BL_ScalarInterpolator(ipo, channels[i]);
+
+ //assert(new_ipo);
+ push_back(new_ipo);
+ }
+}
+
+BL_InterpolatorList::~BL_InterpolatorList() {
+ BL_InterpolatorList::iterator i;
+ for (i = begin(); !(i == end()); ++i) {
+ delete *i;
+ }
+}
+
+
+KX_IScalarInterpolator *BL_InterpolatorList::GetScalarInterpolator(BL_IpoChannel channel) {
+ BL_InterpolatorList::iterator i = begin();
+ while (!(i == end()) &&
+ (static_cast<BL_ScalarInterpolator *>(*i))->GetChannel() !=
+ channel) {
+ ++i;
+ }
+
+ return (i == end()) ? 0 : *i;
+}
+
diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.h b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h
new file mode 100644
index 00000000000..6276b286ce4
--- /dev/null
+++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h
@@ -0,0 +1,70 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_SCALARINTERPOLATOR_H
+#define __KX_SCALARINTERPOLATOR_H
+
+#include <vector>
+
+#include "KX_IScalarInterpolator.h"
+
+typedef unsigned short BL_IpoChannel;
+
+class BL_ScalarInterpolator : public KX_IScalarInterpolator {
+public:
+ BL_ScalarInterpolator() {} // required for use in STL list
+ BL_ScalarInterpolator(struct Ipo *ipo, BL_IpoChannel channel) :
+ m_blender_ipo(ipo),
+ m_channel(channel)
+ {}
+
+ virtual ~BL_ScalarInterpolator() {}
+
+ virtual float GetValue(float currentTime) const;
+
+ BL_IpoChannel GetChannel() const { return m_channel; }
+
+private:
+ struct Ipo *m_blender_ipo;
+ BL_IpoChannel m_channel;
+};
+
+
+class BL_InterpolatorList : public std::vector<KX_IScalarInterpolator *> {
+public:
+ BL_InterpolatorList(struct Ipo *ipo);
+ ~BL_InterpolatorList();
+
+ KX_IScalarInterpolator *GetScalarInterpolator(BL_IpoChannel channel);
+};
+
+
+#endif //__KX_SCALARINTERPOLATOR_H
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
new file mode 100644
index 00000000000..fdba851b7a3
--- /dev/null
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -0,0 +1,416 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+
+ #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+#endif
+
+
+#include "KX_Scene.h"
+#include "KX_GameObject.h"
+#include "KX_IpoConvert.h"
+#include "RAS_MeshObject.h"
+#include "KX_PhysicsEngineEnums.h"
+
+#include "DummyPhysicsEnvironment.h"
+
+#ifdef USE_ODE
+#include "OdePhysicsEnvironment.h"
+#endif //USE_ODE
+
+//to decide to use sumo/ode or dummy physics
+#include "KX_ConvertPhysicsObject.h"
+#ifdef USE_SUMO_SOLID
+#include "SumoPhysicsEnvironment.h"
+#endif
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_BlenderScalarInterpolator.h"
+#include "BL_BlenderDataConversion.h"
+#include "BlenderWorldInfo.h"
+#include "KX_Scene.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+/* This list includes only data type definitions */
+#include "DNA_scene_types.h"
+#include "DNA_world_types.h"
+#include "BKE_main.h"
+
+
+KX_BlenderSceneConverter::KX_BlenderSceneConverter(
+ struct Main* maggie,
+ class KX_KetsjiEngine* engine
+ )
+ : m_maggie(maggie),
+ m_ketsjiEngine(engine),
+ m_alwaysUseExpandFraming(false)
+{
+ m_newfilename = "";
+}
+
+
+KX_BlenderSceneConverter::~KX_BlenderSceneConverter()
+{
+ // clears meshes, and hashmaps from blender to gameengine data
+ int i;
+ // delete sumoshapes
+
+
+ int numipolists = m_map_blender_to_gameipolist.size();
+ for (i=0; i<numipolists; i++) {
+ BL_InterpolatorList *ipoList= *m_map_blender_to_gameipolist.at(i);
+
+ delete (ipoList);
+ }
+
+ vector<KX_WorldInfo*>::iterator itw = m_worldinfos.begin();
+ while (itw != m_worldinfos.end()) {
+ delete (*itw);
+ itw++;
+ }
+
+ vector<RAS_IPolyMaterial*>::iterator itp = m_polymaterials.begin();
+ while (itp != m_polymaterials.end()) {
+ delete (*itp);
+ itp++;
+ }
+
+ vector<RAS_MeshObject*>::iterator itm = m_meshobjects.begin();
+ while (itm != m_meshobjects.end()) {
+ delete (*itm);
+ itm++;
+ }
+}
+
+
+
+void KX_BlenderSceneConverter::SetNewFileName(const STR_String& filename)
+{
+ m_newfilename = filename;
+}
+
+
+
+bool KX_BlenderSceneConverter::TryAndLoadNewFile()
+{
+ bool result = false;
+
+ // find the file
+/* if ()
+ {
+ result = true;
+ }
+ // if not, clear the newfilename
+ else
+ {
+ m_newfilename = "";
+ }
+*/
+ return result;
+}
+
+
+
+ /**
+ * Find the specified scene by name, or the first
+ * scene if nothing matches (shouldn't happen).
+ */
+static struct Scene *GetSceneForName2(struct Main *maggie, const STR_String& scenename) {
+ Scene *sce;
+
+ for (sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
+ if (scenename == (sce->id.name+2))
+ return sce;
+
+ return (Scene*) maggie->scene.first;
+}
+
+
+void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
+ class KX_Scene* destinationscene,
+ PyObject* dictobj,
+ class SCA_IInputDevice* keyinputdev,
+ class RAS_IRenderTools* rendertools,
+ class RAS_ICanvas* canvas)
+{
+ //find out which physics engine
+ Scene *blenderscene = GetSceneForName2(m_maggie, scenename);
+
+ e_PhysicsEngine physics_engine = UseSumo;
+
+ if (blenderscene)
+ {
+ int i=0;
+
+ if (blenderscene->world)
+ {
+
+ switch (blenderscene->world->pad1)
+ {
+
+ case 4:
+ {
+ physics_engine = UseODE;
+ break;
+ }
+ case 5:
+ {
+ physics_engine = UseDynamo;
+ break;
+ }
+ case 7:
+ {
+ physics_engine = UseNone;
+ break;
+ };
+ default:
+ {
+ physics_engine = UseSumo;
+ }
+ }
+ }
+ }
+
+ switch (physics_engine)
+ {
+
+ case UseSumo:
+ {
+#ifdef USE_SUMO_SOLID
+
+ PHY_IPhysicsEnvironment* physEnv =
+ new SumoPhysicsEnvironment();
+#else
+ physics_engine = UseNone;
+
+ PHY_IPhysicsEnvironment* physEnv =
+ new DummyPhysicsEnvironment();
+
+#endif
+ destinationscene ->SetPhysicsEnvironment(physEnv);
+ break;
+ }
+ case UseODE:
+ {
+#ifdef USE_ODE
+
+ PHY_IPhysicsEnvironment* physEnv =
+ new ODEPhysicsEnvironment();
+#else
+ PHY_IPhysicsEnvironment* physEnv =
+ new DummyPhysicsEnvironment();
+
+#endif //USE_ODE
+
+ destinationscene ->SetPhysicsEnvironment(physEnv);
+ break;
+ }
+ case UseDynamo:
+ {
+ }
+
+ case UseNone:
+ {
+ };
+ default:
+ {
+ physics_engine = UseNone;
+
+ PHY_IPhysicsEnvironment* physEnv =
+ new DummyPhysicsEnvironment();
+ destinationscene ->SetPhysicsEnvironment(physEnv);
+
+ }
+ }
+
+ BL_ConvertBlenderObjects(m_maggie,
+ scenename,
+ destinationscene,
+ m_ketsjiEngine,
+ physics_engine,
+ dictobj,
+ keyinputdev,
+ rendertools,
+ canvas,
+ this,
+ m_alwaysUseExpandFraming
+ );
+
+ m_map_blender_to_gameactuator.clear();
+ m_map_blender_to_gamecontroller.clear();
+
+ m_map_blender_to_gameobject.clear();
+ m_map_mesh_to_gamemesh.clear();
+ m_map_gameobject_to_blender.clear();
+}
+
+
+
+void KX_BlenderSceneConverter::SetAlwaysUseExpandFraming(
+ bool to_what)
+{
+ m_alwaysUseExpandFraming= to_what;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterGameObject(
+ KX_GameObject *gameobject,
+ struct Object *for_blenderobject)
+{
+ m_map_gameobject_to_blender.insert(CHashedPtr(gameobject),for_blenderobject);
+ m_map_blender_to_gameobject.insert(CHashedPtr(for_blenderobject),gameobject);
+}
+
+
+
+KX_GameObject *KX_BlenderSceneConverter::FindGameObject(
+ struct Object *for_blenderobject)
+{
+ KX_GameObject **obp= m_map_blender_to_gameobject[CHashedPtr(for_blenderobject)];
+
+ return obp?*obp:NULL;
+}
+
+
+
+struct Object *KX_BlenderSceneConverter::FindBlenderObject(
+ KX_GameObject *for_gameobject)
+{
+ struct Object **obp= m_map_gameobject_to_blender[CHashedPtr(for_gameobject)];
+
+ return obp?*obp:NULL;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterGameMesh(
+ RAS_MeshObject *gamemesh,
+ struct Mesh *for_blendermesh)
+{
+ m_map_mesh_to_gamemesh.insert(CHashedPtr(for_blendermesh),gamemesh);
+ m_meshobjects.push_back(gamemesh);
+}
+
+
+
+RAS_MeshObject *KX_BlenderSceneConverter::FindGameMesh(
+ struct Mesh *for_blendermesh,
+ unsigned int onlayer)
+{
+ RAS_MeshObject** meshp = m_map_mesh_to_gamemesh[CHashedPtr(for_blendermesh)];
+
+ if (meshp && onlayer==(*meshp)->GetLightLayer()) {
+ return *meshp;
+ } else {
+ return NULL;
+ }
+}
+
+
+
+
+
+
+void KX_BlenderSceneConverter::RegisterPolyMaterial(RAS_IPolyMaterial *polymat)
+{
+ m_polymaterials.push_back(polymat);
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterInterpolatorList(
+ BL_InterpolatorList *ipoList,
+ struct Ipo *for_ipo)
+{
+ m_map_blender_to_gameipolist.insert(CHashedPtr(for_ipo), ipoList);
+}
+
+
+
+BL_InterpolatorList *KX_BlenderSceneConverter::FindInterpolatorList(
+ struct Ipo *for_ipo)
+{
+ BL_InterpolatorList **listp = m_map_blender_to_gameipolist[CHashedPtr(for_ipo)];
+
+ return listp?*listp:NULL;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterGameActuator(
+ SCA_IActuator *act,
+ struct bActuator *for_actuator)
+{
+ m_map_blender_to_gameactuator.insert(CHashedPtr(for_actuator), act);
+}
+
+
+
+SCA_IActuator *KX_BlenderSceneConverter::FindGameActuator(
+ struct bActuator *for_actuator)
+{
+ SCA_IActuator **actp = m_map_blender_to_gameactuator[CHashedPtr(for_actuator)];
+
+ return actp?*actp:NULL;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterGameController(
+ SCA_IController *cont,
+ struct bController *for_controller)
+{
+ m_map_blender_to_gamecontroller.insert(CHashedPtr(for_controller), cont);
+}
+
+
+
+SCA_IController *KX_BlenderSceneConverter::FindGameController(
+ struct bController *for_controller)
+{
+ SCA_IController **contp = m_map_blender_to_gamecontroller[CHashedPtr(for_controller)];
+
+ return contp?*contp:NULL;
+}
+
+
+
+void KX_BlenderSceneConverter::RegisterWorldInfo(
+ KX_WorldInfo *worldinfo)
+{
+ m_worldinfos.push_back(worldinfo);
+}
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.h b/source/gameengine/Converter/KX_BlenderSceneConverter.h
new file mode 100644
index 00000000000..446c238a274
--- /dev/null
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.h
@@ -0,0 +1,120 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_BLENDERSCENECONVERTER_H
+#define __KX_BLENDERSCENECONVERTER_H
+
+#include "GEN_Map.h"
+
+#include "KX_ISceneConverter.h"
+#include "KX_HashedPtr.h"
+#include "KX_IpoConvert.h"
+
+class KX_WorldInfo;
+class SCA_IActuator;
+class SCA_IController;
+class RAS_MeshObject;
+class RAS_IPolyMaterial;
+class BL_InterpolatorList;
+
+class KX_BlenderSceneConverter : public KX_ISceneConverter
+{
+ vector<KX_WorldInfo*> m_worldinfos;
+ vector<RAS_IPolyMaterial*> m_polymaterials;
+ vector<RAS_MeshObject*> m_meshobjects;
+
+ GEN_Map<CHashedPtr,struct Object*> m_map_gameobject_to_blender;
+ GEN_Map<CHashedPtr,KX_GameObject*> m_map_blender_to_gameobject;
+
+ GEN_Map<CHashedPtr,RAS_MeshObject*> m_map_mesh_to_gamemesh;
+// GEN_Map<CHashedPtr,DT_ShapeHandle> m_map_gamemesh_to_sumoshape;
+
+ GEN_Map<CHashedPtr,SCA_IActuator*> m_map_blender_to_gameactuator;
+ GEN_Map<CHashedPtr,SCA_IController*> m_map_blender_to_gamecontroller;
+
+ GEN_Map<CHashedPtr,BL_InterpolatorList*> m_map_blender_to_gameipolist;
+
+ struct Main* m_maggie;
+ STR_String m_newfilename;
+ class KX_KetsjiEngine* m_ketsjiEngine;
+ bool m_alwaysUseExpandFraming;
+
+public:
+ KX_BlenderSceneConverter(
+ struct Main* maggie,
+ class KX_KetsjiEngine* engine
+ );
+
+ virtual ~KX_BlenderSceneConverter();
+
+ /* Scenename: name of the scene to be converted.
+ * destinationscene: pass an empty scene, everything goes into this
+ * dictobj: python dictionary (for pythoncontrollers)
+ */
+ virtual void ConvertScene(
+ const STR_String& scenename,
+ class KX_Scene* destinationscene,
+ PyObject* dictobj,
+ class SCA_IInputDevice* keyinputdev,
+ class RAS_IRenderTools* rendertools,
+ class RAS_ICanvas* canvas
+ );
+
+ void SetNewFileName(const STR_String& filename);
+ bool TryAndLoadNewFile();
+
+ void SetAlwaysUseExpandFraming(bool to_what);
+
+ void RegisterGameObject(KX_GameObject *gameobject, struct Object *for_blenderobject);
+ KX_GameObject *FindGameObject(struct Object *for_blenderobject);
+ struct Object *FindBlenderObject(KX_GameObject *for_gameobject);
+
+ void RegisterGameMesh(RAS_MeshObject *gamemesh, struct Mesh *for_blendermesh);
+ RAS_MeshObject *FindGameMesh(struct Mesh *for_blendermesh, unsigned int onlayer);
+
+// void RegisterSumoShape(DT_ShapeHandle shape, RAS_MeshObject *for_gamemesh);
+// DT_ShapeHandle FindSumoShape(RAS_MeshObject *for_gamemesh);
+
+ void RegisterPolyMaterial(RAS_IPolyMaterial *polymat);
+
+ void RegisterInterpolatorList(BL_InterpolatorList *ipoList, struct Ipo *for_ipo);
+ BL_InterpolatorList *FindInterpolatorList(struct Ipo *for_ipo);
+
+ void RegisterGameActuator(SCA_IActuator *act, struct bActuator *for_actuator);
+ SCA_IActuator *FindGameActuator(struct bActuator *for_actuator);
+
+ void RegisterGameController(SCA_IController *cont, struct bController *for_controller);
+ SCA_IController *FindGameController(struct bController *for_controller);
+
+ void RegisterWorldInfo(KX_WorldInfo *worldinfo);
+};
+
+#endif //__KX_BLENDERSCENECONVERTER_H
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
new file mode 100644
index 00000000000..2628441ba72
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -0,0 +1,909 @@
+/**
+* $Id$
+*
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+* Convert Blender actuators for use in the GameEngine
+*/
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#define BLENDER_HACK_DTIME 0.02
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_ConvertActuators.h"
+
+// Actuators
+//SCA logiclibrary native logicbricks
+#include "SCA_PropertyActuator.h"
+#include "SCA_LogicManager.h"
+#include "SCA_RandomActuator.h"
+
+
+// Ketsji specific logicbricks
+#include "KX_SceneActuator.h"
+#include "KX_IpoActuator.h"
+#include "KX_SoundActuator.h"
+#include "KX_CDActuator.h"
+#include "KX_ObjectActuator.h"
+#include "KX_TrackToActuator.h"
+#include "KX_ConstraintActuator.h"
+#include "KX_CameraActuator.h"
+#include "KX_GameActuator.h"
+#include "KX_VisibilityActuator.h"
+#include "KX_SCA_AddObjectActuator.h"
+#include "KX_SCA_EndObjectActuator.h"
+#include "KX_SCA_ReplaceMeshActuator.h"
+
+#include "KX_Scene.h"
+#include "KX_KetsjiEngine.h"
+
+#include "IntValue.h"
+#include "KX_GameObject.h"
+
+/* This little block needed for linking to Blender... */
+
+#include "BLI_blenlib.h"
+
+#include "KX_NetworkMessageActuator.h"
+
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_actuator_types.h"
+#include "DNA_packedFile_types.h"
+#include "BL_ActionActuator.h"
+/* end of blender include block */
+
+#include "BL_BlenderDataConversion.h"
+
+/**
+KX_BLENDERTRUNC needed to round 'almost' zero values to zero, else velocities etc. are incorrectly set
+*/
+
+#define KX_BLENDERTRUNC(x) (( x < 0.0001 && x > -0.0001 ) ? 0.0 : x)
+
+void BL_ConvertActuators(char* maggiename,
+ struct Object* blenderobject,
+ KX_GameObject* gameobj,
+ SCA_LogicManager* logicmgr,
+ KX_Scene* scene,
+ KX_KetsjiEngine* ketsjiEngine,
+ int & executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ RAS_IRenderTools* rendertools,
+ KX_BlenderSceneConverter* converter
+ )
+{
+
+ int uniqueint = 0;
+ bActuator* bact = (bActuator*) blenderobject->actuators.first;
+ while(bact)
+ {
+ STR_String uniquename = bact->name;
+ STR_String objectname = gameobj->GetName();
+
+ SCA_IActuator* baseact = NULL;
+ switch (bact->type)
+ {
+ case ACT_OBJECT:
+ {
+ bObjectActuator* obact = (bObjectActuator*) bact->data;
+ MT_Vector3 forcevec(KX_BLENDERTRUNC(obact->forceloc[0]),
+ KX_BLENDERTRUNC(obact->forceloc[1]),
+ KX_BLENDERTRUNC(obact->forceloc[2]));
+ MT_Vector3 torquevec(obact->forcerot[0],obact->forcerot[1],obact->forcerot[2]);
+ MT_Vector3 dlocvec ( KX_BLENDERTRUNC(obact->dloc[0]),
+ KX_BLENDERTRUNC(obact->dloc[1]),
+ KX_BLENDERTRUNC(obact->dloc[2]));
+ MT_Vector3 drotvec ( KX_BLENDERTRUNC(obact->drot[0]),obact->drot[1],obact->drot[2]);
+ MT_Vector3 linvelvec ( KX_BLENDERTRUNC(obact->linearvelocity[0]),
+ KX_BLENDERTRUNC(obact->linearvelocity[1]),
+ KX_BLENDERTRUNC(obact->linearvelocity[2]));
+ MT_Vector3 angvelvec ( KX_BLENDERTRUNC(obact->angularvelocity[0]),
+ KX_BLENDERTRUNC(obact->angularvelocity[1]),
+ KX_BLENDERTRUNC(obact->angularvelocity[2]));
+
+ drotvec /= BLENDER_HACK_DTIME;
+ //drotvec /= BLENDER_HACK_DTIME;
+ drotvec *= MT_2_PI/360.0;
+ //dlocvec /= BLENDER_HACK_DTIME;
+ //linvelvec /= BLENDER_HACK_DTIME;
+ //angvelvec /= BLENDER_HACK_DTIME;
+
+ /* Blender uses a bit vector internally for the local-flags. In */
+ /* KX, we have four bools. The compiler should be smart enough */
+ /* to do the right thing. We need to explicitly convert here! */
+
+ KX_LocalFlags bitLocalFlag;
+
+ bitLocalFlag.Force = bool((obact->flag & ACT_FORCE_LOCAL)!=0);
+ bitLocalFlag.Torque = bool((obact->flag & ACT_TORQUE_LOCAL) !=0);//rlocal;
+ bitLocalFlag.DLoc = bool((obact->flag & ACT_DLOC_LOCAL)!=0);
+ bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0);
+ bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
+ bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
+
+ bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0);
+
+
+ KX_ObjectActuator* tmpbaseact = new KX_ObjectActuator(gameobj,
+ forcevec.getValue(),
+ torquevec.getValue(),
+ dlocvec.getValue(),
+ drotvec.getValue(),
+ linvelvec.getValue(),
+ angvelvec.getValue(),
+ bitLocalFlag
+ );
+ baseact = tmpbaseact;
+ break;
+ }
+ case ACT_ACTION:
+ {
+ if (blenderobject->type==OB_ARMATURE){
+ bActionActuator* actact = (bActionActuator*) bact->data;
+ STR_String propname = (actact->name ? actact->name : "");
+
+ BL_ActionActuator* tmpbaseact = new BL_ActionActuator(
+ gameobj,
+ propname,
+ actact->sta,
+ actact->end,
+ actact->act,
+ actact->type, // + 1, because Blender starts to count at zero,
+ actact->blendin,
+ actact->priority,
+ actact->stridelength
+ // Ketsji at 1, because zero is reserved for "NoDef"
+ );
+ baseact= tmpbaseact;
+ break;
+ }
+ else
+ printf ("Discarded action actuator from non-armature object [%s]\n", blenderobject->id.name+2);
+ }
+ case ACT_IPO:
+ {
+ bIpoActuator* ipoact = (bIpoActuator*) bact->data;
+ bool ipochild = (ipoact->flag & ACT_IPOCHILD) !=0;
+ STR_String propname = ( ipoact->name ? ipoact->name : "");
+ // first bit?
+ bool ipo_as_force = (ipoact->flag & ACT_IPOFORCE);
+ bool force_local = (ipoact->flag & ACT_IPOFORCE_LOCAL);
+
+ KX_IpoActuator* tmpbaseact = new KX_IpoActuator(
+ gameobj,
+ propname ,
+ ipoact->sta,
+ ipoact->end,
+ ipochild,
+ ipoact->type + 1, // + 1, because Blender starts to count at zero,
+ // Ketsji at 1, because zero is reserved for "NoDef"
+ ipo_as_force,
+ force_local
+ );
+ baseact = tmpbaseact;
+ break;
+ }
+ case ACT_LAMP:
+ {
+ break;
+ }
+ case ACT_CAMERA:
+ {
+ bCameraActuator *camact = (bCameraActuator *) bact->data;
+ if (camact->ob) {
+ KX_GameObject *tmpgob = converter->FindGameObject(camact->ob);
+
+ /* visifac, fac and axis are not copied from the struct... */
+ /* that's some internal state... */
+ KX_CameraActuator *tmpcamact
+ = new KX_CameraActuator(gameobj,
+ tmpgob,
+ camact->height,
+ camact->min,
+ camact->max,
+ camact->axis=='x');
+ baseact = tmpcamact;
+ }
+ break;
+ }
+ case ACT_MESSAGE:
+ {
+ bMessageActuator *msgAct = (bMessageActuator *) bact->data;
+
+ /**
+ * Get the name of the properties that objects must own that
+ * we're sending to, if present
+ */
+ STR_String toPropName = (msgAct->toPropName
+ ? (char*) msgAct->toPropName
+ : "");
+ /**
+ * Get the Message Subject to send.
+ */
+ STR_String subject = (msgAct->subject
+ ? (char*) msgAct->subject
+ : "");
+
+ /**
+ * Get the bodyType
+ */
+ int bodyType = msgAct->bodyType;
+
+ /**
+ * Get the body (text message or property name whose value
+ * we'll be sending, might be empty
+ */
+ STR_String body = (msgAct->body
+ ? (char*) msgAct->body
+ : "");
+
+ KX_NetworkMessageActuator *tmpmsgact =
+ new KX_NetworkMessageActuator(
+ gameobj, // actuator controlling object
+ scene->GetNetworkScene(), // needed for replication
+ toPropName,
+ subject,
+ bodyType,
+ body);
+ baseact = tmpmsgact;
+ break;
+ }
+ case ACT_MATERIAL:
+ {
+ break;
+ }
+ case ACT_SOUND:
+ {
+ bSoundActuator* soundact = (bSoundActuator*) bact->data;
+ /* get type, and possibly a start and end frame */
+ short startFrame = soundact->sta, stopFrame = soundact->end;
+ KX_SoundActuator::KX_SOUNDACT_TYPE
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
+
+ switch(soundact->type) {
+ case ACT_SND_PLAY_STOP_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYSTOP;
+ break;
+ case ACT_SND_PLAY_END_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_PLAYEND;
+ break;
+ case ACT_SND_LOOP_STOP_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPSTOP;
+ break;
+ case ACT_SND_LOOP_END_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPEND;
+ break;
+ case ACT_SND_LOOP_BIDIRECTIONAL_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL;
+ break;
+ case ACT_SND_LOOP_BIDIRECTIONAL_STOP_SOUND:
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP;
+ break;
+
+ default:
+ /* This is an error!!! */
+ soundActuatorType = KX_SoundActuator::KX_SOUNDACT_NODEF;
+ }
+
+ if (soundActuatorType != KX_SoundActuator::KX_SOUNDACT_NODEF)
+ {
+ SND_SoundObject* sndobj = NULL;
+
+ if (soundact->sound)
+ {
+ SND_Scene* soundscene = scene->GetSoundScene();
+ STR_String samplename = soundact->sound->name;
+
+ bool sampleisloaded = false;
+
+ /* let's see if the sample was already loaded */
+ if (soundscene->IsSampleLoaded(samplename))
+ {
+ sampleisloaded = true;
+ }
+ else
+ {
+ /* if not, make it so */
+ PackedFile* pf = soundact->sound->newpackedfile;
+
+ /* but we need a packed file then */
+ if (pf)
+ {
+ if (soundscene->LoadSample(samplename, pf->data, pf->size) > -1)
+ sampleisloaded = true;
+ }
+ /* or else load it from disk */
+ else
+ {
+ /* but we need to convert the samplename into absolute pathname first */
+ BLI_convertstringcode(soundact->sound->name, maggiename, 0);
+ samplename = soundact->sound->name;
+
+ /* and now we can load it */
+ if (soundscene->LoadSample(samplename, NULL, 0) > -1)
+ sampleisloaded = true;
+ }
+ }
+
+ if (sampleisloaded)
+ {
+ sndobj = new SND_SoundObject();
+ sndobj->SetSampleName(samplename.Ptr());
+ sndobj->SetObjectName(bact->name);
+ sndobj->SetRollOffFactor(soundact->sound->attenuation);
+ sndobj->SetGain(soundact->sound->volume);
+ sndobj->SetPitch(exp((soundact->sound->pitch / 12.0) * log(2.0)));
+ // sndobj->SetLoopStart(soundact->sound->loopstart);
+ // sndobj->SetLoopStart(soundact->sound->loopend);
+ if (soundact->sound->flags & SOUND_FLAGS_LOOP)
+ {
+ if (soundact->sound->flags & SOUND_FLAGS_BIDIRECTIONAL_LOOP)
+ sndobj->SetLoopMode(SND_LOOP_BIDIRECTIONAL);
+ else
+ sndobj->SetLoopMode(SND_LOOP_NORMAL);
+ }
+ else
+ sndobj->SetLoopMode(SND_LOOP_OFF);
+
+ if (soundact->sound->flags & SOUND_FLAGS_PRIORITY)
+ sndobj->SetHighPriority(true);
+ else
+ sndobj->SetHighPriority(false);
+
+ if (soundact->sound->flags & SOUND_FLAGS_3D)
+ sndobj->Set3D(true);
+ else
+ sndobj->Set3D(false);
+
+ KX_SoundActuator* tmpsoundact =
+ new KX_SoundActuator(gameobj,
+ sndobj,
+ scene->GetSoundScene(), // needed for replication!
+ soundActuatorType,
+ startFrame,
+ stopFrame);
+
+ tmpsoundact->SetName(bact->name);
+ baseact = tmpsoundact;
+ soundscene->AddObject(sndobj);
+ }
+ }
+ }
+ break;
+ }
+ case ACT_CD:
+ {
+ bCDActuator* cdact = (bCDActuator*) bact->data;
+ /* get type, and possibly a start and end frame */
+ short startFrame = cdact->sta, stopFrame = cdact->end;
+ KX_CDActuator::KX_CDACT_TYPE
+ cdActuatorType = KX_CDActuator::KX_CDACT_NODEF;
+
+ switch(cdact->type)
+ {
+ case ACT_CD_PLAY_ALL:
+ cdActuatorType = KX_CDActuator::KX_CDACT_PLAY_ALL;
+ break;
+ case ACT_CD_PLAY_TRACK:
+ cdActuatorType = KX_CDActuator::KX_CDACT_PLAY_TRACK;
+ break;
+ case ACT_CD_LOOP_TRACK:
+ cdActuatorType = KX_CDActuator::KX_CDACT_LOOP_TRACK;
+ break;
+ case ACT_CD_VOLUME:
+ cdActuatorType = KX_CDActuator::KX_CDACT_VOLUME;
+ break;
+ case ACT_CD_STOP:
+ cdActuatorType = KX_CDActuator::KX_CDACT_STOP;
+ break;
+ case ACT_CD_PAUSE:
+ cdActuatorType = KX_CDActuator::KX_CDACT_PAUSE;
+ break;
+ case ACT_CD_RESUME:
+ cdActuatorType = KX_CDActuator::KX_CDACT_RESUME;
+ break;
+
+ default:
+ /* This is an error!!! */
+ cdActuatorType = KX_CDActuator::KX_CDACT_NODEF;
+ }
+
+ if (cdActuatorType != KX_CDActuator::KX_CDACT_NODEF)
+ {
+ SND_Scene* soundscene = scene->GetSoundScene();
+ SND_CDObject* pCD = SND_CDObject::Instance();
+
+ if (pCD)
+ {
+ pCD->SetGain(cdact->volume);
+
+ KX_CDActuator* tmpcdact =
+ new KX_CDActuator(gameobj,
+ scene->GetSoundScene(), // needed for replication!
+ cdActuatorType,
+ cdact->track,
+ startFrame,
+ stopFrame);
+
+ tmpcdact->SetName(bact->name);
+ baseact = tmpcdact;
+ }
+ }
+ break;
+ }
+ case ACT_PROPERTY:
+ {
+ bPropertyActuator* propact = (bPropertyActuator*) bact->data;
+ CValue* destinationObj = NULL;
+
+ /*
+ here the destinationobject is searched. problem with multiple scenes: other scenes
+ have not been converted yet, so the destobj will not be found, so the prop will
+ not be copied.
+ possible solutions:
+ - convert everything when possible and not realtime only when needed.
+ - let the object-with-property report itself to the act when converted
+ */
+ if (propact->ob)
+ {
+ KX_GameObject* tempObj = converter->FindGameObject(propact->ob);
+ if (tempObj)
+ {
+ destinationObj = tempObj;
+ }
+ }
+
+ SCA_PropertyActuator* tmppropact = new SCA_PropertyActuator(
+ gameobj,
+ destinationObj,
+ propact->name,
+ propact->value,
+ propact->type+1); // + 1 because Ketsji Logic starts
+ // with 0 for KX_ACT_PROP_NODEF
+ baseact = tmppropact;
+ break;
+ }
+ case ACT_EDIT_OBJECT:
+ {
+ bEditObjectActuator *editobact
+ = (bEditObjectActuator *) bact->data;
+ /* There are four different kinds of 'edit object' thingies */
+ /* The alternative to this lengthy conversion is packing */
+ /* several actuators in one, which is not very nice design.. */
+ switch (editobact->type) {
+ case ACT_EDOB_ADD_OBJECT:
+ {
+
+ // does the 'original' for replication exists, and
+ // is it in a non-active layer ?
+ if (editobact->ob && !(editobact->ob->lay & activeLayerBitInfo))
+ {
+ CValue* originalval = converter->FindGameObject(editobact->ob);
+
+ if (originalval)
+ {
+ MT_Vector3 linvelvec ( KX_BLENDERTRUNC(editobact->linVelocity[0]),
+ KX_BLENDERTRUNC(editobact->linVelocity[1]),
+ KX_BLENDERTRUNC(editobact->linVelocity[2]));
+ KX_SCA_AddObjectActuator* tmpaddact =
+ new KX_SCA_AddObjectActuator(
+
+ gameobj,
+ originalval,
+ editobact->time,
+ scene,
+ linvelvec.getValue(),
+ editobact->localflag!=0
+
+ );
+
+ //editobact->ob to gameobj
+ baseact = tmpaddact;
+ }
+ else
+ {
+ // let's pretend this never happened
+ exit(0);
+ }
+ } else
+ {
+ printf ("ERROR: GameObject %s has a AddObjectActuator %s without object (in 'nonactive' layer)\n",
+ objectname.ReadPtr(),
+ uniquename.ReadPtr() );
+ }
+ }
+ break;
+ case ACT_EDOB_END_OBJECT:
+ {
+ KX_SCA_EndObjectActuator* tmpendact
+ = new KX_SCA_EndObjectActuator(gameobj,scene);
+ baseact = tmpendact;
+ }
+ break;
+ case ACT_EDOB_REPLACE_MESH:
+ {
+ if (editobact->me)
+ {
+ RAS_MeshObject *tmpmesh = BL_ConvertMesh(
+ editobact->me,
+ blenderobject,
+ rendertools,
+ scene,
+ converter
+ );
+ KX_SCA_ReplaceMeshActuator* tmpreplaceact
+ = new KX_SCA_ReplaceMeshActuator(
+ gameobj,
+ tmpmesh,
+ scene
+ );
+
+ baseact = tmpreplaceact;
+ }
+ else
+ {
+ printf ("ERROR: GameObject %s ReplaceMeshActuator %s without object\n",
+ objectname.ReadPtr(),
+ uniquename.ReadPtr());
+ }
+ }
+ break;
+ case ACT_EDOB_TRACK_TO:
+ {
+ if (editobact->ob)
+ {
+ SCA_IObject* originalval = converter->FindGameObject(editobact->ob);
+
+ KX_TrackToActuator* tmptrackact
+ = new KX_TrackToActuator(gameobj,
+ originalval,
+ editobact->time,
+ editobact->flag,
+ blenderobject->trackflag,
+ blenderobject->upflag
+ );
+ baseact = tmptrackact;
+ }
+ else
+ {
+ printf("ERROR: GameObject %s no object in EditObjectActuator %s\n",
+ objectname.ReadPtr(),
+ uniquename.ReadPtr() );
+
+
+ }
+ }
+ }
+ break;
+ }
+ case ACT_CONSTRAINT:
+ {
+ float min = 0.0, max = 0.0;
+ int locrot;
+ bConstraintActuator *conact
+ = (bConstraintActuator*) bact->data;
+ /* convert settings... degrees in the ui become radians */
+ /* internally */
+ switch (conact->flag) {
+ case ACT_CONST_LOCX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX;
+ min = conact->minloc[0];
+ max = conact->maxloc[0];
+ break;
+ case ACT_CONST_LOCY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY;
+ min = conact->minloc[1];
+ max = conact->maxloc[1];
+ break;
+ case ACT_CONST_LOCZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ;
+ min = conact->minloc[2];
+ max = conact->maxloc[2];
+ break;
+ case ACT_CONST_ROTX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX;
+ min = MT_2_PI * conact->minrot[0] / 360.0;
+ max = MT_2_PI * conact->maxrot[0] / 360.0;
+ break;
+ case ACT_CONST_ROTY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY;
+ min = MT_2_PI * conact->minrot[1] / 360.0;
+ max = MT_2_PI * conact->maxrot[1] / 360.0;
+ break;
+ case ACT_CONST_ROTZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ;
+ min = MT_2_PI * conact->minrot[2] / 360.0;
+ max = MT_2_PI * conact->maxrot[2] / 360.0;
+ break;
+ default:
+ ; /* error */
+ }
+ KX_ConstraintActuator *tmpconact
+ = new KX_ConstraintActuator(gameobj,
+ conact->damp,
+ min,
+ max,
+ locrot);
+ baseact = tmpconact;
+ break;
+ }
+ case ACT_GROUP:
+ {
+ // deprecated
+ }
+ break;
+ case ACT_SCENE:
+ {
+ bSceneActuator *sceneact = (bSceneActuator *) bact->data;
+ bool scenevalid = true;
+ STR_String nextSceneName;
+
+ KX_SceneActuator* tmpsceneact;
+ int mode = KX_SceneActuator::KX_SCENE_NODEF;
+ KX_Camera *cam = NULL;
+ //KX_Scene* scene = NULL;
+ switch (sceneact->type)
+ {
+ case ACT_SCENE_RESUME:
+ case ACT_SCENE_SUSPEND:
+ case ACT_SCENE_ADD_FRONT:
+ case ACT_SCENE_ADD_BACK:
+ case ACT_SCENE_REMOVE:
+ case ACT_SCENE_SET:
+ {
+ switch (sceneact->type)
+ {
+ case ACT_SCENE_RESUME:
+ mode = KX_SceneActuator::KX_SCENE_RESUME;
+ break;
+ case ACT_SCENE_SUSPEND:
+ mode = KX_SceneActuator::KX_SCENE_SUSPEND;
+ break;
+ case ACT_SCENE_ADD_FRONT:
+ mode = KX_SceneActuator::KX_SCENE_ADD_FRONT_SCENE;
+ break;
+ case ACT_SCENE_ADD_BACK:
+ mode = KX_SceneActuator::KX_SCENE_ADD_BACK_SCENE;
+ break;
+ case ACT_SCENE_REMOVE:
+ mode = KX_SceneActuator::KX_SCENE_REMOVE_SCENE;
+ break;
+ case ACT_SCENE_SET:
+ default:
+ mode = KX_SceneActuator::KX_SCENE_SET_SCENE;
+ break;
+ };
+
+ if (sceneact->scene)
+ {
+ nextSceneName = sceneact->scene->id.name + 2; // this '2' is necessary to remove prefix 'SC'
+ }
+
+ if (!nextSceneName.Length())
+ {
+ printf ("ERROR: GameObject %s has a SceneActuator %s (SetScene) without scene\n",
+ objectname.ReadPtr(),
+ uniquename.ReadPtr());
+ scenevalid = false;
+
+ }
+ break;
+ }
+ case ACT_SCENE_CAMERA:
+ if (sceneact->camera)
+ {
+ mode = KX_SceneActuator::KX_SCENE_SET_CAMERA;
+ cam = (KX_Camera*) converter->FindGameObject(sceneact->camera);
+ }
+ else
+ {
+ // TODO:warn user
+ }
+ break;
+ case ACT_SCENE_RESTART:
+ {
+
+ mode = KX_SceneActuator::KX_SCENE_RESTART;
+ break;
+ }
+ default:
+ ; /* flag error */
+ }
+ if (scenevalid )
+ {
+ tmpsceneact = new KX_SceneActuator(gameobj,
+ mode,
+ scene,
+ ketsjiEngine,
+ nextSceneName,
+ cam);
+ baseact = tmpsceneact;
+ }
+ break;
+ }
+ case ACT_GAME:
+ {
+ bGameActuator *gameact = (bGameActuator *) bact->data;
+ KX_GameActuator* tmpgameact;
+ STR_String filename = maggiename;
+ STR_String loadinganimationname = "";
+ int mode = KX_GameActuator::KX_GAME_NODEF;
+ switch (gameact->type)
+ {
+ case ACT_GAME_LOAD:
+ {
+ mode = KX_GameActuator::KX_GAME_LOAD;
+ filename = gameact->filename;
+ loadinganimationname = gameact->loadaniname;
+ break;
+ }
+ case ACT_GAME_START:
+ {
+ mode = KX_GameActuator::KX_GAME_START;
+ filename = gameact->filename;
+ loadinganimationname = gameact->loadaniname;
+ break;
+ }
+ case ACT_GAME_RESTART:
+ {
+ mode = KX_GameActuator::KX_GAME_RESTART;
+ break;
+ }
+ case ACT_GAME_QUIT:
+ {
+ mode = KX_GameActuator::KX_GAME_QUIT;
+ break;
+ }
+ default:
+ ; /* flag error */
+ }
+ tmpgameact = new KX_GameActuator(gameobj,
+ mode,
+ filename,
+ loadinganimationname,
+ scene,
+ ketsjiEngine);
+ baseact = tmpgameact;
+
+ break;
+ }
+ case ACT_RANDOM:
+ {
+ bRandomActuator *randAct
+ = (bRandomActuator *) bact->data;
+
+ unsigned long seedArg = randAct->seed;
+ SCA_RandomActuator::KX_RANDOMACT_MODE modeArg
+ = SCA_RandomActuator::KX_RANDOMACT_NODEF;
+ SCA_RandomActuator *tmprandomact;
+ float paraArg1 = 0.0;
+ float paraArg2 = 0.0;
+
+ switch (randAct->distribution) {
+ case ACT_RANDOM_BOOL_CONST:
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST;
+ paraArg1 = (float) randAct->int_arg_1;
+ break;
+ case ACT_RANDOM_BOOL_UNIFORM:
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM;
+ break;
+ case ACT_RANDOM_BOOL_BERNOUILLI:
+ paraArg1 = randAct->float_arg_1;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI;
+ break;
+ case ACT_RANDOM_INT_CONST:
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_CONST;
+ paraArg1 = (float) randAct->int_arg_1;
+ break;
+ case ACT_RANDOM_INT_UNIFORM:
+ paraArg1 = (float) randAct->int_arg_1;
+ paraArg2 = (float) randAct->int_arg_2;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM;
+ break;
+ case ACT_RANDOM_INT_POISSON:
+ paraArg1 = randAct->float_arg_1;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_INT_POISSON;
+ break;
+ case ACT_RANDOM_FLOAT_CONST:
+ paraArg1 = randAct->float_arg_1;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST;
+ break;
+ case ACT_RANDOM_FLOAT_UNIFORM:
+ paraArg1 = randAct->float_arg_1;
+ paraArg2 = randAct->float_arg_2;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM;
+ break;
+ case ACT_RANDOM_FLOAT_NORMAL:
+ paraArg1 = randAct->float_arg_1;
+ paraArg2 = randAct->float_arg_2;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL;
+ break;
+ case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL:
+ paraArg1 = randAct->float_arg_1;
+ modeArg = SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
+ break;
+ default:
+ ; /* error */
+ }
+ tmprandomact = new SCA_RandomActuator(gameobj,
+ seedArg,
+ modeArg,
+ paraArg1,
+ paraArg2,
+ randAct->propname);
+ baseact = tmprandomact;
+ }
+ break;
+
+ case ACT_VISIBILITY:
+ {
+ bVisibilityActuator *vis_act = (bVisibilityActuator *) bact->data;
+ KX_VisibilityActuator * tmp_vis_act = NULL;
+ bool v = ((vis_act->flag & ACT_VISIBILITY_INVISIBLE) != 0);
+
+ tmp_vis_act =
+ new KX_VisibilityActuator(gameobj,
+ !v);
+
+ baseact = tmp_vis_act;
+ }
+ break;
+
+ default:
+ ; /* generate some error */
+ }
+
+ if (baseact)
+ {
+ baseact->SetExecutePriority(executePriority++);
+ uniquename += "#ACT#";
+ uniqueint++;
+ CIntValue* uniqueval = new CIntValue(uniqueint);
+ uniquename += uniqueval->GetText();
+ uniqueval->Release();
+ baseact->SetName(STR_String(bact->name));
+ //gameobj->SetProperty(uniquename,baseact);
+ gameobj->AddActuator(baseact);
+
+ converter->RegisterGameActuator(baseact, bact);
+ }
+
+ bact = bact->next;
+ }
+}
+
diff --git a/source/gameengine/Converter/KX_ConvertActuators.h b/source/gameengine/Converter/KX_ConvertActuators.h
new file mode 100644
index 00000000000..80aa64a19ef
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertActuators.h
@@ -0,0 +1,48 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_CONVERTACTUATORS_H
+#define __KX_CONVERTACTUATORS_H
+
+void BL_ConvertActuators(char* maggiename,
+ struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ class SCA_LogicManager* logicmgr,
+ class KX_Scene* scene,
+ class KX_KetsjiEngine* ketsjiEngine,
+ int & executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ class RAS_IRenderTools* rendertools,
+ class KX_BlenderSceneConverter* converter);
+
+
+#endif //__KX_CONVERTACTUATORS_H
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
new file mode 100644
index 00000000000..1a958744d70
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -0,0 +1,179 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "MEM_guardedalloc.h"
+
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_ConvertControllers.h"
+#include "KX_Python.h"
+
+// Controller
+#include "SCA_ANDController.h"
+#include "SCA_ORController.h"
+#include "SCA_PythonController.h"
+#include "SCA_ExpressionController.h"
+
+#include "SCA_LogicManager.h"
+#include "KX_GameObject.h"
+#include "IntValue.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_controller_types.h"
+#include "DNA_text_types.h"
+
+#include "BKE_text.h"
+
+#include "BLI_blenlib.h"
+
+/* end of blender include block */
+
+
+ static void
+LinkControllerToActuators(
+ SCA_IController *game_controller,
+ bController* bcontr,
+ SCA_LogicManager* logicmgr,
+ KX_BlenderSceneConverter* converter
+) {
+ // Iterate through the actuators of the game blender
+ // controller and find the corresponding ketsji actuator.
+
+ for (int i=0;i<bcontr->totlinks;i++)
+ {
+ bActuator* bact = (bActuator*) bcontr->links[i];
+ SCA_IActuator *game_actuator = converter->FindGameActuator(bact);
+ if (game_actuator) {
+ logicmgr->RegisterToActuator(game_controller, game_actuator);
+ }
+ }
+}
+
+
+void BL_ConvertControllers(
+ struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ SCA_LogicManager* logicmgr,
+ PyObject* pythondictionary,
+ int &executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ KX_BlenderSceneConverter* converter
+) {
+ int uniqueint=0;
+ bController* bcontr = (bController*)blenderobject->controllers.first;
+ while (bcontr)
+ {
+ SCA_IController* gamecontroller = NULL;
+ switch(bcontr->type)
+ {
+ case CONT_LOGIC_AND:
+ {
+ gamecontroller = new SCA_ANDController(gameobj);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ case CONT_LOGIC_OR:
+ {
+ gamecontroller = new SCA_ORController(gameobj);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ case CONT_EXPRESSION:
+ {
+ bExpressionCont* bexpcont = (bExpressionCont*) bcontr->data;
+ STR_String expressiontext = STR_String(bexpcont->str);
+ if (expressiontext.Length() > 0)
+ {
+ gamecontroller = new SCA_ExpressionController(gameobj,expressiontext);
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+
+ }
+ break;
+ }
+ case CONT_PYTHON:
+ {
+
+ // we should create a Python controller here
+
+ SCA_PythonController* pyctrl = new SCA_PythonController(gameobj);
+ gamecontroller = pyctrl;
+
+ bPythonCont* pycont = (bPythonCont*) bcontr->data;
+ pyctrl->SetDictionary(pythondictionary);
+
+ if (pycont->text)
+ {
+ char *buf;
+ // this is some blender specific code
+ buf= txt_to_buf(pycont->text);
+ if (buf)
+ {
+ pyctrl->SetScriptText(STR_String(buf));
+ pyctrl->SetScriptName(pycont->text->id.name+2);
+ MEM_freeN(buf);
+ }
+
+ }
+
+ LinkControllerToActuators(gamecontroller,bcontr,logicmgr,converter);
+ break;
+ }
+ default:
+ {
+
+ }
+ }
+
+ if (gamecontroller)
+ {
+ gamecontroller->SetExecutePriority(executePriority++);
+ STR_String uniquename = bcontr->name;
+ uniquename += "#CONTR#";
+ uniqueint++;
+ CIntValue* uniqueval = new CIntValue(uniqueint);
+ uniquename += uniqueval->GetText();
+ uniqueval->Release();
+ gamecontroller->SetName(uniquename);
+ gameobj->AddController(gamecontroller);
+
+ converter->RegisterGameController(gamecontroller, bcontr);
+ }
+
+ bcontr = bcontr->next;
+ }
+
+}
diff --git a/source/gameengine/Converter/KX_ConvertControllers.h b/source/gameengine/Converter/KX_ConvertControllers.h
new file mode 100644
index 00000000000..637780a7dbd
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertControllers.h
@@ -0,0 +1,51 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_CONVERTCONTROLLERS_H
+#define __KX_CONVERTCONTROLLERS_H
+
+#include "KX_Python.h"
+
+void BL_ConvertControllers(
+ struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ class SCA_LogicManager* logicmgr,
+ PyObject* pythondictionary,
+ int & executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ class KX_BlenderSceneConverter* converter
+);
+
+
+
+
+#endif //__KX_CONVERTCONTROLLERS_H
diff --git a/source/gameengine/Converter/KX_ConvertProperties.cpp b/source/gameengine/Converter/KX_ConvertProperties.cpp
new file mode 100644
index 00000000000..e3cbadc5808
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertProperties.cpp
@@ -0,0 +1,134 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "KX_ConvertProperties.h"
+
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_property_types.h"
+/* end of blender include block */
+
+#include "Value.h"
+#include "VectorValue.h"
+#include "BoolValue.h"
+#include "StringValue.h"
+#include "FloatValue.h"
+#include "KX_GameObject.h"
+//#include "ListValue.h"
+#include "IntValue.h"
+#include "SCA_TimeEventManager.h"
+#include "SCA_IScene.h"
+
+
+void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer)
+{
+
+ bProperty* prop = (bProperty*)object->prop.first;
+ CValue* propval;
+ bool show_debug_info;
+ while(prop)
+ {
+
+ propval = NULL;
+ show_debug_info = bool (prop->flag & PROP_DEBUG);
+
+ switch(prop->type) {
+ case PROP_BOOL:
+ {
+ propval = new CBoolValue((bool)(prop->data != 0));
+ gameobj->SetProperty(prop->name,propval);
+ //promp->poin= &prop->data;
+ break;
+ }
+ case PROP_INT:
+ {
+ propval = new CIntValue((int)prop->data);
+ gameobj->SetProperty(prop->name,propval);
+ break;
+ }
+ case PROP_FLOAT:
+ {
+ //prop->poin= &prop->data;
+ float floatprop = *((float*)&prop->data);
+ propval = new CFloatValue(floatprop);
+ gameobj->SetProperty(prop->name,propval);
+ }
+ break;
+ case PROP_STRING:
+ {
+ //prop->poin= callocN(MAX_PROPSTRING, "property string");
+ propval = new CStringValue((char*)prop->poin,"");
+ gameobj->SetProperty(prop->name,propval);
+ break;
+ }
+ case PROP_TIME:
+ {
+ float floatprop = *((float*)&prop->data);
+
+ CValue* timeval = new CFloatValue(floatprop);
+ // set a subproperty called 'timer' so that
+ // we can register the replica of this property
+ // at the time a game object is replicated (AddObjectActuator triggers this)
+
+ timeval->SetProperty("timer",new CBoolValue(true));
+ if (isInActiveLayer)
+ {
+ timemgr->AddTimeProperty(timeval);
+ }
+
+ propval = timeval;
+ gameobj->SetProperty(prop->name,timeval);
+
+ }
+ default:
+ {
+ // todo make an assert etc.
+ }
+ }
+
+ if (propval)
+ {
+ if (show_debug_info)
+ {
+ scene->AddDebugProperty(gameobj,STR_String(prop->name));
+ }
+ }
+
+ prop = prop->next;
+ }
+
+
+}
diff --git a/source/gameengine/Converter/KX_ConvertProperties.h b/source/gameengine/Converter/KX_ConvertProperties.h
new file mode 100644
index 00000000000..7360baa2e47
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertProperties.h
@@ -0,0 +1,41 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_CONVERTPROPERTIES
+#define __KX_CONVERTPROPERTIES
+
+void BL_ConvertProperties(struct Object* object,
+ class KX_GameObject* gameobj,
+ class SCA_TimeEventManager* timemgr,
+ class SCA_IScene* scene,
+ bool isInActiveLayer);
+
+#endif //__KX_CONVERTPROPERTIES
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
new file mode 100644
index 00000000000..42be5354d20
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -0,0 +1,658 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * Conversion of Blender data blocks to KX sensor system
+ */
+
+#ifdef WIN32
+#pragma warning (disable : 4786)
+#endif //WIN32
+
+#include "KX_BlenderSceneConverter.h"
+#include "KX_ConvertSensors.h"
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+#include "DNA_sensor_types.h"
+#include "DNA_actuator_types.h" /* for SENS_ALL_KEYS ? this define is
+probably misplaced */
+/* end of blender include block */
+
+#include "RAS_IPolygonMaterial.h"
+// Sensors
+#include "KX_GameObject.h"
+#include "RAS_MeshObject.h"
+#include "SCA_KeyboardSensor.h"
+#include "SCA_MouseSensor.h"
+#include "SCA_AlwaysSensor.h"
+#include "KX_TouchSensor.h"
+#include "KX_NearSensor.h"
+#include "KX_RadarSensor.h"
+#include "KX_MouseFocusSensor.h"
+
+#include "KX_NetworkMessageSensor.h"
+
+#include "SCA_PropertySensor.h"
+#include "SCA_RandomSensor.h"
+#include "KX_RaySensor.h"
+#include "SCA_EventManager.h"
+#include "SCA_LogicManager.h"
+#include "KX_BlenderInputDevice.h"
+#include "KX_Scene.h"
+#include "IntValue.h"
+#include "KX_BlenderKeyboardDevice.h"
+#include "KX_BlenderGL.h"
+#include "RAS_ICanvas.h"
+
+#include "KX_KetsjiEngine.h"
+#include "KX_BlenderSceneConverter.h"
+
+// this map is Blender specific: a conversion between blender and ketsji enums
+std::map<int,SCA_IInputDevice::KX_EnumInputs> gReverseKeyTranslateTable;
+
+
+void BL_ConvertSensors(struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ SCA_LogicManager* logicmgr,
+ KX_Scene* kxscene,
+ SCA_IInputDevice* keydev,
+ int & executePriority,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ RAS_ICanvas* canvas,
+ KX_BlenderSceneConverter* converter
+ )
+{
+
+
+
+ /* The reverse table. In order to not confuse ourselves, we */
+ /* immediately convert all events that come in to KX codes. */
+ gReverseKeyTranslateTable[LEFTMOUSE ] = SCA_IInputDevice::KX_LEFTMOUSE;
+ gReverseKeyTranslateTable[MIDDLEMOUSE ] = SCA_IInputDevice::KX_MIDDLEMOUSE;
+ gReverseKeyTranslateTable[RIGHTMOUSE ] = SCA_IInputDevice::KX_RIGHTMOUSE;
+ gReverseKeyTranslateTable[MOUSEX ] = SCA_IInputDevice::KX_MOUSEX;
+ gReverseKeyTranslateTable[MOUSEY ] = SCA_IInputDevice::KX_MOUSEY;
+
+ // TIMERS
+
+ gReverseKeyTranslateTable[TIMER0 ] = SCA_IInputDevice::KX_TIMER0;
+ gReverseKeyTranslateTable[TIMER1 ] = SCA_IInputDevice::KX_TIMER1;
+ gReverseKeyTranslateTable[TIMER2 ] = SCA_IInputDevice::KX_TIMER2;
+ gReverseKeyTranslateTable[TIMER3 ] = SCA_IInputDevice::KX_TIMER3;
+
+ // SYSTEM
+
+ gReverseKeyTranslateTable[KEYBD ] = SCA_IInputDevice::KX_KEYBD;
+ gReverseKeyTranslateTable[RAWKEYBD ] = SCA_IInputDevice::KX_RAWKEYBD;
+ gReverseKeyTranslateTable[REDRAW ] = SCA_IInputDevice::KX_REDRAW;
+ gReverseKeyTranslateTable[INPUTCHANGE ] = SCA_IInputDevice::KX_INPUTCHANGE;
+ gReverseKeyTranslateTable[QFULL ] = SCA_IInputDevice::KX_QFULL;
+ gReverseKeyTranslateTable[WINFREEZE ] = SCA_IInputDevice::KX_WINFREEZE;
+ gReverseKeyTranslateTable[WINTHAW ] = SCA_IInputDevice::KX_WINTHAW;
+ gReverseKeyTranslateTable[WINCLOSE ] = SCA_IInputDevice::KX_WINCLOSE;
+ gReverseKeyTranslateTable[WINQUIT ] = SCA_IInputDevice::KX_WINQUIT;
+ gReverseKeyTranslateTable[Q_FIRSTTIME ] = SCA_IInputDevice::KX_Q_FIRSTTIME;
+
+ // standard keyboard
+
+ gReverseKeyTranslateTable[AKEY ] = SCA_IInputDevice::KX_AKEY;
+ gReverseKeyTranslateTable[BKEY ] = SCA_IInputDevice::KX_BKEY;
+ gReverseKeyTranslateTable[CKEY ] = SCA_IInputDevice::KX_CKEY;
+ gReverseKeyTranslateTable[DKEY ] = SCA_IInputDevice::KX_DKEY;
+ gReverseKeyTranslateTable[EKEY ] = SCA_IInputDevice::KX_EKEY;
+ gReverseKeyTranslateTable[FKEY ] = SCA_IInputDevice::KX_FKEY;
+ gReverseKeyTranslateTable[GKEY ] = SCA_IInputDevice::KX_GKEY;
+ gReverseKeyTranslateTable[HKEY ] = SCA_IInputDevice::KX_HKEY;
+ gReverseKeyTranslateTable[IKEY ] = SCA_IInputDevice::KX_IKEY;
+ gReverseKeyTranslateTable[JKEY ] = SCA_IInputDevice::KX_JKEY;
+ gReverseKeyTranslateTable[KKEY ] = SCA_IInputDevice::KX_KKEY;
+ gReverseKeyTranslateTable[LKEY ] = SCA_IInputDevice::KX_LKEY;
+ gReverseKeyTranslateTable[MKEY ] = SCA_IInputDevice::KX_MKEY;
+ gReverseKeyTranslateTable[NKEY ] = SCA_IInputDevice::KX_NKEY;
+ gReverseKeyTranslateTable[OKEY ] = SCA_IInputDevice::KX_OKEY;
+ gReverseKeyTranslateTable[PKEY ] = SCA_IInputDevice::KX_PKEY;
+ gReverseKeyTranslateTable[QKEY ] = SCA_IInputDevice::KX_QKEY;
+ gReverseKeyTranslateTable[RKEY ] = SCA_IInputDevice::KX_RKEY;
+ gReverseKeyTranslateTable[SKEY ] = SCA_IInputDevice::KX_SKEY;
+ gReverseKeyTranslateTable[TKEY ] = SCA_IInputDevice::KX_TKEY;
+ gReverseKeyTranslateTable[UKEY ] = SCA_IInputDevice::KX_UKEY;
+ gReverseKeyTranslateTable[VKEY ] = SCA_IInputDevice::KX_VKEY;
+ gReverseKeyTranslateTable[WKEY ] = SCA_IInputDevice::KX_WKEY;
+ gReverseKeyTranslateTable[XKEY ] = SCA_IInputDevice::KX_XKEY;
+ gReverseKeyTranslateTable[YKEY ] = SCA_IInputDevice::KX_YKEY;
+ gReverseKeyTranslateTable[ZKEY ] = SCA_IInputDevice::KX_ZKEY;
+
+ gReverseKeyTranslateTable[ZEROKEY ] = SCA_IInputDevice::KX_ZEROKEY;
+ gReverseKeyTranslateTable[ONEKEY ] = SCA_IInputDevice::KX_ONEKEY;
+ gReverseKeyTranslateTable[TWOKEY ] = SCA_IInputDevice::KX_TWOKEY;
+ gReverseKeyTranslateTable[THREEKEY ] = SCA_IInputDevice::KX_THREEKEY;
+ gReverseKeyTranslateTable[FOURKEY ] = SCA_IInputDevice::KX_FOURKEY;
+ gReverseKeyTranslateTable[FIVEKEY ] = SCA_IInputDevice::KX_FIVEKEY;
+ gReverseKeyTranslateTable[SIXKEY ] = SCA_IInputDevice::KX_SIXKEY;
+ gReverseKeyTranslateTable[SEVENKEY ] = SCA_IInputDevice::KX_SEVENKEY;
+ gReverseKeyTranslateTable[EIGHTKEY ] = SCA_IInputDevice::KX_EIGHTKEY;
+ gReverseKeyTranslateTable[NINEKEY ] = SCA_IInputDevice::KX_NINEKEY;
+
+ gReverseKeyTranslateTable[CAPSLOCKKEY ] = SCA_IInputDevice::KX_CAPSLOCKKEY;
+
+ gReverseKeyTranslateTable[LEFTCTRLKEY ] = SCA_IInputDevice::KX_LEFTCTRLKEY;
+ gReverseKeyTranslateTable[LEFTALTKEY ] = SCA_IInputDevice::KX_LEFTALTKEY;
+ gReverseKeyTranslateTable[RIGHTALTKEY ] = SCA_IInputDevice::KX_RIGHTALTKEY;
+ gReverseKeyTranslateTable[RIGHTCTRLKEY ] = SCA_IInputDevice::KX_RIGHTCTRLKEY;
+ gReverseKeyTranslateTable[RIGHTSHIFTKEY ] = SCA_IInputDevice::KX_RIGHTSHIFTKEY;
+ gReverseKeyTranslateTable[LEFTSHIFTKEY ] = SCA_IInputDevice::KX_LEFTSHIFTKEY;
+
+ gReverseKeyTranslateTable[ESCKEY ] = SCA_IInputDevice::KX_ESCKEY;
+ gReverseKeyTranslateTable[TABKEY ] = SCA_IInputDevice::KX_TABKEY;
+ gReverseKeyTranslateTable[RETKEY ] = SCA_IInputDevice::KX_RETKEY;
+ gReverseKeyTranslateTable[SPACEKEY ] = SCA_IInputDevice::KX_SPACEKEY;
+ gReverseKeyTranslateTable[LINEFEEDKEY ] = SCA_IInputDevice::KX_LINEFEEDKEY;
+ gReverseKeyTranslateTable[BACKSPACEKEY ] = SCA_IInputDevice::KX_BACKSPACEKEY;
+ gReverseKeyTranslateTable[DELKEY ] = SCA_IInputDevice::KX_DELKEY;
+ gReverseKeyTranslateTable[SEMICOLONKEY ] = SCA_IInputDevice::KX_SEMICOLONKEY;
+ gReverseKeyTranslateTable[PERIODKEY ] = SCA_IInputDevice::KX_PERIODKEY;
+ gReverseKeyTranslateTable[COMMAKEY ] = SCA_IInputDevice::KX_COMMAKEY;
+ gReverseKeyTranslateTable[QUOTEKEY ] = SCA_IInputDevice::KX_QUOTEKEY;
+ gReverseKeyTranslateTable[ACCENTGRAVEKEY ] = SCA_IInputDevice::KX_ACCENTGRAVEKEY;
+ gReverseKeyTranslateTable[MINUSKEY ] = SCA_IInputDevice::KX_MINUSKEY;
+ gReverseKeyTranslateTable[SLASHKEY ] = SCA_IInputDevice::KX_SLASHKEY;
+ gReverseKeyTranslateTable[BACKSLASHKEY ] = SCA_IInputDevice::KX_BACKSLASHKEY;
+ gReverseKeyTranslateTable[EQUALKEY ] = SCA_IInputDevice::KX_EQUALKEY;
+ gReverseKeyTranslateTable[LEFTBRACKETKEY ] = SCA_IInputDevice::KX_LEFTBRACKETKEY;
+ gReverseKeyTranslateTable[RIGHTBRACKETKEY ] = SCA_IInputDevice::KX_RIGHTBRACKETKEY;
+
+ gReverseKeyTranslateTable[LEFTARROWKEY ] = SCA_IInputDevice::KX_LEFTARROWKEY;
+ gReverseKeyTranslateTable[DOWNARROWKEY ] = SCA_IInputDevice::KX_DOWNARROWKEY;
+ gReverseKeyTranslateTable[RIGHTARROWKEY ] = SCA_IInputDevice::KX_RIGHTARROWKEY;
+ gReverseKeyTranslateTable[UPARROWKEY ] = SCA_IInputDevice::KX_UPARROWKEY;
+
+ gReverseKeyTranslateTable[PAD2 ] = SCA_IInputDevice::KX_PAD2;
+ gReverseKeyTranslateTable[PAD4 ] = SCA_IInputDevice::KX_PAD4;
+ gReverseKeyTranslateTable[PAD6 ] = SCA_IInputDevice::KX_PAD6;
+ gReverseKeyTranslateTable[PAD8 ] = SCA_IInputDevice::KX_PAD8;
+
+ gReverseKeyTranslateTable[PAD1 ] = SCA_IInputDevice::KX_PAD1;
+ gReverseKeyTranslateTable[PAD3 ] = SCA_IInputDevice::KX_PAD3;
+ gReverseKeyTranslateTable[PAD5 ] = SCA_IInputDevice::KX_PAD5;
+ gReverseKeyTranslateTable[PAD7 ] = SCA_IInputDevice::KX_PAD7;
+ gReverseKeyTranslateTable[PAD9 ] = SCA_IInputDevice::KX_PAD9;
+
+ gReverseKeyTranslateTable[PADPERIOD ] = SCA_IInputDevice::KX_PADPERIOD;
+ gReverseKeyTranslateTable[PADSLASHKEY ] = SCA_IInputDevice::KX_PADSLASHKEY;
+ gReverseKeyTranslateTable[PADASTERKEY ] = SCA_IInputDevice::KX_PADASTERKEY;
+
+ gReverseKeyTranslateTable[PAD0 ] = SCA_IInputDevice::KX_PAD0;
+ gReverseKeyTranslateTable[PADMINUS ] = SCA_IInputDevice::KX_PADMINUS;
+ gReverseKeyTranslateTable[PADENTER ] = SCA_IInputDevice::KX_PADENTER;
+ gReverseKeyTranslateTable[PADPLUSKEY ] = SCA_IInputDevice::KX_PADPLUSKEY;
+
+
+ gReverseKeyTranslateTable[F1KEY ] = SCA_IInputDevice::KX_F1KEY;
+ gReverseKeyTranslateTable[F2KEY ] = SCA_IInputDevice::KX_F2KEY;
+ gReverseKeyTranslateTable[F3KEY ] = SCA_IInputDevice::KX_F3KEY;
+ gReverseKeyTranslateTable[F4KEY ] = SCA_IInputDevice::KX_F4KEY;
+ gReverseKeyTranslateTable[F5KEY ] = SCA_IInputDevice::KX_F5KEY;
+ gReverseKeyTranslateTable[F6KEY ] = SCA_IInputDevice::KX_F6KEY;
+ gReverseKeyTranslateTable[F7KEY ] = SCA_IInputDevice::KX_F7KEY;
+ gReverseKeyTranslateTable[F8KEY ] = SCA_IInputDevice::KX_F8KEY;
+ gReverseKeyTranslateTable[F9KEY ] = SCA_IInputDevice::KX_F9KEY;
+ gReverseKeyTranslateTable[F10KEY ] = SCA_IInputDevice::KX_F10KEY;
+ gReverseKeyTranslateTable[F11KEY ] = SCA_IInputDevice::KX_F11KEY;
+ gReverseKeyTranslateTable[F12KEY ] = SCA_IInputDevice::KX_F12KEY;
+
+ gReverseKeyTranslateTable[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY;
+ gReverseKeyTranslateTable[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY;
+ gReverseKeyTranslateTable[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY;
+ gReverseKeyTranslateTable[PAGEUPKEY ] = SCA_IInputDevice::KX_PAGEUPKEY;
+ gReverseKeyTranslateTable[PAGEDOWNKEY ] = SCA_IInputDevice::KX_PAGEDOWNKEY;
+ gReverseKeyTranslateTable[ENDKEY ] = SCA_IInputDevice::KX_ENDKEY;
+
+ int uniqueint = 0;
+ bSensor* sens = (bSensor*)blenderobject->sensors.first;
+ bool pos_pulsemode = false;
+ bool neg_pulsemode = false;
+ int frequency = 0;
+ bool invert = false;
+
+ while(sens)
+ {
+ SCA_ISensor* gamesensor=NULL;
+ /* All sensors have a pulse toggle, frequency, and invert field. */
+ /* These are extracted here, and set when the sensor is added to the */
+ /* list. */
+ pos_pulsemode = (sens->pulse & SENS_PULSE_REPEAT)!=0;
+ neg_pulsemode = (sens->pulse & SENS_NEG_PULSE_MODE)!=0;
+
+ frequency = sens->freq;
+ invert = !(sens->invert == 0);
+
+ switch (sens->type)
+ {
+ case SENS_ALWAYS:
+ {
+
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::ALWAYS_EVENTMGR);
+ if (eventmgr)
+ {
+ gamesensor = new SCA_AlwaysSensor(eventmgr, gameobj);
+ }
+
+ break;
+ }
+
+ case SENS_COLLISION:
+ {
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ // collision sensor can sense both materials and properties.
+
+ bool bFindMaterial = false;
+
+ bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
+
+ bFindMaterial = (blendertouchsensor->mode
+ & SENS_COLLISION_MATERIAL);
+
+
+ STR_String touchPropOrMatName = ( bFindMaterial ?
+ blendertouchsensor->materialName:
+ (blendertouchsensor->name ? blendertouchsensor->name: ""));
+
+
+ //if (gameobj->GetSumoObject())
+ //{
+ // gamesensor = 0;
+ //new KX_TouchSensor(eventmgr,
+ //gameobj,
+ //gameobj->GetSumoObject(),
+ //bFindMaterial,
+ //touchPropOrMatName);
+ //}
+
+ }
+
+ break;
+ }
+ case SENS_TOUCH:
+ {
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String touchpropertyname;
+ bTouchSensor* blendertouchsensor = (bTouchSensor*)sens->data;
+
+ if (blendertouchsensor->ma)
+ {
+ touchpropertyname = (char*) (blendertouchsensor->ma->id.name+2);
+ }
+ bool bFindMaterial = true;
+ //if (gameobj->GetSumoObject())
+ //{
+ // gamesensor = 0;
+ //new KX_TouchSensor(eventmgr,
+ // gameobj,
+ // gameobj->GetSumoObject(),
+ // bFindMaterial,
+ // touchpropertyname);
+ //}
+ }
+ break;
+ }
+ case SENS_MESSAGE:
+ {
+ KX_NetworkEventManager* eventmgr = (KX_NetworkEventManager*)
+ logicmgr->FindEventManager(SCA_EventManager::NETWORK_EVENTMGR);
+ if (eventmgr) {
+ bMessageSensor* msgSens = (bMessageSensor*) sens->data;
+
+ /* Get our NetworkScene */
+ NG_NetworkScene *NetworkScene = kxscene->GetNetworkScene();
+ /* filter on the incoming subjects, might be empty */
+ STR_String subject = (msgSens->subject
+ ? (char*)msgSens->subject
+ : "");
+
+ gamesensor = new KX_NetworkMessageSensor(
+ eventmgr, // our eventmanager
+ NetworkScene, // our NetworkScene
+ gameobj, // the sensor controlling object
+ subject); // subject to filter on
+ }
+ break;
+ }
+ case SENS_NEAR:
+ {
+
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String nearpropertyname;
+ bNearSensor* blendernearsensor = (bNearSensor*)sens->data;
+ if (blendernearsensor->name)
+ {
+ // only objects that own this property will be taken into account
+ nearpropertyname = (char*) blendernearsensor->name;
+ }
+
+ //DT_ShapeHandle shape = DT_Sphere(0.0);
+
+ // this sumoObject is not deleted by a gameobj, so delete it ourself
+ // later (memleaks)!
+ //SM_Object* sumoObj = new SM_Object(shape,NULL,NULL,NULL);
+ //sumoObj->setMargin(blendernearsensor->dist);
+ //sumoObj->setPosition(gameobj->NodeGetWorldPosition());
+ bool bFindMaterial = false;
+ gamesensor = 0;//new KX_NearSensor(eventmgr,gameobj,blendernearsensor->dist,blendernearsensor->resetdist,bFindMaterial,nearpropertyname,kxscene);
+
+ }
+ break;
+ }
+
+
+ case SENS_KEYBOARD:
+ {
+ /* temporary input device, for converting the code for the keyboard sensor */
+
+ bKeyboardSensor* blenderkeybdsensor = (bKeyboardSensor*)sens->data;
+ SCA_KeyboardManager* eventmgr = (SCA_KeyboardManager*) logicmgr->FindEventManager(SCA_EventManager::KEYBOARD_EVENTMGR);
+ if (eventmgr)
+ {
+ gamesensor = new SCA_KeyboardSensor(eventmgr,
+ gReverseKeyTranslateTable[blenderkeybdsensor->key],
+ blenderkeybdsensor->qual,
+ blenderkeybdsensor->qual2,
+ (blenderkeybdsensor->type == SENS_ALL_KEYS),
+ blenderkeybdsensor->targetName,
+ blenderkeybdsensor->toggleName,
+ gameobj); // blenderkeybdsensor->pad);
+
+ }
+
+ break;
+ }
+ case SENS_MOUSE:
+ {
+ int keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_NODEF;
+ bool trackfocus = false;
+ bMouseSensor *bmouse = (bMouseSensor *)sens->data;
+
+ /* There are two main types of mouse sensors. If there is
+ * no focus-related behaviour requested, we can make do
+ * with a basic sensor. This cuts down memory usage and
+ * gives a slight performance gain. */
+
+ SCA_MouseManager *eventmgr
+ = (SCA_MouseManager*) logicmgr->FindEventManager(SCA_EventManager::MOUSE_EVENTMGR);
+ if (eventmgr) {
+
+ /* Determine key mode. There is at most one active mode. */
+ switch (bmouse->type) {
+ case BL_SENS_MOUSE_LEFT_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_LEFTBUTTON;
+ break;
+ case BL_SENS_MOUSE_MIDDLE_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MIDDLEBUTTON;
+ break;
+ case BL_SENS_MOUSE_RIGHT_BUTTON:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_RIGHTBUTTON;
+ break;
+ case BL_SENS_MOUSE_MOVEMENT:
+ keytype = SCA_MouseSensor::KX_MOUSESENSORMODE_MOVEMENT;
+ break;
+ case BL_SENS_MOUSE_MOUSEOVER:
+ trackfocus = true;
+ break;
+ default:
+ ; /* error */
+ }
+
+ /* initial mouse position */
+ int startx = canvas->GetWidth()/2;
+ int starty = canvas->GetHeight()/2;
+
+ if (!trackfocus) {
+ /* plain, simple mouse sensor */
+ gamesensor = new SCA_MouseSensor(eventmgr,
+ startx,starty,
+ keytype,
+ gameobj);
+ } else {
+ /* give us a focus-aware sensor */
+ gamesensor = new KX_MouseFocusSensor(eventmgr,
+ startx,
+ starty,
+ keytype,
+ trackfocus,
+ canvas,
+ kxscene,
+ gameobj);
+ }
+ } else {
+ // cout << "\n Could't find mouse event manager..."; - should throw an error here...
+ }
+ break;
+ }
+ case SENS_PROPERTY:
+ {
+ bPropertySensor* blenderpropsensor = (bPropertySensor*) sens->data;
+ SCA_EventManager* eventmgr
+ = logicmgr->FindEventManager(SCA_EventManager::PROPERTY_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String propname=blenderpropsensor->name;
+ STR_String propval=blenderpropsensor->value;
+ STR_String propmaxval=blenderpropsensor->maxvalue;
+
+ SCA_PropertySensor::KX_PROPSENSOR_TYPE
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NODEF;
+
+ /* Better do an explicit conversion here! (was implicit */
+ /* before...) */
+ switch(blenderpropsensor->type) {
+ case SENS_PROP_EQUAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EQUAL;
+ break;
+ case SENS_PROP_NEQUAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL;
+ break;
+ case SENS_PROP_INTERVAL:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_INTERVAL;
+ break;
+ case SENS_PROP_CHANGED:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_CHANGED;
+ break;
+ case SENS_PROP_EXPRESSION:
+ propchecktype = SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION;
+ /* error */
+ break;
+ default:
+ ; /* error */
+ }
+ gamesensor = new SCA_PropertySensor(eventmgr,gameobj,propname,propval,propmaxval,propchecktype);
+ }
+
+ break;
+ }
+
+ case SENS_RADAR:
+ {
+ /*
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::TOUCH_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String radarpropertyname;
+ STR_String touchpropertyname;
+ bRadarSensor* blenderradarsensor = (bRadarSensor*) sens->data;
+
+ int radaraxis = blenderradarsensor->axis;
+
+ if (blenderradarsensor->name)
+ {
+ // only objects that own this property will be taken into account
+ radarpropertyname = (char*) blenderradarsensor->name;
+ }
+
+ MT_Scalar coneheight = blenderradarsensor->range;
+
+ // janco: the angle was doubled, so should I divide the factor in 2
+ // or the blenderradarsensor->angle?
+ // nzc: the angle is the opening angle. We need to init with
+ // the axis-hull angle,so /2.0.
+ MT_Scalar factor = tan(MT_radians((blenderradarsensor->angle)/2.0));
+ //MT_Scalar coneradius = coneheight * (factor / 2);
+ MT_Scalar coneradius = coneheight * factor;
+
+ DT_ShapeHandle shape = DT_Cone(coneradius,coneheight);
+
+ // this sumoObject is not deleted by a gameobj, so delete it ourself
+ // later (memleaks)!
+ SM_Object* sumoObj = new SM_Object(shape,NULL,NULL,NULL);
+ sumoObj->setMargin(0.0);
+
+ sumoObj->setPosition(gameobj->NodeGetWorldPosition());
+ MT_Scalar smallmargin = 0.0;
+ MT_Scalar largemargin = 0.1;
+
+ bool bFindMaterial = false;
+ gamesensor = new KX_RadarSensor(
+ eventmgr,
+ gameobj,
+ coneradius,
+ coneheight,
+ radaraxis,
+ smallmargin,
+ largemargin,
+ sumoObj,
+ bFindMaterial,
+ radarpropertyname,
+ kxscene);
+
+ }
+ */
+ break;
+ }
+ case SENS_RAY:
+ {
+ bRaySensor* blenderraysensor = (bRaySensor*) sens->data;
+
+ //blenderradarsensor->angle;
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RAY_EVENTMGR);
+ if (eventmgr)
+ {
+ bool bFindMaterial = (blenderraysensor->mode & SENS_COLLISION_MATERIAL);
+
+ STR_String checkname = (bFindMaterial? blenderraysensor->matname : blenderraysensor->propname);
+
+ // don't want to get rays of length 0.0 or so
+ double distance = (blenderraysensor->range < 0.01 ? 0.01 : blenderraysensor->range );
+ int axis = blenderraysensor->axisflag;
+
+
+ gamesensor = 0;
+ /*new KX_RaySensor(eventmgr,
+ gameobj,
+ checkname,
+ bFindMaterial,
+ distance,
+ axis,
+ kxscene->GetSumoScene());
+ */
+
+ }
+ break;
+ }
+
+ case SENS_RANDOM:
+ {
+ bRandomSensor* blenderrndsensor = (bRandomSensor*) sens->data;
+ // some files didn't write randomsensor, avoid crash now for NULL ptr's
+ if (blenderrndsensor)
+ {
+ SCA_EventManager* eventmgr = logicmgr->FindEventManager(SCA_EventManager::RANDOM_EVENTMGR);
+ if (eventmgr)
+ {
+ int randomSeed = blenderrndsensor->seed;
+ gamesensor = new SCA_RandomSensor(eventmgr, gameobj, randomSeed);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ }
+ }
+
+ if (gamesensor)
+ {
+ gamesensor->SetExecutePriority(executePriority++);
+ STR_String uniquename = sens->name;
+ uniquename += "#SENS#";
+ uniqueint++;
+ CIntValue* uniqueval = new CIntValue(uniqueint);
+ uniquename += uniqueval->GetText();
+ uniqueval->Release();
+
+ /* Conversion succeeded, so we can set the generic props here. */
+ gamesensor->SetPulseMode(pos_pulsemode,
+ neg_pulsemode,
+ frequency);
+ gamesensor->SetInvert(invert);
+ gamesensor->SetName(STR_String(sens->name));
+
+ gameobj->AddSensor(gamesensor);
+
+ // only register to manager if it's in an active layer
+
+ if (isInActiveLayer)
+ gamesensor->RegisterToManager();
+
+
+ for (int i=0;i<sens->totlinks;i++)
+ {
+ bController* linkedcont = (bController*) sens->links[i];
+ SCA_IController* gamecont = converter->FindGameController(linkedcont);
+
+ if (gamecont) {
+ logicmgr->RegisterToSensor(gamecont,gamesensor);
+ }
+ }
+
+ }
+ sens=sens->next;
+ }
+}
+
diff --git a/source/gameengine/Converter/KX_ConvertSensors.h b/source/gameengine/Converter/KX_ConvertSensors.h
new file mode 100644
index 00000000000..ed7dccf87a9
--- /dev/null
+++ b/source/gameengine/Converter/KX_ConvertSensors.h
@@ -0,0 +1,47 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_CONVERTSENSOR_H
+#define __KX_CONVERTSENSOR_H
+
+void BL_ConvertSensors(struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ class SCA_LogicManager* logicmgr,
+ class KX_Scene* kxscene,
+ class SCA_IInputDevice* keydev,
+ int & executePriority ,
+ int activeLayerBitInfo,
+ bool isInActiveLayer,
+ class RAS_ICanvas* canvas,
+ class KX_BlenderSceneConverter* converter);
+
+
+#endif //__KX_CONVERTSENSOR_H
diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp
new file mode 100644
index 00000000000..46c9ef0ef13
--- /dev/null
+++ b/source/gameengine/Converter/KX_IpoConvert.cpp
@@ -0,0 +1,559 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifdef WIN32
+
+// don't show stl-warnings
+#pragma warning (disable:4786)
+#endif
+
+
+#include "KX_GameObject.h"
+#include "KX_IpoConvert.h"
+#include "KX_IInterpolator.h"
+#include "KX_ScalarInterpolator.h"
+
+#include "KX_BlenderScalarInterpolator.h"
+#include "KX_BlenderSceneConverter.h"
+
+
+/* This little block needed for linking to Blender... */
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_object_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_world_types.h"
+#include "DNA_camera_types.h"
+/* end of blender include block */
+
+#include "KX_IPO_SGController.h"
+#include "KX_LightIpoSGController.h"
+#include "KX_CameraIpoSGController.h"
+#include "KX_WorldIpoController.h"
+#include "KX_ObColorIpoSGController.h"
+
+#include "SG_Node.h"
+
+static BL_InterpolatorList *GetIpoList(struct Ipo *for_ipo, KX_BlenderSceneConverter *converter) {
+ BL_InterpolatorList *ipoList= converter->FindInterpolatorList(for_ipo);
+
+ if (!ipoList) {
+ ipoList = new BL_InterpolatorList(for_ipo);
+ converter->RegisterInterpolatorList(ipoList, for_ipo);
+ }
+
+ return ipoList;
+}
+
+void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_BlenderSceneConverter *converter)
+{
+ if (blenderobject->ipo) {
+
+ KX_IpoSGController* ipocontr = new KX_IpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+
+ // For ipo_as_force, we need to know which SM object and Scene the
+ // object associated with this ipo is in. Is this already known here?
+ // I think not.... then it must be done later :(
+// ipocontr->SetSumoReference(gameobj->GetSumoScene(),
+// gameobj->GetSumoObject());
+
+ ipocontr->SetGameObject(gameobj);
+
+ ipocontr->GetIPOTransform().SetPosition(
+ MT_Point3(
+ blenderobject->loc[0]+blenderobject->dloc[0],
+ blenderobject->loc[1]+blenderobject->dloc[1],
+ blenderobject->loc[2]+blenderobject->dloc[2]
+ )
+ );
+ ipocontr->GetIPOTransform().SetEulerAngles(
+ MT_Vector3(
+ blenderobject->rot[0],
+ blenderobject->rot[1],
+ blenderobject->rot[2]
+ )
+ );
+ ipocontr->GetIPOTransform().SetScaling(
+ MT_Vector3(
+ blenderobject->size[0],
+ blenderobject->size[1],
+ blenderobject->size[2]
+ )
+ );
+
+ BL_InterpolatorList *ipoList= GetIpoList(blenderobject->ipo, converter);
+
+ // For each active channel in the ipoList add an
+ // interpolator to the game object.
+
+ KX_IScalarInterpolator *ipo;
+
+ ipo = ipoList->GetScalarInterpolator(OB_LOC_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetPosition()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+
+ }
+
+ ipo = ipoList->GetScalarInterpolator(OB_LOC_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetPosition()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(OB_LOC_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetPosition()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ // Master the art of cut & paste programming...
+
+ ipo = ipoList->GetScalarInterpolator(OB_DLOC_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaPosition()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(OB_DLOC_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaPosition()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(OB_DLOC_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaPosition()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyPosition(true);
+ }
+
+ // Explore the finesse of reuse and slight modification
+
+ ipo = ipoList->GetScalarInterpolator(OB_ROT_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetEulerAngles()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_ROT_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetEulerAngles()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_ROT_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetEulerAngles()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+
+ // Hmmm, the need for a macro comes to mind...
+
+ ipo = ipoList->GetScalarInterpolator(OB_DROT_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_DROT_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_DROT_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyOrientation(true);
+ }
+
+ // Hang on, almost there...
+
+ ipo = ipoList->GetScalarInterpolator(OB_SIZE_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetScaling()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_SIZE_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetScaling()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_SIZE_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetScaling()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+
+ // The last few...
+
+ ipo = ipoList->GetScalarInterpolator(OB_DSIZE_X);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaScaling()[0]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_DSIZE_Y);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaScaling()[1]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_DSIZE_Z);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &(ipocontr->GetIPOTransform().GetDeltaScaling()[2]),
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyScaling(true);
+ }
+
+ {
+ KX_ObColorIpoSGController* ipocontr=NULL;
+
+ ipo = ipoList->GetScalarInterpolator(OB_COL_R);
+ if (ipo)
+ {
+ if (!ipocontr)
+ {
+ ipocontr = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &ipocontr->m_rgba[0],
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_COL_G);
+ if (ipo)
+ {
+ if (!ipocontr)
+ {
+ ipocontr = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &ipocontr->m_rgba[1],
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_COL_B);
+ if (ipo)
+ {
+ if (!ipocontr)
+ {
+ ipocontr = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &ipocontr->m_rgba[2],
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ }
+ ipo = ipoList->GetScalarInterpolator(OB_COL_A);
+ if (ipo)
+ {
+ if (!ipocontr)
+ {
+ ipocontr = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(
+ &ipocontr->m_rgba[3],
+ ipo);
+ ipocontr->AddInterpolator(interpolator);
+ }
+ }
+
+
+ }
+
+
+}
+
+void BL_ConvertLampIpos(struct Lamp* blenderlamp, KX_GameObject *lightobj,KX_BlenderSceneConverter *converter)
+{
+
+ if (blenderlamp->ipo) {
+
+ KX_LightIpoSGController* ipocontr = new KX_LightIpoSGController();
+ lightobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(lightobj->GetSGNode());
+
+ ipocontr->m_energy = blenderlamp->energy;
+ ipocontr->m_col_rgb[0] = blenderlamp->r;
+ ipocontr->m_col_rgb[1] = blenderlamp->g;
+ ipocontr->m_col_rgb[2] = blenderlamp->b;
+ ipocontr->m_dist = blenderlamp->dist;
+
+ BL_InterpolatorList *ipoList= GetIpoList(blenderlamp->ipo, converter);
+
+ // For each active channel in the ipoList add an
+ // interpolator to the game object.
+
+ KX_IScalarInterpolator *ipo;
+
+ ipo = ipoList->GetScalarInterpolator(LA_ENERGY);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_energy, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyEnergy(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(LA_DIST);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_dist, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyDist(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(LA_COL_R);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_col_rgb[0], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(LA_COL_G);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_col_rgb[1], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(LA_COL_B);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_col_rgb[2], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyColor(true);
+ }
+ }
+}
+
+
+
+
+void BL_ConvertCameraIpos(struct Camera* blendercamera, KX_GameObject *cameraobj,KX_BlenderSceneConverter *converter)
+{
+
+ if (blendercamera->ipo) {
+
+ KX_CameraIpoSGController* ipocontr = new KX_CameraIpoSGController();
+ cameraobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(cameraobj->GetSGNode());
+
+ ipocontr->m_lens = blendercamera->lens;
+ ipocontr->m_clipstart = blendercamera->clipsta;
+ ipocontr->m_clipend = blendercamera->clipend;
+
+ BL_InterpolatorList *ipoList= GetIpoList(blendercamera->ipo, converter);
+
+ // For each active channel in the ipoList add an
+ // interpolator to the game object.
+
+ KX_IScalarInterpolator *ipo;
+
+ ipo = ipoList->GetScalarInterpolator(CAM_LENS);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_lens, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyLens(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(CAM_STA);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_clipstart, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyClipStart(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(CAM_END);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_clipend, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyClipEnd(true);
+ }
+
+ }
+}
+
+
+void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *converter)
+{
+
+ if (blenderworld->ipo) {
+
+ KX_WorldIpoController* ipocontr = new KX_WorldIpoController();
+
+// Erwin, hook up the world ipo controller here
+// Gino: hook it up to what ?
+// is there a userinterface element for that ?
+// for now, we have some new python hooks to access the data, for a work-around
+
+ ipocontr->m_mist_start = blenderworld->miststa;
+ ipocontr->m_mist_dist = blenderworld->mistdist;
+ ipocontr->m_mist_rgb[0] = blenderworld->horr;
+ ipocontr->m_mist_rgb[1] = blenderworld->horg;
+ ipocontr->m_mist_rgb[2] = blenderworld->horb;
+
+ BL_InterpolatorList *ipoList= GetIpoList(blenderworld->ipo, converter);
+
+ // For each active channel in the ipoList add an
+ // interpolator to the game object.
+
+ KX_IScalarInterpolator *ipo;
+
+ ipo = ipoList->GetScalarInterpolator(WO_HOR_R);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[0], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(WO_HOR_G);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[1], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(WO_HOR_B);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_rgb[2], ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistColor(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(WO_MISTDI);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_dist, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistDist(true);
+ }
+
+ ipo = ipoList->GetScalarInterpolator(WO_MISTSTA);
+ if (ipo) {
+ KX_IInterpolator *interpolator =
+ new KX_ScalarInterpolator(&ipocontr->m_mist_start, ipo);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetModifyMistStart(true);
+ }
+ }
+}
+
diff --git a/source/gameengine/Converter/KX_IpoConvert.h b/source/gameengine/Converter/KX_IpoConvert.h
new file mode 100644
index 00000000000..5686ca866eb
--- /dev/null
+++ b/source/gameengine/Converter/KX_IpoConvert.h
@@ -0,0 +1,54 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_IPOCONVERT_H
+#define __KX_IPOCONVERT_H
+
+struct Object;
+
+void BL_ConvertIpos(struct Object* blenderobject,
+ class KX_GameObject* gameobj,
+ class KX_BlenderSceneConverter *converter
+ );
+
+void BL_ConvertLampIpos(struct Lamp* blenderlight,
+ class KX_GameObject* lightobj,
+ class KX_BlenderSceneConverter *converter);
+
+void BL_ConvertWorldIpos(struct World* blenderworld,
+ class KX_BlenderSceneConverter *converter);
+
+void BL_ConvertCameraIpos(struct Camera* blendercamera,
+ class KX_GameObject* cameraobj,
+ class KX_BlenderSceneConverter *converter);
+
+
+#endif //__KX_IPOCONVERT_H
diff --git a/source/gameengine/Converter/Makefile b/source/gameengine/Converter/Makefile
new file mode 100644
index 00000000000..8f85e4c1a58
--- /dev/null
+++ b/source/gameengine/Converter/Makefile
@@ -0,0 +1,60 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL 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. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = blconverter
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include
+CPPFLAGS += -I../../blender
+# these two needed because of blenkernel
+CPPFLAGS += -I../../blender/imbuf
+CPPFLAGS += -I../../blender/makesdna
+CPPFLAGS += -I../../blender/include
+CPPFLAGS += -I../../blender/blenlib
+CPPFLAGS += -I../../blender/blenkernel
+CPPFLAGS += -I../../blender/render/extern/include
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../Expressions -I../Rasterizer -I../GameLogic -I../SoundSystem
+CPPFLAGS += -I../Ketsji -I../BlenderRoutines -I../SceneGraph
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Rasterizer/RAS_OpenGLRasterizer
+CPPFLAGS += -I../Network -I../Ketsji/KXNetwork
+CPPFLAGS += -I../Physics/common -I../Physics/Dummy
+