diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /source/gameengine/Converter |
Initial revisionv2.25
Diffstat (limited to 'source/gameengine/Converter')
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 + |