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/Ketsji |
Initial revisionv2.25
Diffstat (limited to 'source/gameengine/Ketsji')
121 files changed, 20843 insertions, 0 deletions
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp new file mode 100644 index 00000000000..99aa798cfa5 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.cpp @@ -0,0 +1,92 @@ +/** + * $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 ***** + * Ketsji Logic Extenstion: Network Event Manager generic implementation + */ + +// Ketsji specific sensor part +#include "SCA_ISensor.h" + +// Ketsji specific network part +#include "KX_NetworkEventManager.h" + +// Network module specific +#include "NG_NetworkDeviceInterface.h" +#include "NG_NetworkMessage.h" +#include "NG_NetworkObject.h" + +KX_NetworkEventManager::KX_NetworkEventManager(class SCA_LogicManager* +logicmgr, class NG_NetworkDeviceInterface *ndi) : +SCA_EventManager(NETWORK_EVENTMGR), m_logicmgr(logicmgr), m_ndi(ndi) +{ + //printf("KX_NetworkEventManager constructor\n"); +} + +KX_NetworkEventManager::~KX_NetworkEventManager() +{ + //printf("KX_NetworkEventManager destructor\n"); +} + +void KX_NetworkEventManager::RegisterSensor(class SCA_ISensor* sensor) +{ + //printf("KX_NetworkEventManager RegisterSensor\n"); + m_sensors.push_back(sensor); +} + +void KX_NetworkEventManager::RemoveSensor(class SCA_ISensor* sensor) +{ + //printf("KX_NetworkEventManager RemoveSensor\n"); + // Network specific RemoveSensor stuff goes here + + // parent + SCA_EventManager::RemoveSensor(sensor); +} + +void KX_NetworkEventManager::NextFrame(double curtime, double deltatime) +{ +// printf("KX_NetworkEventManager::proceed %.2f - %.2f\n", curtime, deltatime); + // each frame, the logicmanager will call the network + // eventmanager to look for network events, and process it's + // 'network' sensors + vector<class SCA_ISensor*>::iterator it; + + for (it = m_sensors.begin(); !(it==m_sensors.end()); it++) { +// printf("KX_NetworkEventManager::proceed sensor %.2f\n", curtime); + // process queue + (*it)->Activate(m_logicmgr, NULL); + } + + // now a list of triggerer sensors has been built +} + +void KX_NetworkEventManager::EndFrame() +{ +} + diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h new file mode 100644 index 00000000000..521a3b4d030 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkEventManager.h @@ -0,0 +1,59 @@ +/** + * $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 ***** + * Ketsji Logic Extenstion: Network Event Manager class + */ +#ifndef KX_NETWORK_EVENTMANAGER_H +#define KX_NETWORK_EVENTMANAGER_H + +#include "SCA_EventManager.h" + +class KX_NetworkEventManager : public SCA_EventManager +{ + class SCA_LogicManager* m_logicmgr; + class NG_NetworkDeviceInterface* m_ndi; + +public: + KX_NetworkEventManager(class SCA_LogicManager* logicmgr, + class NG_NetworkDeviceInterface *ndi); + virtual ~KX_NetworkEventManager (); + + virtual void RegisterSensor(class SCA_ISensor* sensor); + virtual void RemoveSensor(class SCA_ISensor* sensor); + + virtual void NextFrame(double curtime, double deltatime); + virtual void EndFrame(); + + SCA_LogicManager* GetLogicManager() { return m_logicmgr; } + class NG_NetworkDeviceInterface* GetNetworkDevice() { + return m_ndi; } +}; + +#endif //KX_NETWORK_EVENTMANAGER_H diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp new file mode 100644 index 00000000000..1eb85d60b29 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp @@ -0,0 +1,208 @@ +/** + * $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 ***** + * Ketsji Logic Extenstion: Network Message Actuator generic implementation + */ + +#include "NG_NetworkScene.h" +#include "KX_NetworkMessageActuator.h" + +KX_NetworkMessageActuator::KX_NetworkMessageActuator( + SCA_IObject* gameobj, // the actuator controlling object + NG_NetworkScene* networkscene, // needed for replication + const STR_String &toPropName, + const STR_String &subject, + int bodyType, + const STR_String &body, + PyTypeObject* T) : + SCA_IActuator(gameobj,T), + m_networkscene(networkscene), + m_toPropName(toPropName), + m_subject(subject), + m_bodyType(bodyType), + m_body(body) +{ +} + +KX_NetworkMessageActuator::~KX_NetworkMessageActuator() +{ +} + +// returns true if the actuators needs to be running over several frames +bool KX_NetworkMessageActuator::Update(double curtime, double deltatime) +{ + //printf("update messageactuator\n"); + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) { + return false; // do nothing on negative events + //printf("messageactuator false event\n"); + } + //printf("messageactuator true event\n"); + + if (m_bodyType == 1) // ACT_MESG_PROP in DNA_actuator_types.h + { + m_networkscene->SendMessage( + m_toPropName, + GetParent()->GetName(), + m_subject, + GetParent()->GetPropertyText(m_body,"")); + } else + { + m_networkscene->SendMessage( + m_toPropName, + GetParent()->GetName(), + m_subject, + m_body); + } + return false; +} + +CValue* KX_NetworkMessageActuator::GetReplica() +{ + KX_NetworkMessageActuator* replica = + new KX_NetworkMessageActuator(*this); + replica->ProcessReplica(); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +} + +/* -------------------------------------------------------------------- */ +/* Python interface --------------------------------------------------- */ +/* -------------------------------------------------------------------- */ + +/* Integration hooks -------------------------------------------------- */ +PyTypeObject KX_NetworkMessageActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_NetworkMessageActuator", + sizeof(KX_NetworkMessageActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_NetworkMessageActuator::Parents[] = { + &KX_NetworkMessageActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_NetworkMessageActuator::Methods[] = { + {"setToPropName", (PyCFunction) + KX_NetworkMessageActuator::sPySetToPropName, METH_VARARGS}, + {"setSubject", (PyCFunction) + KX_NetworkMessageActuator::sPySetSubject, METH_VARARGS}, + {"setBodyType", (PyCFunction) + KX_NetworkMessageActuator::sPySetBodyType, METH_VARARGS}, + {"setBody", (PyCFunction) + KX_NetworkMessageActuator::sPySetBody, METH_VARARGS}, + {NULL,NULL} // Sentinel +}; + +PyObject* KX_NetworkMessageActuator::_getattr(char* attr) { + _getattr_up(SCA_IActuator); +} + +// 1. SetToPropName +PyObject* KX_NetworkMessageActuator::PySetToPropName( + PyObject* self, + PyObject* args, + PyObject* kwds) +{ + char* ToPropName; + + if (PyArg_ParseTuple(args, "s", &ToPropName)) { + m_toPropName = ToPropName; + } + + Py_Return; +} + +// 2. SetSubject +PyObject* KX_NetworkMessageActuator::PySetSubject( + PyObject* self, + PyObject* args, + PyObject* kwds) +{ + char* Subject; + + if (PyArg_ParseTuple(args, "s", &Subject)) { + m_subject = Subject; + } + + Py_Return; +} + +// 3. SetBodyType +PyObject* KX_NetworkMessageActuator::PySetBodyType( + PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int BodyType; + + if (PyArg_ParseTuple(args, "i", &BodyType)) { + m_bodyType = BodyType; + } + + Py_Return; +} + +// 4. SetBody +PyObject* KX_NetworkMessageActuator::PySetBody( + PyObject* self, + PyObject* args, + PyObject* kwds) +{ + char* Body; + + if (PyArg_ParseTuple(args, "s", &Body)) { + m_body = Body; + } + + Py_Return; +} + diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h new file mode 100644 index 00000000000..2ab4319821c --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h @@ -0,0 +1,77 @@ +/** + * $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 ***** + * Ketsji Logic Extenstion: Network Message Actuator class + */ +#ifndef __KX_NETWORKMESSAGEACTUATOR_H +#define __KX_NETWORKMESSAGEACTUATOR_H + +#include "STR_String.h" + +#include "SCA_IActuator.h" + +#include "NG_NetworkMessage.h" + +class KX_NetworkMessageActuator : public SCA_IActuator +{ + Py_Header; + bool m_lastEvent; + class NG_NetworkScene* m_networkscene; // needed for replication + STR_String m_toPropName; + STR_String m_subject; + int m_bodyType; + STR_String m_body; +public: + KX_NetworkMessageActuator( + SCA_IObject* gameobj, + NG_NetworkScene* networkscene, + const STR_String &toPropName, + const STR_String &subject, + int bodyType, + const STR_String &body, + PyTypeObject* T=&Type); + virtual ~KX_NetworkMessageActuator(); + + virtual bool Update(double curtime, double deltatime); + virtual CValue* GetReplica(); + + /* ------------------------------------------------------------ */ + /* Python interface ------------------------------------------- */ + /* ------------------------------------------------------------ */ + + virtual PyObject* _getattr(char *attr); + + KX_PYMETHOD(KX_NetworkMessageActuator, SetToPropName); + KX_PYMETHOD(KX_NetworkMessageActuator, SetSubject); + KX_PYMETHOD(KX_NetworkMessageActuator, SetBodyType); + KX_PYMETHOD(KX_NetworkMessageActuator, SetBody); + +}; +#endif //__KX_NETWORKMESSAGEACTUATOR_H diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp new file mode 100644 index 00000000000..1eeceb55469 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp @@ -0,0 +1,258 @@ +/** + * $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 ***** + * Ketsji Logic Extenstion: Network Message Sensor generic implementation + */ + +#include "KX_NetworkMessageSensor.h" +#include "KX_NetworkEventManager.h" +#include "NG_NetworkMessage.h" +#include "NG_NetworkScene.h" +#include "NG_NetworkObject.h" +#include "SCA_IObject.h" +#include "InputParser.h" +#include "ListValue.h" +#include "StringValue.h" + +#ifdef NAN_NET_DEBUG + #include <iostream> +#endif + +KX_NetworkMessageSensor::KX_NetworkMessageSensor( + class KX_NetworkEventManager* eventmgr, // our eventmanager + class NG_NetworkScene *NetworkScene, // our scene + SCA_IObject* gameobj, // the sensor controlling object + const STR_String &subject, + PyTypeObject* T +) : + SCA_ISensor(gameobj,eventmgr,T), + m_Networkeventmgr(eventmgr), + m_NetworkScene(NetworkScene), + m_subject(subject), + m_frame_message_count (0), + m_IsUp(false), + m_BodyList(NULL) +{ +} + +KX_NetworkMessageSensor::~KX_NetworkMessageSensor() +{ +} + +CValue* KX_NetworkMessageSensor::GetReplica() { + // This is the standard sensor implementation of GetReplica + // There may be more network message sensor specific stuff to do here. + CValue* replica = new KX_NetworkMessageSensor(*this); + + if (replica == NULL) return NULL; + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +} + +// Return true only for flank (UP and DOWN) +bool KX_NetworkMessageSensor::Evaluate(CValue* event) +{ + bool result = false; + bool WasUp = m_IsUp; + + m_IsUp = false; + if (m_BodyList) { + m_BodyList->Release(); + m_BodyList = NULL; + } + + STR_String toname=GetParent()->GetName(); + STR_String subject = this->m_subject; + + vector<NG_NetworkMessage*> messages = + m_NetworkScene->FindMessages(toname,"",subject,true); + + m_frame_message_count = messages.size(); + + if (!messages.empty()) { +#ifdef NAN_NET_DEBUG + printf("KX_NetworkMessageSensor found one or more messages\n"); +#endif + m_IsUp = true; + m_BodyList = new CListValue(); + } + + vector<NG_NetworkMessage*>::iterator mesit; + for (mesit=messages.begin();mesit!=messages.end();mesit++) + { + // save the body + STR_String body = (*mesit)->GetMessageText(); +#ifdef NAN_NET_DEBUG + if (body) { + cout << "body [" << body << "]\n"; + } +#endif + m_BodyList->Add(new CStringValue(body,"body")); + + // free the message + (*mesit)->Release(); + } + messages.clear(); + + result = (WasUp != m_IsUp); + + // Return true if the message received state has changed. + return result; +} + +// return true for being up (no flank needed) +bool KX_NetworkMessageSensor::IsPositiveTrigger() +{ +// printf("KX_NetworkMessageSensor IsPositiveTrigger\n"); + return m_IsUp; +} + +/* --------------------------------------------------------------------- */ +/* Python interface ---------------------------------------------------- */ +/* --------------------------------------------------------------------- */ + +/* Integration hooks --------------------------------------------------- */ +PyTypeObject KX_NetworkMessageSensor::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_NetworkMessageSensor", + sizeof(KX_NetworkMessageSensor), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_NetworkMessageSensor::Parents[] = { + &KX_NetworkMessageSensor::Type, + &SCA_ISensor::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_NetworkMessageSensor::Methods[] = { + {"setSubjectFilterText", (PyCFunction) + KX_NetworkMessageSensor::sPySetSubjectFilterText, METH_VARARGS, + SetSubjectFilterText_doc}, + {"getFrameMessageCount", (PyCFunction) + KX_NetworkMessageSensor::sPyGetFrameMessageCount, METH_VARARGS, + GetFrameMessageCount_doc}, + {"getBodies", (PyCFunction) + KX_NetworkMessageSensor::sPyGetBodies, METH_VARARGS, + GetBodies_doc}, + {"getSubject", (PyCFunction) + KX_NetworkMessageSensor::sPyGetSubject, METH_VARARGS, + GetSubject_doc}, + {NULL,NULL} //Sentinel +}; + +PyObject* KX_NetworkMessageSensor::_getattr(char* attr) { + _getattr_up(SCA_ISensor); // implicit return! +} + +// 1. Set the message subject that this sensor listens for +char KX_NetworkMessageSensor::SetSubjectFilterText_doc[] = +"\tsetSubjectFilterText(value)\n" +"\tChange the message subject text that this sensor is listening to.\n"; + +PyObject* KX_NetworkMessageSensor::PySetSubjectFilterText( + PyObject* self, + PyObject* args, + PyObject* kwds) +{ + char* Subject; + + if (PyArg_ParseTuple(args, "s", &Subject)) + { + m_subject = Subject; + } + + Py_Return; +} + +// 2. Get the number of messages received since the last frame +char KX_NetworkMessageSensor::GetFrameMessageCount_doc[] = +"\tgetFrameMessageCount()\n" +"\tGet the number of messages received since the last frame.\n"; + +PyObject* KX_NetworkMessageSensor::PyGetFrameMessageCount( + PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return PyInt_FromLong(long(m_frame_message_count)); +} + +// 3. Get the message bodies +char KX_NetworkMessageSensor::GetBodies_doc[] = +"\tgetBodies()\n" +"\tGet the list of message bodies.\n"; + +PyObject* KX_NetworkMessageSensor::PyGetBodies( + PyObject* self, + PyObject* args, + PyObject* kwds) +{ + if (m_BodyList) { + return ((PyObject*) m_BodyList->AddRef()); + } + + Py_Return; +} + +// 4. Get the message subject +char KX_NetworkMessageSensor::GetSubject_doc[] = +"\tgetSubject()\n" +"\tGet the subject of the message.\n"; + +PyObject* KX_NetworkMessageSensor::PyGetSubject( + PyObject* self, + PyObject* args, + PyObject* kwds) +{ + if (m_subject) { + return PyString_FromString(m_subject); + } + + Py_Return; +} + diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h new file mode 100644 index 00000000000..2c30befd883 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -0,0 +1,85 @@ +/** + * $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 ***** + * Ketsji Logic Extenstion: Network Message Sensor class + */ +#ifndef __KX_NETWORKMESSAGE_SENSOR_H +#define __KX_NETWORKMESSAGE_SENSOR_H + +#include "SCA_ISensor.h" + +class KX_NetworkEventManager; +class NG_NetworkScene; + +class KX_NetworkMessageSensor : public SCA_ISensor +{ + // note: Py_Header MUST BE the first listed here + Py_Header; + KX_NetworkEventManager *m_Networkeventmgr; + NG_NetworkScene *m_NetworkScene; + + // The subject we filter on. + STR_String m_subject; + + // The number of messages caught since the last frame. + int m_frame_message_count; + + bool m_IsUp; + + class CListValue* m_BodyList; +public: + KX_NetworkMessageSensor( + KX_NetworkEventManager* eventmgr, // our eventmanager + NG_NetworkScene *NetworkScene, // our scene + SCA_IObject* gameobj, // the sensor controlling object + const STR_String &subject, + PyTypeObject* T=&Type + ); + virtual ~KX_NetworkMessageSensor(); + + virtual CValue* GetReplica(); + virtual bool Evaluate(CValue* event); + virtual bool IsPositiveTrigger(); + void EndFrame(); + + /* ------------------------------------------------------------- */ + /* Python interface -------------------------------------------- */ + /* ------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + + KX_PYMETHOD_DOC(KX_NetworkMessageSensor, SetSubjectFilterText); + KX_PYMETHOD_DOC(KX_NetworkMessageSensor, GetFrameMessageCount); + KX_PYMETHOD_DOC(KX_NetworkMessageSensor, GetBodies); + KX_PYMETHOD_DOC(KX_NetworkMessageSensor, GetSubject); + + +}; +#endif //__KX_NETWORKMESSAGE_SENSOR_H diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.cpp new file mode 100644 index 00000000000..a7800aea8c8 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.cpp @@ -0,0 +1,31 @@ +/** + * $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 ***** + */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.h new file mode 100644 index 00000000000..a7800aea8c8 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectActuator.h @@ -0,0 +1,31 @@ +/** + * $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 ***** + */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.cpp new file mode 100644 index 00000000000..a7800aea8c8 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.cpp @@ -0,0 +1,31 @@ +/** + * $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 ***** + */ diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.h new file mode 100644 index 00000000000..a7800aea8c8 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkObjectSensor.h @@ -0,0 +1,31 @@ +/** + * $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 ***** + */ diff --git a/source/gameengine/Ketsji/KXNetwork/Makefile b/source/gameengine/Ketsji/KXNetwork/Makefile new file mode 100644 index 00000000000..bce2cbc29a3 --- /dev/null +++ b/source/gameengine/Ketsji/KXNetwork/Makefile @@ -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 ***** +# +# + +LIBNAME = KXNetwork +DIR = $(OCGDIR)/gameengine/ketsji/$(LIBNAME) + +include nan_compile.mk + +CCFLAGS += $(LEVEL_1_CPP_WARNINGS) + +CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) +CPPFLAGS += -I$(NAN_STRING)/include +CPPFLAGS += -I../../Expressions +CPPFLAGS += -I../../GameLogic +CPPFLAGS += -I../../Network +CPPFLAGS += -I../../../kernel/gen_system +CPPFLAGS += -I.. + diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp new file mode 100644 index 00000000000..e69e0e98960 --- /dev/null +++ b/source/gameengine/Ketsji/KX_CDActuator.cpp @@ -0,0 +1,252 @@ +/** + * KX_CDActuator.cpp + * + * $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_CDActuator.h" +#include "SND_CDObject.h" +#include "KX_GameObject.h" +#include "SND_Scene.h" // needed for replication +#include <iostream> + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ +KX_CDActuator::KX_CDActuator(SCA_IObject* gameobject, + SND_Scene* soundscene, + KX_CDACT_TYPE type, + int track, + short start, + short end, + PyTypeObject* T) + : SCA_IActuator(gameobject,T) +{ + m_soundscene = soundscene; + m_type = type; + m_track = track; + m_lastEvent = true; + m_isplaying = false; + m_startFrame = start; + m_endFrame = end; + m_gain = SND_CDObject::Instance()->GetGain(); +} + + + +KX_CDActuator::~KX_CDActuator() +{ +} + + +/* hmmm, do we want this? */ +CValue* KX_CDActuator::GetReplica() +{ + KX_CDActuator* replica = new KX_CDActuator(*this); + replica->ProcessReplica(); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; +}; + + + +bool KX_CDActuator::Update(double curtime,double deltatime) +{ + bool result = false; + bool bNegativeEvent = IsNegativeEvent(); + + RemoveAllEvents(); + + if (!bNegativeEvent) + { + switch (m_type) + { + case KX_CDACT_PLAY_ALL: + { + SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL); + SND_CDObject::Instance()->SetTrack(1); + SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY); + result = true; + break; + } + case KX_CDACT_PLAY_TRACK: + { + SND_CDObject::Instance()->SetPlaymode(SND_CD_TRACK); + SND_CDObject::Instance()->SetTrack(m_track); + SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY); + result = true; + break; + } + case KX_CDACT_LOOP_TRACK: + { + SND_CDObject::Instance()->SetPlaymode(SND_CD_ALL); + SND_CDObject::Instance()->SetTrack(m_track); + SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY); + result = true; + break; + } + case KX_CDACT_STOP: + { + SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP); + break; + } + case KX_CDACT_PAUSE: + { + SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE); + result = true; + break; + } + case KX_CDACT_RESUME: + { + SND_CDObject::Instance()->SetPlaystate(SND_MUST_RESUME); + result = true; + break; + } + case KX_CDACT_VOLUME: + { + SND_CDObject::Instance()->SetGain(m_gain); + result = true; + break; + } + default: + // implement me !! + break; + } + } + return result; +} + + + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + + + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_CDActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_SoundActuator", + sizeof(KX_CDActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + + + +PyParentObject KX_CDActuator::Parents[] = { + &KX_CDActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + + +PyMethodDef KX_CDActuator::Methods[] = { + {"startCD",(PyCFunction) KX_CDActuator::sPyStartCD,METH_VARARGS,NULL}, + {"pauseCD",(PyCFunction) KX_CDActuator::sPyPauseCD,METH_VARARGS,NULL}, + {"stopCD",(PyCFunction) KX_CDActuator::sPyStopCD,METH_VARARGS,NULL}, + {"setGain",(PyCFunction) KX_CDActuator::sPySetGain,METH_VARARGS,NULL}, + {"getGain",(PyCFunction) KX_CDActuator::sPyGetGain,METH_VARARGS,NULL}, + {NULL,NULL,NULL,NULL} //Sentinel +}; + + + +PyObject* KX_CDActuator::_getattr(char* attr) +{ + _getattr_up(SCA_IActuator); +} + + + + +PyObject* KX_CDActuator::PyStartCD(PyObject* self, PyObject* args, PyObject* kwds) +{ + SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY); + Py_Return; +} + + + +PyObject* KX_CDActuator::PyPauseCD(PyObject* self, PyObject* args, PyObject* kwds) +{ + SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE); + Py_Return; +} + + + +PyObject* KX_CDActuator::PyStopCD(PyObject* self, PyObject* args, PyObject* kwds) +{ + SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP); + Py_Return; +} + + + +PyObject* KX_CDActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwds) +{ + float gain = 1.0; + if (!PyArg_ParseTuple(args, "f", &gain)) + return NULL; + + SND_CDObject::Instance()->SetGain(gain); + + Py_Return; +} + + + +PyObject* KX_CDActuator::PyGetGain(PyObject* self, PyObject* args, PyObject* kwds) +{ + float gain = SND_CDObject::Instance()->GetGain(); + PyObject* result = PyFloat_FromDouble(gain); + + return result; +}
\ No newline at end of file diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h new file mode 100644 index 00000000000..48570523f51 --- /dev/null +++ b/source/gameengine/Ketsji/KX_CDActuator.h @@ -0,0 +1,97 @@ +/** + * KX_CDActuator.h + * + * $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_CDACTUATOR +#define __KX_CDACTUATOR + +#include "SCA_IActuator.h" +#include "SND_CDObject.h" + + +class KX_CDActuator : public SCA_IActuator +{ + Py_Header; + bool m_lastEvent; + bool m_isplaying; + /* just some handles to the audio-data... */ + class SND_Scene* m_soundscene; + int m_track; + float m_gain; + short m_startFrame; + short m_endFrame; + +public: + enum KX_CDACT_TYPE + { + KX_CDACT_NODEF = 0, + KX_CDACT_PLAY_ALL, + KX_CDACT_PLAY_TRACK, + KX_CDACT_LOOP_TRACK, + KX_CDACT_VOLUME, + KX_CDACT_STOP, + KX_CDACT_PAUSE, + KX_CDACT_RESUME, + KX_SOUNDACT_MAX + }; + + KX_CDACT_TYPE m_type; + + KX_CDActuator(SCA_IObject* gameobject, + SND_Scene* soundscene, + KX_CDACT_TYPE type, + int track, + short start, + short end, + PyTypeObject* T=&Type); + + ~KX_CDActuator(); + + bool Update(double curtime,double deltatime); + + CValue* GetReplica(); + + /* -------------------------------------------------------------------- */ + /* Python interface --------------------------------------------------- */ + /* -------------------------------------------------------------------- */ + + PyObject* _getattr(char *attr); + + KX_PYMETHOD(KX_CDActuator,StartCD); + KX_PYMETHOD(KX_CDActuator,PauseCD); + KX_PYMETHOD(KX_CDActuator,StopCD); + KX_PYMETHOD(KX_CDActuator,SetGain); + KX_PYMETHOD(KX_CDActuator,GetGain); +}; +#endif //__KX_CDACTUATOR + diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp new file mode 100644 index 00000000000..919355d411a --- /dev/null +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -0,0 +1,181 @@ +/* + * $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 ***** + * Camera in the gameengine. Cameras are also used for views. + */ + +#include "KX_Camera.h" + +KX_Camera::KX_Camera(void* sgReplicationInfo, + SG_Callbacks callbacks, + const RAS_CameraData& camdata) + : + KX_GameObject(sgReplicationInfo,callbacks) +{ + // setting a name would be nice... + m_name = "cam"; + m_camdata = camdata; + SetProperty("camera",new CIntValue(1)); +} + + + +KX_Camera::~KX_Camera() +{ +} + + + +MT_Transform KX_Camera::GetWorldToCamera() const +{ + MT_Transform camtrans; + MT_Transform trans; + + trans.setBasis(NodeGetWorldOrientation()); + trans.setOrigin(NodeGetWorldPosition()); + + camtrans.invert(trans); + + return camtrans; +} + + + +MT_Transform KX_Camera::GetCameraToWorld() const +{ + MT_Transform trans; + trans.setBasis(NodeGetWorldOrientation()); + trans.setOrigin(NodeGetWorldPosition()); + + return trans; +} + + + +void KX_Camera::CorrectLookUp(MT_Scalar speed) +{ +} + + + +const MT_Point3 KX_Camera::GetCameraLocation() +{ + /* this is the camera locatio in cam coords... */ + //return m_trans1.getOrigin(); + //return MT_Point3(0,0,0); <----- + /* .... I want it in world coords */ + MT_Transform trans; + trans.setBasis(NodeGetWorldOrientation()); + + return NodeGetWorldPosition(); +} + + + +/* I want the camera orientation as well. */ +const MT_Quaternion KX_Camera::GetCameraOrientation() +{ + MT_Transform trans; + trans.setBasis(NodeGetWorldOrientation()); + trans.setOrigin(NodeGetWorldPosition()); + + return trans.getRotation(); +} + + + +/** +* Sets the projection matrix that is used by the rasterizer. +*/ +void KX_Camera::SetProjectionMatrix(const MT_Matrix4x4 & mat) +{ + m_projection_matrix = mat; +} + + + +/** +* Sets the modelview matrix that is used by the rasterizer. +*/ +void KX_Camera::SetModelviewMatrix(const MT_Matrix4x4 & mat) +{ + m_modelview_matrix = mat; +} + + + +/** +* Gets the projection matrix that is used by the rasterizer. +*/ +void KX_Camera::GetProjectionMatrix(MT_Matrix4x4 & mat) +{ + mat = m_projection_matrix; +} + + + +/** +* Gets the modelview matrix that is used by the rasterizer. +*/ +void KX_Camera::GetModelviewMatrix(MT_Matrix4x4 & mat) +{ + mat = m_modelview_matrix; +} + + + +/* +* These getters retrieve the clip data and the focal length +*/ +float KX_Camera::GetLens() +{ + return m_camdata.m_lens; +} + + + +float KX_Camera::GetCameraNear() +{ + return m_camdata.m_clipstart; +} + + + +float KX_Camera::GetCameraFar() +{ + return m_camdata.m_clipend; +} + + + +RAS_CameraData* KX_Camera::GetCameraData() +{ + return &m_camdata; +} diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h new file mode 100644 index 00000000000..0bc80102e45 --- /dev/null +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -0,0 +1,114 @@ +/* + * $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 ***** + * Camera in the gameengine. Cameras are also used for views. + */ + +#ifndef __KX_CAMERA +#define __KX_CAMERA + + +#include "MT_Transform.h" +#include "MT_Matrix3x3.h" +#include "MT_Matrix4x4.h" +#include "MT_Vector3.h" +#include "MT_Point3.h" +#include "KX_GameObject.h" +#include "IntValue.h" +#include "RAS_CameraData.h" + + +class KX_Camera : public KX_GameObject +{ + + /** Camera parameters (clips distances, focal lenght). These + * params are closely tied to BLender. In the gameengine, only the + * projection and modelview matrices are relevant. There's a + * conversion being done in the engine class. Why is it stored + * here? It doesn't really have a function here. */ + RAS_CameraData m_camdata; + + // Never used, I think... +// void MoveTo(const MT_Point3& movevec) +// { + /*MT_Transform camtrans; + camtrans.invert(m_trans1); + MT_Matrix3x3 camorient = camtrans.getBasis(); + camtrans.translate(camorient.inverse()*movevec); + m_trans1.invert(camtrans); + */ +// } + + /** + * Storage for the projection matrix that is passed to the + * rasterizer. */ + MT_Matrix4x4 m_projection_matrix; + + /** + * Storage for the modelview matrix that is passed to the + * rasterizer. */ + MT_Matrix4x4 m_modelview_matrix; + +public: + + KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata); + virtual ~KX_Camera(); + + MT_Transform GetWorldToCamera() const; + MT_Transform GetCameraToWorld() const; + + void CorrectLookUp(MT_Scalar speed); + const MT_Point3 GetCameraLocation(); + + /* I want the camera orientation as well. */ + const MT_Quaternion GetCameraOrientation(); + + /** Sets the projection matrix that is used by the rasterizer. */ + void SetProjectionMatrix(const MT_Matrix4x4 & mat); + + /** Sets the modelview matrix that is used by the rasterizer. */ + void SetModelviewMatrix(const MT_Matrix4x4 & mat); + + /** Gets the projection matrix that is used by the rasterizer. */ + void GetProjectionMatrix(MT_Matrix4x4 & mat); + + /** Gets the modelview matrix that is used by the rasterizer. */ + void GetModelviewMatrix(MT_Matrix4x4 & mat); + + /** Gets the focal lenght. */ + float GetLens(); + /** Gets the near clip distance. */ + float GetCameraNear(); + /** Gets the far clip distance. */ + float GetCameraFar(); + /** Gets all camera data. */ + RAS_CameraData* GetCameraData(); +}; +#endif //__KX_CAMERA diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp new file mode 100644 index 00000000000..8a6ed0106f5 --- /dev/null +++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp @@ -0,0 +1,368 @@ +/** + * KX_CameraActuator.cpp + * + * $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_CameraActuator.h" +#include <iostream> +#include <math.h> +#include "KX_GameObject.h" + +STR_String KX_CameraActuator::X_AXIS_STRING = "x"; +STR_String KX_CameraActuator::Y_AXIS_STRING = "y"; + + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_CameraActuator::KX_CameraActuator( + SCA_IObject* gameobj, + const CValue *obj, + MT_Scalar hght, + MT_Scalar minhght, + MT_Scalar maxhght, + bool xytog, + PyTypeObject* T +): + SCA_IActuator(gameobj, T), + m_ob (obj), + m_height (hght), + m_minHeight (minhght), + m_maxHeight (maxhght), + m_x (xytog) +{ + // nothing to do +} + +KX_CameraActuator::~KX_CameraActuator() +{ + //nothing to do +} + + CValue* +KX_CameraActuator:: +GetReplica( +) { + KX_CameraActuator* replica = new KX_CameraActuator(*this); + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; +}; + + + + +/* three functions copied from blender arith... don't know if there's an equivalent */ + +float Normalise(float *n) +{ + float d; + + d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2]; + /* FLT_EPSILON is too large! A larger value causes normalise errors in a scaled down utah teapot */ + if(d>0.0000000000001) { + d= sqrt(d); + + n[0]/=d; + n[1]/=d; + n[2]/=d; + } else { + n[0]=n[1]=n[2]= 0.0; + d= 0.0; + } + return d; +} + +void Crossf(float *c, float *a, float *b) +{ + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; +} + + +void VecUpMat3(float *vec, float mat[][3], short axis) +{ + + // Construct a camera matrix s.t. the specified axis + + // maps to the given vector (*vec). Also defines the rotation + + // about this axis by mapping one of the other axis to the y-axis. + + + float inp; + short cox = 0, coy = 0, coz = 0; + + /* up varieeren heeft geen zin, is eigenlijk helemaal geen up! + * zie VecUpMat3old + */ + + if(axis==0) { + cox= 0; coy= 1; coz= 2; /* Y up Z tr */ + } + if(axis==1) { + cox= 1; coy= 2; coz= 0; /* Z up X tr */ + } + if(axis==2) { + cox= 2; coy= 0; coz= 1; /* X up Y tr */ + } + if(axis==3) { + cox= 0; coy= 1; coz= 2; /* Y op -Z tr */ + vec[0]= -vec[0]; + vec[1]= -vec[1]; + vec[2]= -vec[2]; + } + if(axis==4) { + cox= 1; coy= 0; coz= 2; /* */ + } + if(axis==5) { + cox= 2; coy= 1; coz= 0; /* Y up X tr */ + } + + mat[coz][0]= vec[0]; + mat[coz][1]= vec[1]; + mat[coz][2]= vec[2]; + Normalise((float *)mat[coz]); + + inp= mat[coz][2]; + mat[coy][0]= - inp*mat[coz][0]; + mat[coy][1]= - inp*mat[coz][1]; + mat[coy][2]= 1.0 - inp*mat[coz][2]; + + Normalise((float *)mat[coy]); + + Crossf(mat[cox], mat[coy], mat[coz]); + +} + +bool KX_CameraActuator::Update(double curtime,double deltatime) +{ + bool result = true; + + KX_GameObject *obj = (KX_GameObject*) GetParent(); + MT_Point3 from = obj->NodeGetWorldPosition(); + MT_Matrix3x3 frommat = obj->NodeGetWorldOrientation(); + /* These casts are _very_ dangerous!!! */ + MT_Point3 lookat = ((KX_GameObject*)m_ob)->NodeGetWorldPosition(); + MT_Matrix3x3 actormat = ((KX_GameObject*)m_ob)->NodeGetWorldOrientation(); + + + + float fp1[3], fp2[3], rc[3]; + float inp, fac; //, factor = 0.0; /* some factor... */ + float mindistsq, maxdistsq, distsq; + float mat[3][3]; + + /* wondering... is it really neccesary/desirable to suppress negative */ + /* events here? */ + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) return false; + + /* The rules: */ + /* CONSTRAINT 1: not implemented */ + /* CONSTRAINT 2: can camera see actor? */ + /* CONSTRAINT 3: fixed height relative to floor below actor. */ + /* CONSTRAINT 4: camera rotates behind actor */ + /* CONSTRAINT 5: minimum / maximum distance */ + /* CONSTRAINT 6: again: fixed height relative to floor below actor */ + /* CONSTRAINT 7: track to floor below actor */ + /* CONSTRAINT 8: look a little bit left or right, depending on how the + + character is looking (horizontal x) + */ + + /* ...and then set the camera position. Since we assume the parent of */ + /* this actuator is always a camera, just set the parent position and */ + /* rotation. We do not check whether we really have a camera as parent. */ + /* It may be better to turn this into a general tracking actuator later */ + /* on, since lots of plausible relations can be filled in here. */ + + /* ... set up some parameters ... */ + /* missing here: the 'floorloc' of the actor's shadow */ + + mindistsq= m_minHeight*m_minHeight; + maxdistsq= m_maxHeight*m_maxHeight; + + /* C1: not checked... is a future option */ + + /* C2: blender test_visibility function. Can this be a ray-test? */ + + /* C3: fixed height */ + from[2] = (15.0*from[2] + lookat[2] + m_height)/16.0; + + + /* C4: camera behind actor */ + if (m_x) { + fp1[0] = actormat[0][0]; + fp1[1] = actormat[1][0]; + fp1[2] = actormat[2][0]; + + fp2[0] = frommat[0][0]; + fp2[1] = frommat[1][0]; + fp2[2] = frommat[2][0]; + } + else { + fp1[0] = actormat[0][1]; + fp1[1] = actormat[1][1]; + fp1[2] = actormat[2][1]; + + fp2[0] = frommat[0][1]; + fp2[1] = frommat[1][1]; + fp2[2] = frommat[2][1]; + } + + inp= fp1[0]*fp2[0] + fp1[1]*fp2[1] + fp1[2]*fp2[2]; + fac= (-1.0 + inp)/32.0; + + from[0]+= fac*fp1[0]; + from[1]+= fac*fp1[1]; + from[2]+= fac*fp1[2]; + + /* alleen alstie ervoor ligt: cross testen en loodrechte bijtellen */ + if(inp<0.0) { + if(fp1[0]*fp2[1] - fp1[1]*fp2[0] > 0.0) { + from[0]-= fac*fp1[1]; + from[1]+= fac*fp1[0]; + } + else { + from[0]+= fac*fp1[1]; + from[1]-= fac*fp1[0]; + } + } + + /* CONSTRAINT 5: minimum / maximum afstand */ + + rc[0]= (lookat[0]-from[0]); + rc[1]= (lookat[1]-from[1]); + rc[2]= (lookat[2]-from[2]); + distsq= rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2]; + + if(distsq > maxdistsq) { + distsq = 0.15*(distsq-maxdistsq)/distsq; + + from[0] += distsq*rc[0]; + from[1] += distsq*rc[1]; + from[2] += distsq*rc[2]; + } + else if(distsq < mindistsq) { + distsq = 0.15*(mindistsq-distsq)/mindistsq; + + from[0] -= distsq*rc[0]; + from[1] -= distsq*rc[1]; + from[2] -= distsq*rc[2]; + } + + + /* CONSTRAINT 7: track to schaduw */ + rc[0]= (lookat[0]-from[0]); + rc[1]= (lookat[1]-from[1]); + rc[2]= (lookat[2]-from[2]); + VecUpMat3(rc, mat, 3); /* y up Track -z */ + + + + + /* now set the camera position and rotation */ + + obj->NodeSetLocalPosition(from); + + actormat[0][0]= mat[0][0]; actormat[0][1]= mat[1][0]; actormat[0][2]= mat[2][0]; + actormat[1][0]= mat[0][1]; actormat[1][1]= mat[1][1]; actormat[1][2]= mat[2][1]; + actormat[2][0]= mat[0][2]; actormat[2][1]= mat[1][2]; actormat[2][2]= mat[2][2]; + obj->NodeSetLocalOrientation(actormat); + + return result; +} + +CValue *KX_CameraActuator::findObject(char *obName) +{ + /* hook to object system */ + return NULL; +} + +bool KX_CameraActuator::string2axischoice(const char *axisString) +{ + bool res = true; + + res = !(axisString == Y_AXIS_STRING); + + return res; +} + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_CameraActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_CameraActuator", + sizeof(KX_CameraActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_CameraActuator::Parents[] = { + &KX_CameraActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_CameraActuator::Methods[] = { + {NULL,NULL,NULL,NULL} //Sentinel +}; + +PyObject* KX_CameraActuator::_getattr(char* attr) { + _getattr_up(SCA_IActuator); +} + + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h new file mode 100644 index 00000000000..1d819864cff --- /dev/null +++ b/source/gameengine/Ketsji/KX_CameraActuator.h @@ -0,0 +1,128 @@ +/** + * KX_CameraActuator.h + * + * $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_CAMERAACTUATOR +#define __KX_CAMERAACTUATOR + +#include "SCA_IActuator.h" +#include "MT_Scalar.h" + + +/** + * The camera actuator does a Robbie Muller prespective for you. This is a + * weird set of rules that positions the camera sort of behind the object, + * tracking, while avoiding any objects between the 'ideal' position and the + * actor being tracked. + */ + + +class KX_CameraActuator : public SCA_IActuator +{ + +private : + Py_Header; + + /** Object that will be tracked. */ + const CValue *m_ob; + + /** height (float), */ + const MT_Scalar m_height; + + /** min (float), */ + const MT_Scalar m_minHeight; + + /** max (float), */ + const MT_Scalar m_maxHeight; + + /** xy toggle (pick one): true == x, false == y */ + bool m_x; + + /* get the KX_IGameObject with this name */ + CValue *findObject(char *obName); + + /* parse x or y to a toggle pick */ + bool string2axischoice(const char *axisString); + + public: + static STR_String X_AXIS_STRING; + static STR_String Y_AXIS_STRING; + + /** + * Set the bool toggle to true to use x lock, false for y lock + */ + KX_CameraActuator( + + SCA_IObject *gameobj, + const CValue *ob, + MT_Scalar hght, + MT_Scalar minhght, + MT_Scalar maxhght, + bool xytog, + PyTypeObject* T=&Type + + ); + + + ~KX_CameraActuator(); + + + + /** Methods Inherited from CValue */ + + + CValue* GetReplica(); + + + /** Methods inherited from SCA_IActuator */ + + + bool Update( + + double curtime, + + double deltatime + + ); + + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + + + +}; +#endif //__KX_CAMERAACTUATOR diff --git a/source/gameengine/Ketsji/KX_CameraIpoSGController.cpp b/source/gameengine/Ketsji/KX_CameraIpoSGController.cpp new file mode 100644 index 00000000000..2e736864a44 --- /dev/null +++ b/source/gameengine/Ketsji/KX_CameraIpoSGController.cpp @@ -0,0 +1,125 @@ +/** + * $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_CameraIpoSGController.h" + +#include "KX_ScalarInterpolator.h" +#include "KX_Camera.h" + +#include "RAS_CameraData.h" + + +bool KX_CameraIpoSGController::Update(double currentTime) +{ + if (m_modified) + { + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + (*i)->Execute(m_ipotime); + } + + RAS_CameraData* camdata; + + SG_Spatial* ob = (SG_Spatial*)m_pObject; + KX_Camera* kxcamera = (KX_Camera*) ob->GetSGClientObject(); + camdata = kxcamera->GetCameraData(); + + + if (m_modify_lens) { + camdata->m_lens = m_lens; + } + + if (m_modify_clipstart ) { + camdata->m_clipstart = m_clipstart; + } + + if (m_modify_clipend) { + camdata->m_clipend = m_clipend; + } + + m_modified=false; + } + return false; +} + + +void KX_CameraIpoSGController::AddInterpolator(KX_IInterpolator* interp) +{ + this->m_interpolators.push_back(interp); +} + +SG_Controller* KX_CameraIpoSGController::GetReplica(class SG_Node* destnode) +{ + KX_CameraIpoSGController* iporeplica = new KX_CameraIpoSGController(*this); + // clear object that ipo acts on + iporeplica->ClearObject(); + + // dirty hack, ask Gino for a better solution in the ipo implementation + // hacken en zagen, in what we call datahiding, not written for replication :( + + T_InterpolatorList oldlist = m_interpolators; + iporeplica->m_interpolators.clear(); + + T_InterpolatorList::iterator i; + for (i = oldlist.begin(); !(i == oldlist.end()); ++i) { + KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i)); + iporeplica->AddInterpolator(copyipo); + + MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget(); + int orgbase = (int)this; + int orgloc = (int)scaal; + int offset = orgloc-orgbase; + int newaddrbase = (int)iporeplica + offset; + MT_Scalar* blaptr = (MT_Scalar*) newaddrbase; + copyipo->SetNewTarget((MT_Scalar*)blaptr); + } + + return iporeplica; +} + +KX_CameraIpoSGController::~KX_CameraIpoSGController() +{ + + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + delete (*i); + } + +} + + void +KX_CameraIpoSGController::SetOption( + int option, + int value) +{ + /* Setting options */ + +} diff --git a/source/gameengine/Ketsji/KX_CameraIpoSGController.h b/source/gameengine/Ketsji/KX_CameraIpoSGController.h new file mode 100644 index 00000000000..3ebbcc343d4 --- /dev/null +++ b/source/gameengine/Ketsji/KX_CameraIpoSGController.h @@ -0,0 +1,91 @@ +/** + * $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_CAMERAIPOSGCONTROLLER_H +#define KX_CAMERAIPOSGCONTROLLER_H + +#include "SG_Controller.h" +#include "SG_Spatial.h" + +#include "KX_IInterpolator.h" + +struct RAS_CameraData; + +class KX_CameraIpoSGController : public SG_Controller +{ +public: + MT_Scalar m_lens; + MT_Scalar m_clipstart; + MT_Scalar m_clipend; + +private: + T_InterpolatorList m_interpolators; + unsigned short m_modify_lens : 1; + unsigned short m_modify_clipstart : 1; + unsigned short m_modify_clipend : 1; + bool m_modified; + + double m_ipotime; +public: + KX_CameraIpoSGController() : m_ipotime(0.0), + m_modify_lens(false), + m_modify_clipstart(false), + m_modify_clipend(false), + m_modified(true) + {} + + ~KX_CameraIpoSGController(); + SG_Controller* GetReplica(class SG_Node* destnode); + bool Update(double time); + + void + SetOption( + int option, + int value + ); + + void SetSimulatedTime(double time) { + m_ipotime = time; + m_modified = true; + } + void SetModifyLens(bool modify) { + m_modify_lens = modify; + } + void SetModifyClipEnd(bool modify) { + m_modify_clipend = modify; + } + void SetModifyClipStart(bool modify) { + m_modify_clipstart = modify; + } + void AddInterpolator(KX_IInterpolator* interp); +}; + +#endif // KX_CAMERAIPOSGCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h new file mode 100644 index 00000000000..8aec115e44d --- /dev/null +++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h @@ -0,0 +1,46 @@ +/** + * $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_CLIENTOBJECT_INFO_H +#define __KX_CLIENTOBJECT_INFO_H + +/** + * Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks + */ + +struct KX_ClientObjectInfo +{ + int m_type; + void* m_clientobject; + void* m_auxilary_info; +}; + +#endif //__KX_CLIENTOBJECT_INFO_H diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp new file mode 100644 index 00000000000..8aab3e7648d --- /dev/null +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp @@ -0,0 +1,369 @@ +/** + * Apply a constraint to a position or rotation value + * + * $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_IActuator.h" +#include "KX_ConstraintActuator.h" +#include "SCA_IObject.h" +#include "MT_Point3.h" +#include "MT_Matrix3x3.h" +#include "KX_GameObject.h" +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj, + int dampTime, + float minBound, + float maxBound, + int locrotxyz, + PyTypeObject* T) + : SCA_IActuator(gameobj, T) +{ + m_dampTime = dampTime; + m_locrot = locrotxyz; + /* The units of bounds are determined by the type of constraint. To */ + /* make the constraint application easier and more transparent later on, */ + /* I think converting the bounds to the applicable domain makes more */ + /* sense. */ + switch (m_locrot) { + case KX_ACT_CONSTRAINT_LOCX: + case KX_ACT_CONSTRAINT_LOCY: + case KX_ACT_CONSTRAINT_LOCZ: + m_minimumBound = minBound; + m_maximumBound = maxBound; + break; + case KX_ACT_CONSTRAINT_ROTX: + case KX_ACT_CONSTRAINT_ROTY: + case KX_ACT_CONSTRAINT_ROTZ: + /* The user interface asks for degrees, we are radian. */ + m_minimumBound = MT_radians(minBound); + m_maximumBound = MT_radians(maxBound); + break; + default: + ; /* error */ + } + +} /* End of constructor */ + +KX_ConstraintActuator::~KX_ConstraintActuator() +{ + // there's nothing to be done here, really.... +} /* end of destructor */ + +bool KX_ConstraintActuator::Update(double curtime,double deltatime) +{ + + bool result = false; + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) + return false; // do nothing on negative events + + /* Constraint clamps the values to the specified range, with a sort of */ + /* low-pass filtered time response, if the damp time is unequal to 0. */ + + /* Having to retrieve location/rotation and setting it afterwards may not */ + /* be efficient enough... Somthing to look at later. */ + KX_GameObject *parent = (KX_GameObject*) GetParent(); + MT_Point3 position = parent->NodeGetWorldPosition(); + MT_Matrix3x3 rotation = parent->NodeGetWorldOrientation(); +// MT_Vector3 eulerrot = rotation.getEuler(); + + switch (m_locrot) { + case KX_ACT_CONSTRAINT_LOCX: + Clamp(position[0], m_minimumBound, m_maximumBound); + break; + case KX_ACT_CONSTRAINT_LOCY: + Clamp(position[1], m_minimumBound, m_maximumBound); + break; + case KX_ACT_CONSTRAINT_LOCZ: + Clamp(position[2], m_minimumBound, m_maximumBound); + break; + +// case KX_ACT_CONSTRAINT_ROTX: +// /* The angles are Euler angles (I think that's what they are called) */ +// /* but we need to convert from/to the MT_Matrix3x3. */ +// Clamp(eulerrot[0], m_minimumBound, m_maximumBound); +// break; +// case KX_ACT_CONSTRAINT_ROTY: +// Clamp(eulerrot[1], m_minimumBound, m_maximumBound); +// break; +// case KX_ACT_CONSTRAINT_ROTZ: +// Clamp(eulerrot[2], m_minimumBound, m_maximumBound); +// break; +// default: +// ; /* error */ + } + + /* Will be replaced by a filtered clamp. */ + + + switch (m_locrot) { + case KX_ACT_CONSTRAINT_LOCX: + case KX_ACT_CONSTRAINT_LOCY: + case KX_ACT_CONSTRAINT_LOCZ: + parent->NodeSetLocalPosition(position); + break; + + +// case KX_ACT_CONSTRAINT_ROTX: +// case KX_ACT_CONSTRAINT_ROTY: +// case KX_ACT_CONSTRAINT_ROTZ: +// rotation.setEuler(eulerrot); +// parent->NodeSetLocalOrientation(rotation); + break; + + default: + ; /* error */ + } + + return false; +} /* end of KX_ConstraintActuator::Update(double curtime,double deltatime) */ + +void KX_ConstraintActuator::Clamp(MT_Scalar &var, + float min, + float max) { + if (var < min) { + var = min; + } else if (var > max) { + var = max; + } +} + + +bool KX_ConstraintActuator::IsValidMode(KX_ConstraintActuator::KX_CONSTRAINTTYPE m) +{ + bool res = false; + + if ( (m > KX_ACT_CONSTRAINT_NODEF) && (m < KX_ACT_CONSTRAINT_MAX)) { + res = true; + } + + return res; +} + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_ConstraintActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_ConstraintActuator", + sizeof(KX_ConstraintActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_ConstraintActuator::Parents[] = { + &KX_ConstraintActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_ConstraintActuator::Methods[] = { + {"setDamp", (PyCFunction) KX_ConstraintActuator::sPySetDamp, METH_VARARGS, SetDamp_doc}, + {"getDamp", (PyCFunction) KX_ConstraintActuator::sPyGetDamp, METH_VARARGS, GetDamp_doc}, + {"setMin", (PyCFunction) KX_ConstraintActuator::sPySetMin, METH_VARARGS, SetMin_doc}, + {"getMin", (PyCFunction) KX_ConstraintActuator::sPyGetMin, METH_VARARGS, GetMin_doc}, + {"setMax", (PyCFunction) KX_ConstraintActuator::sPySetMax, METH_VARARGS, SetMax_doc}, + {"getMax", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_VARARGS, GetMax_doc}, + {"setLimit", (PyCFunction) KX_ConstraintActuator::sPySetLimit, METH_VARARGS, SetLimit_doc}, + {"getLimit", (PyCFunction) KX_ConstraintActuator::sPyGetLimit, METH_VARARGS, GetLimit_doc}, + {NULL,NULL} //Sentinel +}; + +PyObject* KX_ConstraintActuator::_getattr(char* attr) { + _getattr_up(SCA_IActuator); +} + +/* 2. setDamp */ +char KX_ConstraintActuator::SetDamp_doc[] = +"setDamp(duration)\n" +"\t- duration: integer\n" +"\tSets the time with which the constraint application is delayed.\n" +"\tIf the duration is negative, it is set to 0.\n"; +PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self, + PyObject* args, + PyObject* kwds) { + int dampArg; + if(!PyArg_ParseTuple(args, "i", &dampArg)) { + return NULL; + } + + m_dampTime = dampArg; + if (m_dampTime < 0) m_dampTime = 0; + + Py_Return; +} +/* 3. getDamp */ +char KX_ConstraintActuator::GetDamp_doc[] = +"GetDamp()\n" +"\tReturns the damping time for application of the constraint.\n"; +PyObject* KX_ConstraintActuator::PyGetDamp(PyObject* self, + PyObject* args, + PyObject* kwds){ + return PyInt_FromLong(m_dampTime); +} + +/* 4. setMin */ +char KX_ConstraintActuator::SetMin_doc[] = +"setMin(lower_bound)\n" +"\t- lower_bound: float\n" +"\tSets the lower value of the interval to which the value\n" +"\tis clipped.\n"; +PyObject* KX_ConstraintActuator::PySetMin(PyObject* self, + PyObject* args, + PyObject* kwds) { + float minArg; + if(!PyArg_ParseTuple(args, "f", &minArg)) { + return NULL; + } + + switch (m_locrot) { + case KX_ACT_CONSTRAINT_LOCX: + case KX_ACT_CONSTRAINT_LOCY: + case KX_ACT_CONSTRAINT_LOCZ: + m_minimumBound = minArg; + break; + case KX_ACT_CONSTRAINT_ROTX: + case KX_ACT_CONSTRAINT_ROTY: + case KX_ACT_CONSTRAINT_ROTZ: + m_minimumBound = MT_radians(minArg); + break; + default: + ; /* error */ + } + + Py_Return; +} +/* 5. getMin */ +char KX_ConstraintActuator::GetMin_doc[] = +"getMin()\n" +"\tReturns the lower value of the interval to which the value\n" +"\tis clipped.\n"; +PyObject* KX_ConstraintActuator::PyGetMin(PyObject* self, + PyObject* args, + PyObject* kwds) { + return PyFloat_FromDouble(m_minimumBound); +} + +/* 6. setMax */ +char KX_ConstraintActuator::SetMax_doc[] = +"setMax(upper_bound)\n" +"\t- upper_bound: float\n" +"\tSets the upper value of the interval to which the value\n" +"\tis clipped.\n"; +PyObject* KX_ConstraintActuator::PySetMax(PyObject* self, + PyObject* args, + PyObject* kwds){ + float maxArg; + if(!PyArg_ParseTuple(args, "f", &maxArg)) { + return NULL; + } + + switch (m_locrot) { + case KX_ACT_CONSTRAINT_LOCX: + case KX_ACT_CONSTRAINT_LOCY: + case KX_ACT_CONSTRAINT_LOCZ: + m_maximumBound = maxArg; + break; + case KX_ACT_CONSTRAINT_ROTX: + case KX_ACT_CONSTRAINT_ROTY: + case KX_ACT_CONSTRAINT_ROTZ: + m_maximumBound = MT_radians(maxArg); + break; + default: + ; /* error */ + } + + Py_Return; +} +/* 7. getMax */ +char KX_ConstraintActuator::GetMax_doc[] = +"getMax()\n" +"\tReturns the upper value of the interval to which the value\n" +"\tis clipped.\n"; +PyObject* KX_ConstraintActuator::PyGetMax(PyObject* self, + PyObject* args, + PyObject* kwds) { + return PyFloat_FromDouble(m_maximumBound); +} + + +/* This setter/getter probably for the constraint type */ +/* 8. setLimit */ +char KX_ConstraintActuator::SetLimit_doc[] = +"setLimit(type)\n" +"\t- type: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY,\n" +"\t KX_CONSTRAINTACT_LOCZ, KX_CONSTRAINTACT_ROTX,\n" +"\t KX_CONSTRAINTACT_ROTY, or KX_CONSTRAINTACT_ROTZ.\n" +"\tSets the type of constraint.\n"; +PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self, + PyObject* args, + PyObject* kwds) { + int locrotArg; + if(!PyArg_ParseTuple(args, "i", &locrotArg)) { + return NULL; + } + + if (IsValidMode((KX_CONSTRAINTTYPE)locrotArg)) m_locrot = locrotArg; + + Py_Return; +} +/* 9. getLimit */ +char KX_ConstraintActuator::GetLimit_doc[] = +"getLimit(type)\n" +"\tReturns the type of constraint.\n"; +PyObject* KX_ConstraintActuator::PyGetLimit(PyObject* self, + PyObject* args, + PyObject* kwds) { + return PyInt_FromLong(m_locrot); +} + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h new file mode 100644 index 00000000000..247e7ea55f9 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -0,0 +1,109 @@ +/** + * KX_ConstraintActuator.h + * + * $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_CONSTRAINTACTUATOR +#define __KX_CONSTRAINTACTUATOR + +#include "SCA_IActuator.h" +#include "MT_Scalar.h" + + +class KX_ConstraintActuator : public SCA_IActuator +{ + Py_Header; + + // Damp time (int), + int m_dampTime; + // min (float), + float m_minimumBound; + // max (float), + float m_maximumBound; + // locrotxyz choice (pick one): only one choice allowed at a time! + int m_locrot; + + /** + * Clamp <var> to <min>, <max>. Borders are included (in as far as + * float comparisons are good for equality...). + */ + void Clamp(MT_Scalar &var, float min, float max); + + + public: + enum KX_CONSTRAINTTYPE { + KX_ACT_CONSTRAINT_NODEF = 0, + KX_ACT_CONSTRAINT_LOCX, + KX_ACT_CONSTRAINT_LOCY, + KX_ACT_CONSTRAINT_LOCZ, + KX_ACT_CONSTRAINT_ROTX, + KX_ACT_CONSTRAINT_ROTY, + KX_ACT_CONSTRAINT_ROTZ, + KX_ACT_CONSTRAINT_MAX + }; + + bool IsValidMode(KX_CONSTRAINTTYPE m); + + KX_ConstraintActuator(SCA_IObject* gameobj, + int damptime, + float min, + float max, + int locrot, + PyTypeObject* T=&Type); + virtual ~KX_ConstraintActuator(); + virtual CValue* GetReplica() { + KX_ConstraintActuator* replica = new KX_ConstraintActuator(*this); + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; + }; + + virtual bool Update(double curtime,double deltatime); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + + KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDamp); + KX_PYMETHOD_DOC(KX_ConstraintActuator,GetDamp); + KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMin); + KX_PYMETHOD_DOC(KX_ConstraintActuator,GetMin); + KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMax); + KX_PYMETHOD_DOC(KX_ConstraintActuator,GetMax); + KX_PYMETHOD_DOC(KX_ConstraintActuator,SetLimit); + KX_PYMETHOD_DOC(KX_ConstraintActuator,GetLimit); + +}; +#endif //__KX_CONSTRAINTACTUATOR diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp new file mode 100644 index 00000000000..0a741aa55ac --- /dev/null +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp @@ -0,0 +1,131 @@ +/** + * $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 <Python.h> + +#include "KX_ConstraintWrapper.h" +#include "PHY_IPhysicsEnvironment.h" + +KX_ConstraintWrapper::KX_ConstraintWrapper( + PHY_ConstraintType ctype, + int constraintId, + PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) +: m_constraintType(ctype),m_constraintId(constraintId),m_physenv(physenv),PyObjectPlus(T) +{ +} +KX_ConstraintWrapper::~KX_ConstraintWrapper() +{ +} +//python integration methods +PyObject* KX_ConstraintWrapper::PyTestMethod(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* KX_ConstraintWrapper::PyGetConstraintId(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return PyInt_FromLong(m_constraintId); +} + + + + +//python specific stuff +PyTypeObject KX_ConstraintWrapper::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_ConstraintWrapper", + sizeof(KX_ConstraintWrapper), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_ConstraintWrapper::Parents[] = { + &KX_ConstraintWrapper::Type, + NULL +}; + +PyObject* KX_ConstraintWrapper::_getattr(char* attr) +{ + //here you can search for existing data members (like mass,friction etc.) + _getattr_up(PyObjectPlus); +} + +int KX_ConstraintWrapper::_setattr(char* attr,PyObject* pyobj) +{ + + PyTypeObject* type = pyobj->ob_type; + int result = 1; + + if (type == &PyList_Type) + { + result = 0; + } + if (type == &PyFloat_Type) + { + result = 0; + + } + if (type == &PyInt_Type) + { + result = 0; + } + if (type == &PyString_Type) + { + result = 0; + } + if (result) + result = PyObjectPlus::_setattr(attr,pyobj); + return result; +}; + + +PyMethodDef KX_ConstraintWrapper::Methods[] = { + {"testMethod",(PyCFunction) KX_ConstraintWrapper::sPyTestMethod, METH_VARARGS}, + {"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS}, + {NULL,NULL} //Sentinel +}; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h new file mode 100644 index 00000000000..3211a74192f --- /dev/null +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -0,0 +1,57 @@ +/** + * $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_CONSTRAINT_WRAPPER +#define KX_CONSTRAINT_WRAPPER + +#include "Value.h" +#include "PHY_DynamicTypes.h" + +class KX_ConstraintWrapper : public PyObjectPlus +{ + Py_Header; + PyObject* _getattr(char* attr); + virtual int _setattr(char *attr, PyObject *value); +public: + KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); + virtual ~KX_ConstraintWrapper (); + int getConstraintId() { return m_constraintId;}; + + KX_PYMETHOD(KX_ConstraintWrapper,TestMethod); + KX_PYMETHOD(KX_ConstraintWrapper,GetConstraintId); + +private: + int m_constraintId; + PHY_ConstraintType m_constraintType; + PHY_IPhysicsEnvironment* m_physenv; +}; + +#endif //KX_CONSTRAINT_WRAPPER diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h new file mode 100644 index 00000000000..f74349a3e1a --- /dev/null +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -0,0 +1,110 @@ +/** + * $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_CONVERTPHYSICSOBJECTS +#define KX_CONVERTPHYSICSOBJECTS + + + + +//#define USE_SUMO_SOLID +//solid is not available yet + +//#define USE_ODE +//ode is not available yet + + +class RAS_MeshObject; +class KX_Scene; + + +struct KX_Bounds +{ + float m_center[3]; + float m_extends[3]; +}; + +struct KX_ObjectProperties +{ + bool m_dyna; + double m_radius; + bool m_angular_rigidbody; + bool m_in_active_layer; + bool m_ghost; + class KX_GameObject* m_dynamic_parent; + bool m_isactor; + bool m_concave; + bool m_isdeformable; + bool m_implicitsphere ; + bool m_implicitbox; + KX_Bounds m_boundingbox; +}; + +#ifdef USE_ODE + + +void KX_ConvertODEEngineObject(KX_GameObject* gameobj, + RAS_MeshObject* meshobj, + KX_Scene* kxscene, + struct PHY_ShapeProps* shapeprops, + struct PHY_MaterialProps* smmaterial, + struct KX_ObjectProperties* objprop); + + +#endif //USE_ODE + + +void KX_ConvertDynamoObject(KX_GameObject* gameobj, + RAS_MeshObject* meshobj, + KX_Scene* kxscene, + struct PHY_ShapeProps* shapeprops, + struct PHY_MaterialProps* smmaterial, + struct KX_ObjectProperties* objprop); + + + +#ifdef USE_SUMO_SOLID + + + + + +void KX_ConvertSumoObject( class KX_GameObject* gameobj, + class RAS_MeshObject* meshobj, + class KX_Scene* kxscene, + struct PHY_ShapeProps* shapeprops, + struct PHY_MaterialProps* smmaterial, + struct KX_ObjectProperties* objprop); +#endif + + + +#endif //KX_CONVERTPHYSICSOBJECTS diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp new file mode 100644 index 00000000000..01d02b58132 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -0,0 +1,427 @@ +/** + * $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 ***** + */ +#pragma warning (disable : 4786) + +#include "KX_ConvertPhysicsObject.h" +#include "KX_GameObject.h" +#include "RAS_MeshObject.h" +#include "KX_Scene.h" +#include "SYS_System.h" + +#include "PHY_Pro.h" //todo cleanup +#include "KX_ClientObjectInfo.h" + +#include "GEN_Map.h" +#include "GEN_HashedPtr.h" + +#include "KX_PhysicsEngineEnums.h" +#include "PHY_Pro.h" + +#include "KX_MotionState.h" // bridge between motionstate and scenegraph node +#ifdef USE_ODE + +#include "KX_OdePhysicsController.h" +#include "odephysicsenvironment.h" +#endif //USE_ODE + + +// USE_SUMO_SOLID is defined in headerfile KX_ConvertPhysicsObjects.h +#ifdef USE_SUMO_SOLID + + +#include "SumoPhysicsEnvironment.h" +#include "KX_SumoPhysicsController.h" + + +// sumo physics specific +#include "SM_Object.h" +#include "SM_FhObject.h" +#include "SM_Scene.h" +#include "SM_ClientObjectInfo.h" + +#include "KX_SumoPhysicsController.h" + +GEN_Map<GEN_HashedPtr,DT_ShapeHandle> map_gamemesh_to_sumoshape; + +// forward declarations +void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,DT_SceneHandle solidscene,class SM_Object* sumoObj,const char* matname,bool isDynamic,bool isActor); +DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj); + + +void KX_ConvertSumoObject( class KX_GameObject* gameobj, + class RAS_MeshObject* meshobj, + class KX_Scene* kxscene, + PHY_ShapeProps* kxshapeprops, + PHY_MaterialProps* kxmaterial, + struct KX_ObjectProperties* objprop) + + +{ + + SM_ShapeProps* smprop = new SM_ShapeProps; + + smprop->m_ang_drag = kxshapeprops->m_ang_drag; + smprop->m_do_anisotropic = kxshapeprops->m_do_anisotropic; + smprop->m_do_fh = kxshapeprops->m_do_fh; + smprop->m_do_rot_fh = kxshapeprops->m_do_rot_fh ; + smprop->m_friction_scaling[0] = kxshapeprops->m_friction_scaling[0]; + smprop->m_friction_scaling[1] = kxshapeprops->m_friction_scaling[1]; + smprop->m_friction_scaling[2] = kxshapeprops->m_friction_scaling[2]; + smprop->m_inertia = kxshapeprops->m_inertia; + smprop->m_lin_drag = kxshapeprops->m_lin_drag; + smprop->m_mass = kxshapeprops->m_mass; + + + SM_MaterialProps* smmaterial = new SM_MaterialProps; + + smmaterial->m_fh_damping = kxmaterial->m_fh_damping; + smmaterial->m_fh_distance = kxmaterial->m_fh_distance; + smmaterial->m_fh_normal = kxmaterial->m_fh_normal; + smmaterial->m_fh_spring = kxmaterial->m_fh_spring; + smmaterial->m_friction = kxmaterial->m_friction; + smmaterial->m_restitution = kxmaterial->m_restitution; + + class SumoPhysicsEnvironment* sumoEnv = + (SumoPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); + + SM_Scene* sceneptr = sumoEnv->GetSumoScene(); + + + + SM_Object* sumoObj=NULL; + + if (objprop->m_dyna) + { + + DT_ShapeHandle shape = DT_Sphere(0.0); + + if (objprop->m_ghost) + { + + sumoObj = new SM_Object(shape,NULL,smprop,NULL); + } else + { + sumoObj = new SM_Object(shape,smmaterial,smprop,NULL); + } + + double radius = objprop->m_radius; + + MT_Scalar margin = radius;//0.5; + sumoObj->setMargin(margin); + + //if (bRigidBody) + //{ + if (objprop->m_in_active_layer) + { + DT_AddObject(sumoEnv->GetSolidScene(), + sumoObj->getObjectHandle()); + } + //} + + if (objprop->m_angular_rigidbody) + { + sumoObj->setRigidBody(true); + } else + { + sumoObj->setRigidBody(false); + } + + bool isDynamic = true; + bool isActor = true; + + BL_RegisterSumoObject(gameobj,sceneptr,sumoEnv->GetSolidScene(),sumoObj,NULL,isDynamic,isActor); + + } + else { + // non physics object + if (meshobj) + { + int numpolys = meshobj->NumPolygons(); + + { + + DT_ShapeHandle complexshape=0; + + if (objprop->m_implicitbox) + { + complexshape = DT_Box(objprop->m_boundingbox.m_extends[0],objprop->m_boundingbox.m_extends[1],objprop->m_boundingbox.m_extends[2]); + } else + { + if (numpolys>0) + { + complexshape = CreateShapeFromMesh(meshobj); + } + } + + if (complexshape) + { + SM_Object *dynamicParent = NULL; + + if (objprop->m_dynamic_parent) + { + // problem is how to find the dynamic parent + // in the scenegraph + KX_SumoPhysicsController* sumoctrl = + (KX_SumoPhysicsController*) + objprop->m_dynamic_parent->GetPhysicsController(); + + if (sumoctrl) + { + dynamicParent = sumoctrl->GetSumoObject(); + } + + assert(dynamicParent); + } + + + if (objprop->m_ghost) + { + sumoObj = new SM_Object(complexshape,NULL,NULL, dynamicParent); + } else + { + sumoObj = new SM_Object(complexshape,smmaterial,NULL, dynamicParent); + } + + if (objprop->m_in_active_layer) + { + DT_AddObject(sumoEnv->GetSolidScene(), + sumoObj->getObjectHandle()); + } + + + const STR_String& matname=meshobj->GetMaterialName(0); + + + BL_RegisterSumoObject(gameobj,sceneptr, + sumoEnv->GetSolidScene(),sumoObj, + matname.ReadPtr(), + objprop->m_dyna, + objprop->m_isactor); + + } + } + } + } + + // physics object get updated here ! + + + // lazy evaluation because Havok doesn't support scaling !gameobj->UpdateTransform(); + + if (objprop->m_in_active_layer && sumoObj) + { + sceneptr->add(*sumoObj); + } + +} + + + +void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,DT_SceneHandle solidscene,class SM_Object* sumoObj,const char* matname,bool isDynamic,bool isActor) { + + + + //gameobj->SetDynamic(isDynamic); + + PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); + + // need easy access, not via 'node' etc. + KX_SumoPhysicsController* physicscontroller = new KX_SumoPhysicsController(sumoScene,solidscene,sumoObj,motionstate,isDynamic); + gameobj->SetPhysicsController(physicscontroller); + physicscontroller->setClientInfo(gameobj); + + gameobj->GetSGNode()->AddSGController(physicscontroller); + + //gameobj->GetClientInfo()->m_type = (isActor ? 1 : 0); + //gameobj->GetClientInfo()->m_clientobject = gameobj; + + // store materialname in auxinfo, needed for touchsensors + //gameobj->GetClientInfo()->m_auxilary_info = (matname? (void*)(matname+2) : NULL); + + physicscontroller->SetObject(gameobj->GetSGNode()); + + //gameobj->SetDynamicsScaling(MT_Vector3(1.0, 1.0, 1.0)); + +}; + + + +DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj) +{ + + DT_ShapeHandle* shapeptr = map_gamemesh_to_sumoshape[GEN_HashedPtr(meshobj)]; + if (shapeptr) + { + return *shapeptr; + } + + // todo: shared meshes + DT_ShapeHandle shape = DT_NewComplexShape(); + int p=0; + int numpolys = meshobj->NumPolygons(); + if (!numpolys) + { + return NULL; + } + int numvalidpolys = 0; + + + + for (p=0;p<meshobj->m_triangle_indices.size();p++) + { + RAS_TriangleIndex& idx = meshobj->m_triangle_indices[p]; + + // only add polygons that have the collisionflag set + if (idx.m_collider) + { + DT_Begin(); + for (int v=0;v<3;v++) + { + int num = meshobj->m_xyz_index_to_vertex_index_mapping[idx.m_index[v]].size(); + if (num != 1) + { + int i=0; + } + RAS_MatArrayIndex& vertindex = meshobj->m_xyz_index_to_vertex_index_mapping[idx.m_index[v]][0]; + + numvalidpolys++; + + { + const MT_Point3& pt = meshobj->GetVertex(vertindex.m_array, + vertindex.m_index, + (RAS_IPolyMaterial*)vertindex.m_matid)->xyz(); + DT_Vertex(pt[0],pt[1],pt[2]); + } + } + DT_End(); + } + } + + DT_EndComplexShape(); + + if (numvalidpolys > 0) + { + map_gamemesh_to_sumoshape.insert(GEN_HashedPtr(meshobj),shape); + return shape; + } + + // memleak... todo: delete shape + return NULL; +} + + +void KX_ClearSumoSharedShapes() +{ + int numshapes = map_gamemesh_to_sumoshape.size(); + for (int i=0;i<numshapes ;i++) + { + DT_ShapeHandle shape = *map_gamemesh_to_sumoshape.at(i); + DT_DeleteShape(shape); + } + + map_gamemesh_to_sumoshape.clear(); +} + + + + + +#endif //USE_SUMO_SOLID + + +#ifdef USE_ODE + +void KX_ConvertODEEngineObject(KX_GameObject* gameobj, + RAS_MeshObject* meshobj, + KX_Scene* kxscene, + struct PHY_ShapeProps* shapeprops, + struct PHY_MaterialProps* smmaterial, + struct KX_ObjectProperties* objprop) +{ + // not yet, future extension :) + bool dyna=objprop->m_dyna; + bool fullRigidBody= ( objprop->m_dyna && objprop->m_angular_rigidbody) != 0; + bool phantom = objprop->m_ghost; + class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); + + class ODEPhysicsEnvironment* odeEnv = + (ODEPhysicsEnvironment*)kxscene->GetPhysicsEnvironment(); + + dxSpace* space = odeEnv->GetOdeSpace(); + dxWorld* world = odeEnv->GetOdeWorld(); + + if (!objprop->m_implicitsphere && + MT_fuzzyZero(objprop->m_boundingbox.m_extends[0]) || + MT_fuzzyZero(objprop->m_boundingbox.m_extends[1]) || + MT_fuzzyZero(objprop->m_boundingbox.m_extends[2]) + ) + { + + } else + { + + KX_OdePhysicsController* physicscontroller = + new KX_OdePhysicsController( + dyna, + fullRigidBody, + phantom, + motionstate, + space, + world, + shapeprops->m_mass, + smmaterial->m_friction, + smmaterial->m_restitution, + objprop->m_implicitsphere, + objprop->m_boundingbox.m_center, + objprop->m_boundingbox.m_extends, + objprop->m_radius + ); + + gameobj->SetPhysicsController(physicscontroller); + physicscontroller->setClientInfo(gameobj); + gameobj->GetSGNode()->AddSGController(physicscontroller); + + bool isActor = objprop->m_isactor; + STR_String materialname; + if (meshobj) + materialname = meshobj->GetMaterialName(0); + + const char* matname = materialname.ReadPtr(); + + + physicscontroller->SetObject(gameobj->GetSGNode()); + + } +} + + +#endif // USE_ODE diff --git a/source/gameengine/Ketsji/KX_EmptyObject.cpp b/source/gameengine/Ketsji/KX_EmptyObject.cpp new file mode 100644 index 00000000000..d3b120066d9 --- /dev/null +++ b/source/gameengine/Ketsji/KX_EmptyObject.cpp @@ -0,0 +1,32 @@ +/** + * $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_EmptyObject.h" diff --git a/source/gameengine/Ketsji/KX_EmptyObject.h b/source/gameengine/Ketsji/KX_EmptyObject.h new file mode 100644 index 00000000000..472cabe047e --- /dev/null +++ b/source/gameengine/Ketsji/KX_EmptyObject.h @@ -0,0 +1,45 @@ +/** + * $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_EMPTYOBJECT +#define __KX_EMPTYOBJECT +#include "KX_GameObject.h" + +class KX_EmptyObject : public KX_GameObject +{ +public: + KX_EmptyObject(void* sgReplicationInfo,SG_Callbacks callbacks) : + KX_GameObject(sgReplicationInfo,callbacks) + {}; + virtual ~KX_EmptyObject() {}; + +}; +#endif //__KX_EMPTYOBJECT diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp new file mode 100644 index 00000000000..240cef164a3 --- /dev/null +++ b/source/gameengine/Ketsji/KX_GameActuator.cpp @@ -0,0 +1,186 @@ +/** +* global game stuff +* +* $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_IActuator.h" +#include "KX_GameActuator.h" +//#include <iostream> +#include "KX_Scene.h" +#include "KX_KetsjiEngine.h" + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_GameActuator::KX_GameActuator(SCA_IObject *gameobj, + int mode, + const STR_String& filename, + const STR_String& loadinganimationname, + KX_Scene* scene, + KX_KetsjiEngine* ketsjiengine, + PyTypeObject* T) + : SCA_IActuator(gameobj, T) +{ + m_mode = mode; + m_filename = filename; + m_loadinganimationname = loadinganimationname; + m_scene = scene; + m_ketsjiengine = ketsjiengine; +} /* End of constructor */ + + + +KX_GameActuator::~KX_GameActuator() +{ + // there's nothing to be done here, really.... +} /* end of destructor */ + + + +CValue* KX_GameActuator::GetReplica() +{ + KX_GameActuator* replica = new KX_GameActuator(*this); + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +} + + + +bool KX_GameActuator::Update(double curtime, double deltatime) +{ + bool result = false; + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) + return false; // do nothing on negative events + + switch (m_mode) + { + case KX_GAME_LOAD: + case KX_GAME_START: + { + if (m_ketsjiengine) + { + STR_String exitstring = "start other game"; + m_ketsjiengine->RequestExit(KX_EXIT_REQUEST_START_OTHER_GAME); + m_ketsjiengine->SetNameNextGame(m_filename); + m_scene->AddDebugProperty((this)->GetParent(), exitstring); + } + + break; + } + case KX_GAME_RESTART: + { + if (m_ketsjiengine) + { + STR_String exitstring = "restarting game"; + m_ketsjiengine->RequestExit(KX_EXIT_REQUEST_RESTART_GAME); + m_scene->AddDebugProperty((this)->GetParent(), exitstring); + } + break; + } + case KX_GAME_QUIT: + { + if (m_ketsjiengine) + { + STR_String exitstring = "quiting game"; + m_ketsjiengine->RequestExit(KX_EXIT_REQUEST_QUIT_GAME); + m_scene->AddDebugProperty((this)->GetParent(), exitstring); + } + break; + } + default: + ; /* do nothing? this is an internal error !!! */ + } + + return false; +} + + + + + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_GameActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_SceneActuator", + sizeof(KX_GameActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + + + +PyParentObject KX_GameActuator::Parents[] = +{ + &KX_GameActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + + +PyMethodDef KX_GameActuator::Methods[] = +{ + {NULL,NULL} //Sentinel +}; + + + +PyObject* KX_GameActuator::_getattr(char* attr) +{ + _getattr_up(SCA_IActuator); +} + + diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h new file mode 100644 index 00000000000..7f2af86db42 --- /dev/null +++ b/source/gameengine/Ketsji/KX_GameActuator.h @@ -0,0 +1,86 @@ + +// +// actuator for global game stuff +// +// $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_GAMEACTUATOR +#define __KX_GAMEACTUATOR + +#include "SCA_IActuator.h" + +class KX_GameActuator : public SCA_IActuator +{ + Py_Header; + int m_mode; + bool m_restart; + STR_String m_filename; + STR_String m_loadinganimationname; + class KX_Scene* m_scene; + class KX_KetsjiEngine* m_ketsjiengine; + + public: + enum KX_GameActuatorMode + { + KX_GAME_NODEF = 0, + KX_GAME_LOAD, + KX_GAME_START, + KX_GAME_RESTART, + KX_GAME_QUIT, + KX_GAME_MAX + + }; + + KX_GameActuator(SCA_IObject* gameobj, + int mode, + const STR_String& filename, + const STR_String& loadinganimationname, + KX_Scene* scene, + KX_KetsjiEngine* ketsjiEngine, + PyTypeObject* T=&Type); + virtual ~KX_GameActuator(); + + virtual CValue* GetReplica(); + + virtual bool Update(double curtime,double deltatime); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + + +}; /* end of class KX_GameActuator */ + +#endif + diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp new file mode 100644 index 00000000000..1f8b3a8e1ac --- /dev/null +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -0,0 +1,1096 @@ +/** + * $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 ***** + * Game object wrapper + */ + +#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 + + +#define KX_INERTIA_INFINITE 10000 +#include "RAS_IPolygonMaterial.h" +#include "KX_GameObject.h" +#include "RAS_MeshObject.h" +#include "KX_MeshProxy.h" +#include <stdio.h> // printf +#include "SG_Controller.h" +#include "KX_IPhysicsController.h" +#include "SG_Node.h" +#include "SG_Controller.h" +#include "KX_ClientObjectInfo.h" +#include "RAS_BucketManager.h" + +// This file defines relationships between parents and children +// in the game engine. + +#include "KX_SG_NodeRelationships.h" + +KX_GameObject::KX_GameObject( + void* sgReplicationInfo, + SG_Callbacks callbacks, + PyTypeObject* T +) : + SCA_IObject(T), + m_bUseObjectColor(false), + m_bDyna(false), + m_bSuspendDynamics(false), + m_pPhysicsController1(NULL), + m_bVisible(true) +{ + m_ignore_activity_culling = false; + m_pClient_info = new KX_ClientObjectInfo(); + m_pSGNode = new SG_Node(this,sgReplicationInfo,callbacks); + + // define the relationship between this node and it's parent. + + KX_NormalParentRelation * parent_relation = + KX_NormalParentRelation::New(); + m_pSGNode->SetParentRelation(parent_relation); + + +}; + + + +KX_GameObject::~KX_GameObject() +{ + // is this delete somewhere ? + //if (m_sumoObj) + // delete m_sumoObj; + delete m_pClient_info; + //if (m_pSGNode) + // delete m_pSGNode; + +} + + + +CValue* KX_GameObject:: Calc(VALUE_OPERATOR op, CValue *val) +{ + return NULL; +} + + + +CValue* KX_GameObject::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) +{ + return NULL; +} + + + +const STR_String & KX_GameObject::GetText() +{ + return m_text; +} + + + +float KX_GameObject::GetNumber() +{ + return 0; +} + + + +STR_String KX_GameObject::GetName() +{ + return m_name; +} + + + +void KX_GameObject::SetName(STR_String name) +{ + m_name = name; +}; // Set the name of the value + + + +void KX_GameObject::ReplicaSetName(STR_String name) +{ +} + + + + + + +KX_IPhysicsController* KX_GameObject::GetPhysicsController() +{ + return m_pPhysicsController1; +} + + + + + +KX_GameObject* KX_GameObject::GetParent() +{ + KX_GameObject* result = NULL; + SG_Node* node = m_pSGNode; + + while (node && !result) + { + node = node->GetSGParent(); + if (node) + result = (KX_GameObject*)node->GetSGClientObject(); + } + + if (result) + result->AddRef(); + + return result; + +} + + + +void KX_GameObject::ProcessReplica(KX_GameObject* replica) +{ + replica->m_pPhysicsController1 = NULL; + replica->m_pSGNode = NULL; + replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info); + replica->m_pClient_info->m_clientobject = replica; +} + + + +CValue* KX_GameObject::GetReplica() +{ + KX_GameObject* replica = new KX_GameObject(*this); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + ProcessReplica(replica); + + return replica; +} + + + +void KX_GameObject::ApplyForce(const MT_Vector3& force,bool local) +{ + if (m_pPhysicsController1) + m_pPhysicsController1->ApplyForce(force,local); +} + + + +void KX_GameObject::ApplyTorque(const MT_Vector3& torque,bool local) +{ + if (m_pPhysicsController1) + m_pPhysicsController1->ApplyTorque(torque,local); +} + + + +void KX_GameObject::ApplyMovement(const MT_Vector3& dloc,bool local) +{ + if (this->IsDynamic()) + { + m_pPhysicsController1->RelativeTranslate(dloc,local); + } + else + { + GetSGNode()->RelativeTranslate(dloc,GetSGNode()->GetSGParent(),local); + } +} + + + +void KX_GameObject::ApplyRotation(const MT_Vector3& drot,bool local) +{ + MT_Matrix3x3 rotmat(drot); + + if (this->IsDynamic()) //m_pPhysicsController) + m_pPhysicsController1->RelativeRotate(rotmat.transposed(),local); + else + // in worldspace + GetSGNode()->RelativeRotate(rotmat.transposed(),local); +} + + + +/** +GetOpenGL Matrix, returns an OpenGL 'compatible' matrix +*/ +double* KX_GameObject::GetOpenGLMatrix() +{ + // todo: optimize and only update if necessary + double* fl = m_OpenGL_4x4Matrix.getPointer(); + MT_Transform trans; + + trans.setOrigin(GetSGNode()->GetWorldPosition()); + trans.setBasis(GetSGNode()->GetWorldOrientation()); + + MT_Vector3 scaling = GetSGNode()->GetWorldScaling(); + + trans.scale(scaling[0], scaling[1], scaling[2]); + trans.getValue(fl); + + return fl; +} + + + +void KX_GameObject::Bucketize() +{ + double* fl = GetOpenGLMatrix(); + + for (int i=0;i<m_meshes.size();i++) + m_meshes[i]->Bucketize(fl, this, m_bUseObjectColor, m_objectColor); +} + + + +void KX_GameObject::RemoveMeshes() +{ + double* fl = GetOpenGLMatrix(); + + for (int i=0;i<m_meshes.size();i++) + m_meshes[i]->RemoveFromBuckets(fl, this); + + //note: meshes can be shared, and are deleted by KX_BlenderSceneConverter + + m_meshes.clear(); +} + + + +void KX_GameObject::UpdateNonDynas() +{ + if (m_pPhysicsController1) + { + m_pPhysicsController1->SetSumoTransform(true); + } +} + + + +void KX_GameObject::UpdateTransform() +{ + if (m_pPhysicsController1) + { + m_pPhysicsController1->SetSumoTransform(false); + } +} + + + +void KX_GameObject::SetDebugColor(unsigned int bgra) +{ + for (int i=0;i<m_meshes.size();i++) + m_meshes[i]->DebugColor(bgra); +} + + + +void KX_GameObject::ResetDebugColor() +{ + SetDebugColor(0xff000000); +} + + + +void KX_GameObject::UpdateIPO(float curframetime, + bool recurse, + bool ipo_as_force, + bool force_local) +{ + + // The ipo-actuator needs a sumo reference... this is retrieved (unfortunately) + // by the iposgcontr itself... +// ipocontr->SetSumoReference(gameobj->GetSumoScene(), +// gameobj->GetSumoObject()); + + + // The ipo has to be treated as a force, and not a displacement! + // For this case, we send some settings to the controller. This + // may need some caching... + if (ipo_as_force) { + SGControllerList::iterator it = GetSGNode()->GetSGControllerList().begin(); + + while (it != GetSGNode()->GetSGControllerList().end()) { + (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, ipo_as_force); + (*it)->SetOption(SG_Controller::SG_CONTR_IPO_FORCES_ACT_LOCAL, force_local); + it++; + } + } + + // The rest is the 'normal' update procedure. + GetSGNode()->SetSimulatedTime(curframetime,recurse); + GetSGNode()->UpdateWorldData(curframetime); + UpdateTransform(); +} + + +/* +void KX_GameObject::RegisterSumoObject(class SM_Scene* sumoScene, + DT_SceneHandle solidscene, + class SM_Object* sumoObj, + const char* matname, + bool isDynamic, + bool isActor) +{ + m_bDyna = isDynamic; + + // need easy access, not via 'node' etc. + m_pPhysicsController = new KX_PhysicsController(sumoScene,solidscene,sumoObj,isDynamic); + + GetSGNode()->AddSGController(m_pPhysicsController); + + m_pClient_info->m_type = (isActor ? 1 : 0); + m_pClient_info->m_clientobject = this; + + // store materialname in auxinfo, needed for touchsensors + m_pClient_info->m_auxilary_info = (matname? (void*)(matname+2) : NULL); + m_pPhysicsController->SetObject(this->GetSGNode()); +} +*/ + +bool +KX_GameObject::GetVisible( + void + ) +{ + return m_bVisible; +} + +void +KX_GameObject::SetVisible( + bool v + ) +{ + m_bVisible = v; +} + +// used by Python, and the actuatorshould _not_ be misused by the +// scene! +void +KX_GameObject::MarkVisible( + bool visible + ) +{ + /* If explicit visibility settings are used, this is + * determined on this level. Maybe change this to mesh level + * later on? */ + + for (int i=0;i<m_meshes.size();i++) + { + double* fl = GetOpenGLMatrix(); + m_meshes[i]->MarkVisible(fl,this,visible,m_bUseObjectColor,m_objectColor); + } +} + + +// Always use the flag? +void +KX_GameObject::MarkVisible( + void + ) +{ + for (int i=0;i<m_meshes.size();i++) + { + double* fl = GetOpenGLMatrix(); + m_meshes[i]->MarkVisible(fl, + this, + m_bVisible, + m_bUseObjectColor, + m_objectColor + ); + } +} + +void KX_GameObject::addLinearVelocity(const MT_Vector3& lin_vel,bool local) +{ +// if (m_pPhysicsController1) +// m_pPhysicsController1->AddLinearVelocity(lin_vel,local); +} + + + +void KX_GameObject::setLinearVelocity(const MT_Vector3& lin_vel,bool local) +{ + if (m_pPhysicsController1) + m_pPhysicsController1->SetLinearVelocity(lin_vel,local); +} + + + +void KX_GameObject::setAngularVelocity(const MT_Vector3& ang_vel,bool local) +{ + if (m_pPhysicsController1) + m_pPhysicsController1->SetAngularVelocity(ang_vel,local); +} + + + +void KX_GameObject::SetObjectColor(const MT_Vector4& rgbavec) +{ + m_bUseObjectColor = true; + m_objectColor = rgbavec; +} + + + +MT_Vector3 KX_GameObject::GetLinearVelocity() +{ + MT_Vector3 velocity(0.0,0.0,0.0); + + if (m_pPhysicsController1) + { + velocity = m_pPhysicsController1->GetLinearVelocity(); + } + return velocity; + +} + + +// scenegraph node stuff + +void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans) +{ + if (m_pPhysicsController1) + { + m_pPhysicsController1->setPosition(trans); + } + + GetSGNode()->SetLocalPosition(trans); +} + + + +void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot) +{ + if (m_pPhysicsController1) + { + m_pPhysicsController1->setOrientation(rot.getRotation()); + } + + GetSGNode()->SetLocalOrientation(rot); +} + + + +void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale) +{ + if (m_pPhysicsController1) + { + m_pPhysicsController1->setScaling(scale); + } + + GetSGNode()->SetLocalScale(scale); +} + + + +void KX_GameObject::NodeSetRelativeScale(const MT_Vector3& scale) +{ + GetSGNode()->RelativeScale(scale); +} + + + +void KX_GameObject::NodeUpdateGS(double time,bool bInitiator) +{ + GetSGNode()->UpdateWorldData(time); +} + + + +const MT_Matrix3x3& KX_GameObject::NodeGetWorldOrientation() const +{ + return GetSGNode()->GetWorldOrientation(); +} + + + +const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const +{ + return GetSGNode()->GetWorldScaling(); +} + + + +const MT_Point3& KX_GameObject::NodeGetWorldPosition() const +{ + return GetSGNode()->GetWorldPosition(); +} + +/* Suspend/ resume: for the dynamic behaviour, there is a simple + * method. For the residual motion, there is not. I wonder what the + * correct solution is for Sumo. Remove from the motion-update tree? + * + * So far, only switch the physics and logic. + * */ + +void KX_GameObject::Resume(void) +{ + if (m_suspended) { + SCA_IObject::Resume(); + GetPhysicsController()->RestoreDynamics(); + + m_suspended = false; + } +} + +void KX_GameObject::Suspend(void) +{ + if ((!m_ignore_activity_culling) + && (!m_suspended)) { + SCA_IObject::Suspend(); + GetPhysicsController()->SuspendDynamics(); + m_suspended = true; + } +} + + + + +/* ------- python stuff ---------------------------------------------------*/ + + + + +PyMethodDef KX_GameObject::Methods[] = { + {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS}, + {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_VARARGS}, + {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_VARARGS}, + {"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS}, + {"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS}, + {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_VARARGS}, + {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_VARARGS}, + {"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_VARARGS}, + {"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_VARARGS}, + {"applyImpulse", (PyCFunction) KX_GameObject::sPyApplyImpulse, METH_VARARGS}, + {"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics,METH_VARARGS}, + {"restoreDynamics", (PyCFunction)KX_GameObject::sPyRestoreDynamics,METH_VARARGS}, + {"enableRigidBody", (PyCFunction)KX_GameObject::sPyEnableRigidBody,METH_VARARGS}, + {"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_VARARGS}, + {"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_VARARGS}, + {"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS}, + {"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS}, + + + {NULL,NULL} //Sentinel +}; + + + + +bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args, + MT_Vector3& pos, + MT_Vector3& pos2) +{ + PyObject* pylist; + PyObject* pylist2; + bool error = (PyArg_ParseTuple(args,"OO",&pylist,&pylist2)) != 0; + + pos = ConvertPythonPylist(pylist); + pos2 = ConvertPythonPylist(pylist2); + + return error; +} + + + +PyObject* KX_GameObject::sPySetPosition(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return ((KX_GameObject*) self)->PySetPosition(self, args, kwds); +} + + + +PyObject* KX_GameObject::PyGetPosition(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + MT_Point3 pos = NodeGetWorldPosition(); + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index])); + } + + return resultlist; + +} + + + +PyTypeObject KX_GameObject::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_GameObject", + sizeof(KX_GameObject), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + + + +PyParentObject KX_GameObject::Parents[] = { + &KX_GameObject::Type, + &SCA_IObject::Type, + &CValue::Type, + NULL +}; + + + + +PyObject* KX_GameObject::_getattr(char* attr) +{ + _getattr_up(SCA_IObject); +} + + + +PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + // only can get the velocity if we have a physics object connected to us... + MT_Vector3 velocity = GetLinearVelocity(); + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(velocity[index])); + } + + return resultlist; +} + + + +PyObject* KX_GameObject::PySetVisible(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int visible = 1; + + if (PyArg_ParseTuple(args,"i",&visible)) + { + MarkVisible(visible!=0); + m_bVisible = (visible!=0); + } + else + { + return NULL; + } + Py_Return; + +} + + + +PyObject* KX_GameObject::PyGetVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + // only can get the velocity if we have a physics object connected to us... + MT_Vector3 velocity(0.0,0.0,0.0); + MT_Point3 point(0.0,0.0,0.0); + + + MT_Point3 pos; + PyObject* pylist; + bool error = false; + + int len = PyTuple_Size(args); + + if ((len > 0) && PyArg_ParseTuple(args,"O",&pylist)) + { + if (pylist->ob_type == &CListValue::Type) + { + CListValue* listval = (CListValue*) pylist; + if (listval->GetCount() == 3) + { + int index; + for (index=0;index<3;index++) + { + pos[index] = listval->GetValue(index)->GetNumber(); + } + } else + { + error = true; + } + + } else + { + + // assert the list is long enough... + int numitems = PyList_Size(pylist); + if (numitems == 3) + { + int index; + for (index=0;index<3;index++) + { + pos[index] = PyFloat_AsDouble(PyList_GetItem(pylist,index)); + } + } + else + { + error = true; + } + } + + if (!error) + point = pos; + } + + + if (m_pPhysicsController1) + { + velocity = m_pPhysicsController1->GetVelocity(point); + } + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(velocity[index])); + } + + return resultlist; +} + + + +PyObject* KX_GameObject::PyGetMass(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + PyObject* pymass = NULL; + + float mass = GetPhysicsController()->GetMass(); + pymass = PyFloat_FromDouble(mass); + + if (pymass) + return pymass; + + Py_Return; +} + + + +PyObject* KX_GameObject::PyGetReactionForce(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + // only can get the velocity if we have a physics object connected to us... + + MT_Vector3 reaction_force = GetPhysicsController()->getReactionForce(); + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index, + PyFloat_FromDouble(reaction_force[index])); + } + + return resultlist; +} + + + +PyObject* KX_GameObject::PyEnableRigidBody(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + GetPhysicsController()->setRigidBody(true); + + Py_Return; +} + + + +PyObject* KX_GameObject::PyDisableRigidBody(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + GetPhysicsController()->setRigidBody(false); + + Py_Return; +} + + + +PyObject* KX_GameObject::PyGetParent(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + KX_GameObject* parent = this->GetParent(); + if (parent) + return parent; + Py_Return; +} + + + +PyObject* KX_GameObject::PyGetMesh(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + if (m_meshes.size() > 0) + { + KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[0]); + return meshproxy; + } + + Py_Return; +} + + + +PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + MT_Point3 attach(0, 1, 0); + MT_Vector3 impulse(1, 0, 0); + + if (ConvertPythonVectorArgs(args,attach,impulse)) + { + if (m_pPhysicsController1) + { + m_pPhysicsController1->applyImpulse(attach, impulse); + } + + } + + Py_Return; +} + + + +PyObject* KX_GameObject::PySuspendDynamics(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + if (m_bSuspendDynamics) + { + Py_Return; + } + + if (m_pPhysicsController1) + { + m_pPhysicsController1->SuspendDynamics(); + } + m_bSuspendDynamics = true; + + Py_Return; +} + + + +PyObject* KX_GameObject::PyRestoreDynamics(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + if (!m_bSuspendDynamics) + { + Py_Return; + } + + if (m_pPhysicsController1) + { + m_pPhysicsController1->RestoreDynamics(); + } + m_bSuspendDynamics = false; + + Py_Return; +} + + + +PyObject* KX_GameObject::PyGetOrientation(PyObject* self, + PyObject* args, + PyObject* kwds) //keywords +{ + // do the conversion of a C++ matrix to a python list + + PyObject* resultlist = PyList_New(3); + + + int row,col; + const MT_Matrix3x3& orient = NodeGetWorldOrientation(); + + int index = 0; + for (row=0;row<3;row++) + { + PyObject* veclist = PyList_New(3); + + for (col=0;col<3;col++) + { + const MT_Scalar fl = orient[row][col]; + PyList_SetItem(veclist,col,PyFloat_FromDouble(fl)); + } + PyList_SetItem(resultlist,row,veclist); + + } + return resultlist; +} + + + +PyObject* KX_GameObject::PySetOrientation(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + MT_Matrix3x3 matrix; + + PyObject* pylist; + bool error = false; + int row,col; + + PyArg_ParseTuple(args,"O",&pylist); + + if (pylist->ob_type == &CListValue::Type) + { + CListValue* listval = (CListValue*) pylist; + if (listval->GetCount() == 3) + { + for (row=0;row<3;row++) // each row has a 3-vector [x,y,z] + { + CListValue* vecval = (CListValue*)listval->GetValue(row); + for (col=0;col<3;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 == 3) + { + for (row=0;row<3;row++) // each row has a 3-vector [x,y,z] + { + + PyObject* veclist = PyList_GetItem(pylist,row); // here we have a vector3 list + for (col=0;col<3;col++) + { + matrix[row][col] = PyFloat_AsDouble(PyList_GetItem(veclist,col)); + + } + } + } + else + { + error = true; + } + } + + if (!error) + { + if (m_pPhysicsController1) + { + m_pPhysicsController1->setOrientation(matrix.getRotation()); + } + NodeSetLocalOrientation(matrix); + } + + Py_INCREF(Py_None); + return Py_None; +} + + + +PyObject* KX_GameObject::PySetPosition(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + // make a general function for this, it's needed many times + + MT_Point3 pos = ConvertPythonVectorArg(args); + if (this->m_pPhysicsController1) + { + this->m_pPhysicsController1->setPosition(pos); + } + NodeSetLocalPosition(pos); + + Py_INCREF(Py_None); + return Py_None; +} + +PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + KX_IPhysicsController* ctrl = GetPhysicsController(); + int physid=0; + if (ctrl) + { + physid= (int)ctrl->GetUserData(); + } + return PyInt_FromLong(physid); +} + +/* --------------------------------------------------------------------- + * Some stuff taken from the header + * --------------------------------------------------------------------- */ +void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter) +{ + /* intentionally empty ? */ +} + diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h new file mode 100644 index 00000000000..c9c9ccafd0d --- /dev/null +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -0,0 +1,614 @@ +/* + * $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 ***** + * General KX game object. + */ + +#ifndef __KX_GAMEOBJECT +#define __KX_GAMEOBJECT + + +#ifdef WIN32 +// get rid of this stupid "warning 'this' used in initialiser list", generated by VC when including Solid/Sumo +#pragma warning (disable : 4355) +#endif + + +#include "ListValue.h" +#include "SCA_IObject.h" +#include "SG_Node.h" +#include "MT_Transform.h" +#include "MT_CmMatrix4x4.h" +#include "GEN_Map.h" +#include "GEN_HashedPtr.h" + +#define KX_FIXED_FRAME_PER_SEC 25.0f +#define KX_FIXED_SEC_PER_FRAME (1.0f / KX_FIXED_FRAME_PER_SEC) +#define KX_OB_DYNAMIC 1 + + +//Forward declarations. +struct KX_ClientObjectInfo; +class RAS_MeshObject; +class KX_IPhysicsController; +class SM_Object; + +class KX_GameObject : public SCA_IObject +{ + Py_Header; + + bool m_bDyna; + KX_ClientObjectInfo* m_pClient_info; + STR_String m_name; + STR_String m_text; + std::vector<RAS_MeshObject*> m_meshes; + + bool m_bSuspendDynamics; + bool m_bUseObjectColor; + MT_Vector4 m_objectColor; + + // Is this object set to be visible? Only useful for the + // visibility subsystem right now. + bool m_bVisible; + + KX_IPhysicsController* m_pPhysicsController1; + SG_Node* m_pSGNode; + +protected: + MT_CmMatrix4x4 m_OpenGL_4x4Matrix; + +public: + virtual void /* This function should be virtual - derived classed override it */ + Relink( + GEN_Map<GEN_HashedPtr, void*> *map + ); + + /** + * Compute an OpenGl compatable 4x4 matrix. Has the + * side effect of storing the result internally. The + * memory for the matrix remains the property of this class. + */ + double* + GetOpenGLMatrix( + ); + + /** + * Return a pointer to a MT_CmMatrix4x4 storing the + * opengl transformation for this object. This is updated + * by a call to GetOpenGLMatrix(). This class owns the + * memory for the returned matrix. + */ + + MT_CmMatrix4x4* + GetOpenGLMatrixPtr( + ) { + return &m_OpenGL_4x4Matrix; + }; + + /** + * Get a pointer to the game object that is the parent of + * this object. Or NULL if there is no parent. The returned + * object is part of a reference counting scheme. Calling + * this function ups the reference count on the returned + * object. It is the responsibility of the caller to decrement + * the reference count when you have finished with it. + */ + KX_GameObject* + GetParent( + ); + + + /** + * Construct a game object. This class also inherits the + * default constructors - use those with care! + */ + + KX_GameObject( + void* sgReplicationInfo, + SG_Callbacks callbacks, + PyTypeObject* T=&Type + ); + + virtual + ~KX_GameObject( + ); + + CValue* + AddRef() { + /* temporarily to find memleaks */ return CValue::AddRef(); + } + + /** + * @section Stuff which is here due to poor design. + * Inherited from CValue and needs an implementation. + * Do not expect these functions do to anything sensible. + */ + + /** + * Inherited from CValue -- does nothing! + */ + CValue* + Calc( + VALUE_OPERATOR op, + CValue *val + ); + + /** + * Inherited from CValue -- does nothing! + */ + CValue* + CalcFinal( + VALUE_DATA_TYPE dtype, + VALUE_OPERATOR op, + CValue *val + ); + + /** + * Inherited from CValue -- does nothing! + */ + const + STR_String & + GetText( + ); + + /** + * Inherited from CValue -- does nothing! + */ + float + GetNumber( + ); + + /** + * @section Inherited from CValue. These are the useful + * part of the CValue interface that this class implements. + */ + + /** + * Inherited from CValue -- returns the name of this object. + */ + STR_String + GetName( + ); + + /** + * Inherited from CValue -- set the name of this object. + */ + void + SetName( + STR_String name + ); + + /** + * Inherited from CValue -- does nothing. + */ + void + ReplicaSetName( + STR_String name + ); + + /** + * Inherited from CValue -- return a new copy of this + * instance allocated on the heap. Ownership of the new + * object belongs with the caller. + */ + CValue* + GetReplica( + ); + + /** + * Inherited from CValue -- Makes sure any internal + * data owned by this class is deep copied. Called internally + */ + void + ProcessReplica( + KX_GameObject* replica + ); + + /** + * Return the linear velocity of the game object. + */ + MT_Vector3 + GetLinearVelocity( + ); + + /** + * Quick'n'dirty obcolor ipo stuff + */ + + void + SetObjectColor( + const MT_Vector4& rgbavec + ); + + + + + /** + * @return a pointer to the physics controller owned by this class. + */ + + KX_IPhysicsController* + GetPhysicsController( + ) ; + + void SetPhysicsController + (KX_IPhysicsController* physicscontroller) + { m_pPhysicsController1 = physicscontroller;}; + + + /** + * @section Coordinate system manipulation functions + */ + + void + NodeSetLocalPosition( + const MT_Point3& trans + ); + + void + NodeSetLocalOrientation( + const MT_Matrix3x3& rot + ); + + void + NodeSetLocalScale( + const MT_Vector3& scale + ); + + void + NodeSetRelativeScale( + const MT_Vector3& scale + ); + + void + NodeUpdateGS( + double time, + bool bInitiator + ); + + const + MT_Matrix3x3& + NodeGetWorldOrientation( + ) const; + + const + MT_Vector3& + NodeGetWorldScaling( + ) const; + + const + MT_Point3& + NodeGetWorldPosition( + ) const; + + + /** + * @section scene graph node accessor functions. + */ + + SG_Node* + GetSGNode( + ) { + return m_pSGNode; + } + + const + SG_Node* + GetSGNode( + ) const { + return m_pSGNode; + } + + /** + * Set the Scene graph node for this game object. + * warning - it is your responsibility to make sure + * all controllers look at this new node. You must + * also take care of the memory associated with the + * old node. This class takes ownership of the new + * node. + */ + void + SetSGNode( + SG_Node* node + ){ + m_pSGNode = node; + } + + bool + IsDynamic( + ) const { + return m_bDyna; + } + + + /** + * @section Physics accessors for this node. + * + * All these calls get passed directly to the physics controller + * owned by this object. + * This is real interface bloat. Why not just use the physics controller + * directly? I think this is because the python interface is in the wrong + * place. + */ + + void + ApplyForce( + const MT_Vector3& force, bool local + ); + + void + ApplyTorque( + const MT_Vector3& torque, + bool local + ); + + void + ApplyRotation( + const MT_Vector3& drot, + bool local + ); + + void + ApplyMovement( + const MT_Vector3& dloc, + bool local + ); + + void + addLinearVelocity( + const MT_Vector3& lin_vel, + bool local + ); + + void + setLinearVelocity( + const MT_Vector3& lin_vel, + bool local + ); + + void + setAngularVelocity( + const MT_Vector3& ang_vel, + bool local + ); + + /** + * Update the physics object transform based upon the current SG_Node + * position. + */ + void + UpdateTransform( + ); + + /** + * Only update the transform if it's a non-dynamic object + */ + void + UpdateNonDynas( + ); + + /** + * Odd function to update an ipo. ??? + */ + void + UpdateIPO( + float curframetime, + bool resurse, + bool ipo_as_force, + bool force_ipo_local + ); + + /** + * @section Mesh accessor functions. + */ + + /** + * Run through the meshes associated with this + * object and bucketize them. See RAS_Mesh for + * more details on this function. Interesting to + * note that polygon bucketizing seems to happen on a per + * object basis. Which may explain why there is such + * a big performance gain when all static objects + * are joined into 1. + */ + void + Bucketize( + ); + + /** + * Clear the meshes associated with this class + * and remove from the bucketing system. + * Don't think this actually deletes any of the meshes. + */ + void + RemoveMeshes( + ); + + /** + * Add a mesh to the set of meshes associated with this + * node. Meshes added in this way are not deleted by this class. + * Make sure you call RemoveMeshes() before deleting the + * mesh though, + */ + void + AddMesh( + RAS_MeshObject* mesh + ){ + m_meshes.push_back(mesh); + } + + /** + * Pick out a mesh associated with the integer 'num'. + */ + RAS_MeshObject* + GetMesh( + int num + ) const { + return m_meshes[num]; + } + + /** + * Return the number of meshes currently associated with this + * game object. + */ + int + GetMeshCount( + ) const { + return m_meshes.size(); + } + + /** + * Set the debug color of the meshes associated with this + * class. Does this still work? + */ + void + SetDebugColor( + unsigned int bgra + ); + + /** + * Reset the debug color of meshes associated with this class. + */ + void + ResetDebugColor( + ); + + /** + * Set the visibility of the meshes associated with this + * object. + */ + void + MarkVisible( + bool visible + ); + + /** + * Set the visibility according to the visibility flag. + */ + void + MarkVisible( + void + ); + + + /** + * Was this object marked visible? (only for the ewxplicit + * visibility system). + */ + bool + GetVisible( + void + ); + + /** + * Set visibility flag of this object + */ + void + SetVisible( + bool b + ); + + + /** + * @section Logic bubbling methods. + */ + + /** + * Stop making progress + */ + void Suspend(void); + + /** + * Resume making progress + */ + void Resume(void); + + /** + * @section Python interface functions. + */ + + virtual + PyObject* + _getattr( + char *attr + ); + + PyObject* + PySetPosition( + PyObject* self, + PyObject* args, + PyObject* kwds + ); + + static + PyObject* + sPySetPosition( + PyObject* self, + PyObject* args, + PyObject* kwds + ); + + KX_PYMETHOD(KX_GameObject,GetPosition); + KX_PYMETHOD(KX_GameObject,GetLinearVelocity); + KX_PYMETHOD(KX_GameObject,GetVelocity); + KX_PYMETHOD(KX_GameObject,GetMass); + KX_PYMETHOD(KX_GameObject,GetReactionForce); + KX_PYMETHOD(KX_GameObject,GetOrientation); + KX_PYMETHOD(KX_GameObject,SetOrientation); + KX_PYMETHOD(KX_GameObject,SetVisible); + KX_PYMETHOD(KX_GameObject,SuspendDynamics); + KX_PYMETHOD(KX_GameObject,RestoreDynamics); + KX_PYMETHOD(KX_GameObject,EnableRigidBody); + KX_PYMETHOD(KX_GameObject,DisableRigidBody); + KX_PYMETHOD(KX_GameObject,ApplyImpulse); + KX_PYMETHOD(KX_GameObject,GetMesh); + KX_PYMETHOD(KX_GameObject,GetParent); + KX_PYMETHOD(KX_GameObject,GetPhysicsId); + +private : + + /** + * Random internal function to convert python function arguments + * to 2 vectors. + * @return true if conversion was possible. + */ + + bool + ConvertPythonVectorArgs( + PyObject* args, + MT_Vector3& pos, + MT_Vector3& pos2 + ); + +}; + + +#endif //__KX_GAMEOBJECT + diff --git a/source/gameengine/Ketsji/KX_IInterpolator.h b/source/gameengine/Ketsji/KX_IInterpolator.h new file mode 100644 index 00000000000..974f458681b --- /dev/null +++ b/source/gameengine/Ketsji/KX_IInterpolator.h @@ -0,0 +1,46 @@ +/** + * $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_IINTERPOLATOR_H +#define KX_IINTERPOLATOR_H + +#include <vector> + +class KX_IInterpolator { +public: + virtual ~KX_IInterpolator() {} + + virtual void Execute(float currentTime) const = 0; +}; + +typedef std::vector<KX_IInterpolator *> T_InterpolatorList; + +#endif diff --git a/source/gameengine/Ketsji/KX_IPOTransform.h b/source/gameengine/Ketsji/KX_IPOTransform.h new file mode 100644 index 00000000000..9f9f4a92602 --- /dev/null +++ b/source/gameengine/Ketsji/KX_IPOTransform.h @@ -0,0 +1,92 @@ +/** + * An abstract object you can move around in a 3d world, and has some logic + * + * $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_IPOTRANSFORM_H +#define KX_IPOTRANSFORM_H + +#include "MT_Transform.h" + +class KX_IPOTransform { +public: + KX_IPOTransform() : + m_position(0.0, 0.0, 0.0), + m_eulerAngles(0.0, 0.0, 0.0), + m_scaling(1.0, 1.0, 1.0), + m_deltaPosition(0.0, 0.0, 0.0), + m_deltaEulerAngles(0.0, 0.0, 0.0), + m_deltaScaling(0.0, 0.0, 0.0) + {} + + MT_Transform GetTransform() const { + return MT_Transform(m_position + m_deltaPosition, + MT_Matrix3x3(m_eulerAngles + m_deltaEulerAngles, + m_scaling + m_deltaScaling)); + } + + MT_Point3& GetPosition() { return m_position; } + MT_Vector3& GetEulerAngles() { return m_eulerAngles; } + MT_Vector3& GetScaling() { return m_scaling; } + + const MT_Point3& GetPosition() const { return m_position; } + const MT_Vector3& GetEulerAngles() const { return m_eulerAngles; } + const MT_Vector3& GetScaling() const { return m_scaling; } + + MT_Vector3& GetDeltaPosition() { return m_deltaPosition; } + MT_Vector3& GetDeltaEulerAngles() { return m_deltaEulerAngles; } + MT_Vector3& GetDeltaScaling() { return m_deltaScaling; } + + void SetPosition(const MT_Point3& pos) { m_position = pos; } + void SetEulerAngles(const MT_Vector3& eul) { m_eulerAngles = eul; } + void SetScaling(const MT_Vector3& scaling) { m_scaling = scaling; } + + void ClearDeltaStuff() { + m_deltaPosition.setValue(0.0, 0.0, 0.0); + m_deltaEulerAngles.setValue(0.0, 0.0, 0.0); + m_deltaScaling.setValue(0.0, 0.0, 0.0); + } + +protected: + MT_Point3 m_position; + MT_Vector3 m_eulerAngles; + MT_Vector3 m_scaling; + MT_Vector3 m_deltaPosition; + MT_Vector3 m_deltaEulerAngles; + MT_Vector3 m_deltaScaling; +}; + +#endif + + + + diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp new file mode 100644 index 00000000000..ea5617b017a --- /dev/null +++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp @@ -0,0 +1,193 @@ +/** + * $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 ***** + * Scenegraph controller for ipos. + */ + +#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 "KX_IPO_SGController.h" +#include "KX_ScalarInterpolator.h" +#include "KX_GameObject.h" + +// All objects should start on frame 1! Will we ever need an object to +// start on another frame, the 1.0 should change. +KX_IpoSGController::KX_IpoSGController() +: m_ipotime(1.0), + m_modify_position(false), + m_modify_orientation(false), + m_modify_scaling(false), + m_modified(true), + m_ipo_as_force(false), + m_force_ipo_acts_local(false) +{ + m_sumo_object = NULL; + m_game_object = NULL; + +} + + +void KX_IpoSGController::SetOption( + int option, + int value) +{ + switch (option) { + case SG_CONTR_IPO_IPO_AS_FORCE: + m_ipo_as_force = (value != 0); + m_modified = true; + break; + case SG_CONTR_IPO_FORCES_ACT_LOCAL: + m_force_ipo_acts_local = (value != 0); + m_modified = true; + break; + default: + ; /* just ignore the rest */ + } +} + + void +KX_IpoSGController::UpdateSumoReference( + ) +{ + if (m_game_object) { + m_sumo_object = 0;//m_game_object->GetSumoObject(); + } +} + + void +KX_IpoSGController::SetGameObject( + KX_GameObject* go + ) +{ + m_game_object = go; +} + + + +bool KX_IpoSGController::Update(double currentTime) +{ + if (m_modified) + { + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + (*i)->Execute(m_ipotime);//currentTime); + } + + SG_Spatial* ob = (SG_Spatial*)m_pObject; + + if (m_modify_position) { + if (m_ipo_as_force) { + /* + UpdateSumoReference(); + if (m_sumo_object && ob) { + m_sumo_object->applyCenterForce(m_force_ipo_acts_local ? + ob->GetWorldOrientation() * m_ipo_xform.GetPosition() : + m_ipo_xform.GetPosition()); + m_sumo_object->calcXform(); + } + */ + + } else { + ob->SetLocalPosition(m_ipo_xform.GetPosition()); + } + } + if (m_modify_orientation) { + if (m_ipo_as_force) { + /* + UpdateSumoReference(); + if (m_sumo_object && ob) { + m_sumo_object->applyTorque(m_force_ipo_acts_local ? + ob->GetWorldOrientation() * m_ipo_xform.GetEulerAngles() : + m_ipo_xform.GetEulerAngles()); + m_sumo_object->calcXform(); + } + */ + + } else { + ob->SetLocalOrientation(MT_Matrix3x3(m_ipo_xform.GetEulerAngles())); + } + } + if (m_modify_scaling) + ob->SetLocalScale(m_ipo_xform.GetScaling()); + + m_modified=false; + } + return false; +} + + +void KX_IpoSGController::AddInterpolator(KX_IInterpolator* interp) +{ + this->m_interpolators.push_back(interp); +} + +SG_Controller* KX_IpoSGController::GetReplica(class SG_Node* destnode) +{ + KX_IpoSGController* iporeplica = new KX_IpoSGController(*this); + // clear object that ipo acts on in the replica. + iporeplica->ClearObject(); + + // dirty hack, ask Gino for a better solution in the ipo implementation + // hacken en zagen, in what we call datahiding, not written for replication :( + + T_InterpolatorList oldlist = m_interpolators; + iporeplica->m_interpolators.clear(); + + T_InterpolatorList::iterator i; + for (i = oldlist.begin(); !(i == oldlist.end()); ++i) { + KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i)); + iporeplica->AddInterpolator(copyipo); + + MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget(); + int orgbase = (int)&m_ipo_xform; + int orgloc = (int)scaal; + int offset = orgloc-orgbase; + int newaddrbase = (int)&iporeplica->m_ipo_xform; + newaddrbase += offset; + MT_Scalar* blaptr = (MT_Scalar*) newaddrbase; + copyipo->SetNewTarget((MT_Scalar*)blaptr); + } + + return iporeplica; +} + +KX_IpoSGController::~KX_IpoSGController() +{ + + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + delete (*i); + } + +} diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.h b/source/gameengine/Ketsji/KX_IPO_SGController.h new file mode 100644 index 00000000000..201a0051881 --- /dev/null +++ b/source/gameengine/Ketsji/KX_IPO_SGController.h @@ -0,0 +1,111 @@ +/** + * $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 __IPO_SGCONTROLLER_H +#define __IPO_SGCONTROLLER_H + +#include "SG_Controller.h" +#include "SG_Spatial.h" + +#include "KX_IPOTransform.h" +#include "KX_IInterpolator.h" + +class KX_IpoSGController : public SG_Controller +{ + KX_IPOTransform m_ipo_xform; + T_InterpolatorList m_interpolators; + /* Why not bools? */ + short m_modify_position : 1; + short m_modify_orientation : 1; + short m_modify_scaling : 1; + + /** Interpret the ipo as a force rather than a displacement? */ + bool m_ipo_as_force; + + /** Ipo-as-force acts in local rather than in global coordinates? */ + bool m_force_ipo_acts_local; + + /** Were settings altered since the last update? */ + bool m_modified; + + /** Local time of this ipo.*/ + double m_ipotime; + + /** A reference to the sm scene an eventually associated physics object is in. */ +// class SM_Scene* m_sumo_scene; + + /** A reference an eventually associated physics object is in. */ + class SM_Object* m_sumo_object; + + /** A reference to the original game object. */ + class KX_GameObject* m_game_object; + +public: + KX_IpoSGController(); + + virtual ~KX_IpoSGController(); + + virtual SG_Controller* GetReplica(class SG_Node* destnode); + + void + SetOption( + int option, + int value + ); + + /** Set sumo data. */ + void UpdateSumoReference(); + /** Set reference to the corresponding game object. */ + void SetGameObject(class KX_GameObject*); + + void SetModifyPosition(bool modifypos) { + m_modify_position=modifypos; + } + void SetModifyOrientation(bool modifyorient) { + m_modify_orientation=modifyorient; + } + void SetModifyScaling(bool modifyscale) { + m_modify_scaling=modifyscale; + } + + KX_IPOTransform& GetIPOTransform() + { + return m_ipo_xform; + } + void AddInterpolator(KX_IInterpolator* interp); + virtual bool Update(double time); + virtual void SetSimulatedTime(double time) + { + m_ipotime = time; + m_modified = true; + } +}; +#endif //__IPO_SGCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.cpp b/source/gameengine/Ketsji/KX_IPhysicsController.cpp new file mode 100644 index 00000000000..5ef22dd4f74 --- /dev/null +++ b/source/gameengine/Ketsji/KX_IPhysicsController.cpp @@ -0,0 +1,45 @@ +/** + * $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_IPhysicsController.h" + + +KX_IPhysicsController::KX_IPhysicsController(bool dyna,void* userdata) + +: m_bDyna(dyna), + m_userdata(userdata), + m_suspendDynamics(false) +{ +}; + +KX_IPhysicsController::~KX_IPhysicsController() +{ +} diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h new file mode 100644 index 00000000000..997317c0df5 --- /dev/null +++ b/source/gameengine/Ketsji/KX_IPhysicsController.h @@ -0,0 +1,99 @@ +/** + * $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_IPHYSICSCONTROLLER_H +#define __KX_IPHYSICSCONTROLLER_H + +#include "SG_Controller.h" +#include "MT_Vector3.h" +#include "MT_Point3.h" +#include "MT_Matrix3x3.h" + +/** + Physics Controller, a special kind of Scene Graph Transformation Controller. + It get's callbacks from Physics in case a transformation change took place. + Each time the scene graph get's updated, the controller get's a chance + in the 'Update' method to reflect changed. +*/ + +class KX_IPhysicsController : public SG_Controller + +{ + +protected: + bool m_bDyna; + bool m_suspendDynamics; + void* m_userdata; +public: + KX_IPhysicsController(bool dyna,void* userdata); + virtual ~KX_IPhysicsController(); + + + virtual void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse)=0; + virtual void SetObject (SG_IObject* object)=0; + + virtual void RelativeTranslate(const MT_Vector3& dloc,bool local)=0; + virtual void RelativeRotate(const MT_Matrix3x3& drot,bool local)=0; + virtual void ApplyTorque(const MT_Vector3& torque,bool local)=0; + virtual void ApplyForce(const MT_Vector3& force,bool local)=0; + virtual MT_Vector3 GetLinearVelocity()=0; + virtual MT_Vector3 GetVelocity(const MT_Point3& pos)=0; + virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0; + virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0; + virtual void getOrientation(MT_Quaternion& orn)=0; + virtual void setOrientation(const MT_Quaternion& orn)=0; + virtual void setPosition(const MT_Point3& pos)=0; + virtual void setScaling(const MT_Vector3& scaling)=0; + virtual MT_Scalar GetMass()=0; + virtual MT_Vector3 getReactionForce()=0; + virtual void setRigidBody(bool rigid)=0; + + virtual void SuspendDynamics()=0; + virtual void RestoreDynamics()=0; + + virtual SG_Controller* GetReplica(class SG_Node* destnode)=0; + + void SetDyna(bool isDynamic) { + m_bDyna = isDynamic; + } + + + virtual void SetSumoTransform(bool nondynaonly)=0; + // todo: remove next line ! + virtual void SetSimulatedTime(double time)=0; + + // call from scene graph to update + virtual bool Update(double time)=0; + void* GetUserData() { return m_userdata;} + + +}; +#endif //__KX_IPHYSICSCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_IScalarInterpolator.h b/source/gameengine/Ketsji/KX_IScalarInterpolator.h new file mode 100644 index 00000000000..dd153f77205 --- /dev/null +++ b/source/gameengine/Ketsji/KX_IScalarInterpolator.h @@ -0,0 +1,42 @@ +/** + * $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_ISCALARINTERPOLATOR_H +#define KX_ISCALARINTERPOLATOR_H + +class KX_IScalarInterpolator { +public: + virtual ~KX_IScalarInterpolator() {} + + virtual float GetValue(float currentTime) const = 0; +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_ISceneConverter.h b/source/gameengine/Ketsji/KX_ISceneConverter.h new file mode 100644 index 00000000000..fcb73fa8872 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ISceneConverter.h @@ -0,0 +1,64 @@ +/** + * $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_ISCENECONVERTER_H +#define __KX_ISCENECONVERTER_H + +#include "STR_String.h" + +#include "KX_Python.h" + +class KX_ISceneConverter +{ + +public: + KX_ISceneConverter() {} + virtual ~KX_ISceneConverter () {}; + + /* + scenename: name of the scene to be converted, + if the scenename is empty, convert the 'default' scene (whatever this means) + 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)=0; + + virtual void SetAlwaysUseExpandFraming(bool to_what) = 0; + + virtual void SetNewFileName(const STR_String& filename) = 0; + virtual bool TryAndLoadNewFile() = 0; +}; +#endif //__KX_ISCENECONVERTER_H diff --git a/source/gameengine/Ketsji/KX_ISystem.h b/source/gameengine/Ketsji/KX_ISystem.h new file mode 100644 index 00000000000..1ab3e521418 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ISystem.h @@ -0,0 +1,55 @@ +/** +* Abstract system +* +* $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_ISYSTEM +#define __KX_ISYSTEM + +#include <vector> +using namespace std; + +#include "STR_String.h" + +/** + * System Abstraction, needed only for getting some timing stuff from the host. + */ +class KX_ISystem +{ +public: + KX_ISystem() {}; + virtual ~KX_ISystem() {}; + + virtual double GetTimeInSeconds()=0; +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp new file mode 100644 index 00000000000..1e351834822 --- /dev/null +++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp @@ -0,0 +1,643 @@ +/** + * Do Ipo stuff + * + * $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_IpoActuator.h" +#include "KX_GameObject.h" + + +/* ------------------------------------------------------------------------- */ +/* Type strings */ +/* ------------------------------------------------------------------------- */ + +STR_String KX_IpoActuator::S_KX_ACT_IPO_PLAY_STRING = "Play"; +STR_String KX_IpoActuator::S_KX_ACT_IPO_PINGPONG_STRING = "PingPong"; +STR_String KX_IpoActuator::S_KX_ACT_IPO_FLIPPER_STRING = "Flipper"; +STR_String KX_IpoActuator::S_KX_ACT_IPO_LOOPSTOP_STRING = "LoopStop"; +STR_String KX_IpoActuator::S_KX_ACT_IPO_LOOPEND_STRING = "LoopEnd"; +STR_String KX_IpoActuator::S_KX_ACT_IPO_KEY2KEY_STRING = "Key2key"; +STR_String KX_IpoActuator::S_KX_ACT_IPO_FROM_PROP_STRING = "FromProp"; + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ +/** Another poltergeist? This seems to be a very transient class... */ +class CIpoAction : public CAction +{ + float m_curtime; + bool m_resurse; + KX_GameObject* m_gameobj; + bool m_ipo_as_force; + bool m_force_ipo_local; + +public: + CIpoAction(KX_GameObject* gameobj, + float curtime, + bool recurse, + bool ipo_as_force, + bool force_ipo_local) : + m_curtime(curtime) , + m_resurse(recurse), + m_gameobj(gameobj), + m_ipo_as_force(ipo_as_force), + m_force_ipo_local(force_ipo_local) + { + /* intentionally empty */ + }; + + virtual void Execute() const + { + m_gameobj->UpdateIPO( + m_curtime, + m_resurse, + m_ipo_as_force, + m_force_ipo_local); + }; + +}; + + +KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj, + const STR_String& propname, + float starttime, + float endtime, + bool recurse, + int acttype, + bool ipo_as_force, + bool force_ipo_local, + PyTypeObject* T) + : SCA_IActuator(gameobj,T), + m_starttime (starttime), + m_endtime(endtime) , + m_localtime(starttime), + m_recurse(recurse), + m_type((IpoActType)acttype) , + m_direction(1), + m_bNegativeEvent(false), + m_propname(propname), + m_ipo_as_force(ipo_as_force), + m_force_ipo_local(force_ipo_local) +{ + // intentionally empty +} + +void KX_IpoActuator::SetStart(float starttime) +{ + m_starttime=starttime; +} + +void KX_IpoActuator::SetEnd(float endtime) +{ + m_endtime=endtime; +} + + +bool KX_IpoActuator::Update(double curtime,double delta_time) +{ + SCA_IActuator::Update(curtime,delta_time); + // result = true if animation has to be continued, false if animation stops + // maybe there are events for us in the queue ! + + + bool bNegativeEvent = false; + int numevents = m_events.size(); + + for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());) + { + i--; + if ((*i)->GetNumber() == 0.0f) + { + int ka=0; + bNegativeEvent = true; + } + (*i)->Release(); + m_events.pop_back(); + } + + if (bNegativeEvent) + { + RemoveAllEvents(); + } + + + double start_smaller_then_end = ( m_starttime < m_endtime ? 1.0 : -1.0); + + double deltaframetime = start_smaller_then_end * delta_time * KX_FIXED_FRAME_PER_SEC; + + bool result=true; + + switch (m_type) + { + + case KX_ACT_IPO_PLAY: + { + + if (start_smaller_then_end > 0.0) + result = (m_localtime < m_endtime && !(m_localtime == m_starttime && bNegativeEvent)); + else + result = (m_localtime > m_endtime && !(m_localtime == m_starttime && bNegativeEvent)); + if (result) + { + m_localtime += m_direction * deltaframetime; + + /* Perform clamping */ + if ((m_localtime*start_smaller_then_end)>(m_endtime*start_smaller_then_end)) + m_localtime=m_endtime; + + CIpoAction ipoaction( + (KX_GameObject*)GetParent(), + m_localtime, + m_recurse, + m_ipo_as_force, + m_force_ipo_local); + GetParent()->Execute(ipoaction); + } else + { + m_localtime=m_starttime; + m_direction=1; + } + break; + } + case KX_ACT_IPO_PINGPONG: + { + result = true; + if (bNegativeEvent && ((m_localtime == m_starttime )|| (m_localtime == m_endtime))) + { + result = false; + } else + { + m_localtime += m_direction * deltaframetime; + } + + if (m_localtime*start_smaller_then_end < m_starttime*start_smaller_then_end) + { + m_localtime = m_starttime; + result = false; + m_direction = 1; + }else + if (m_localtime*start_smaller_then_end > m_endtime*start_smaller_then_end) + { + m_localtime = m_endtime; + result = false; + m_direction = -1; + } + + CIpoAction ipoaction( + (KX_GameObject*) GetParent(), + m_localtime, + m_recurse, + m_ipo_as_force, + m_force_ipo_local); + GetParent()->Execute(ipoaction); + break; + } + + case KX_ACT_IPO_FLIPPER: + { + result = true; + if (numevents) + { + if (bNegativeEvent) + m_direction = -1; + else + m_direction = 1; + } + + m_localtime += m_direction * deltaframetime; + + if (m_localtime*start_smaller_then_end > m_endtime*start_smaller_then_end) + { + m_localtime = m_endtime; + } else + if (m_localtime*start_smaller_then_end < m_starttime*start_smaller_then_end) + { + m_localtime = m_starttime; + result = false; + } + + CIpoAction ipoaction( + (KX_GameObject*) GetParent(), + m_localtime, + m_recurse, + m_ipo_as_force, + m_force_ipo_local); + GetParent()->Execute(ipoaction); + break; + } + + case KX_ACT_IPO_LOOPSTOP: + { + if (numevents) + { + if (bNegativeEvent) + { + result = false; + m_bNegativeEvent = false; + numevents = 0; + } + } // fall through to loopend, and quit the ipo animation immediatly + } + + case KX_ACT_IPO_LOOPEND: + { + if (numevents){ + if (bNegativeEvent){ + m_bNegativeEvent = true; + } + } + + if (bNegativeEvent && m_localtime == m_starttime){ + result = false; + } + else{ + if (m_localtime*start_smaller_then_end < m_endtime*start_smaller_then_end){ + m_localtime += m_direction * deltaframetime; + } + else{ + if (!m_bNegativeEvent){ + /* Perform wraparound */ + float slop = m_localtime-m_endtime; + float length = fabs(m_starttime-m_endtime); + m_localtime = m_starttime + (slop - (int(slop/length)*(int(length)))); + + } + else + { + /* Perform clamping */ + if ((m_localtime*start_smaller_then_end)>(m_endtime*start_smaller_then_end)) + m_localtime=m_endtime; + + result = false; + m_bNegativeEvent = false; + } + } + } + CIpoAction ipoaction( + (KX_GameObject*) GetParent(), + m_localtime, + m_recurse, + m_ipo_as_force, + m_force_ipo_local); + GetParent()->Execute(ipoaction); + break; + } + case KX_ACT_IPO_KEY2KEY: + { + // not implemented yet + result = false; + break; + } + case KX_ACT_IPO_FROM_PROP: + { + result = !bNegativeEvent; + + CValue* propval = GetParent()->GetProperty(m_propname); + if (propval) + { + m_localtime = propval->GetNumber(); + CIpoAction ipoaction( + (KX_GameObject*) GetParent(), + m_localtime, + m_recurse, + m_ipo_as_force, + m_force_ipo_local); + GetParent()->Execute(ipoaction); + + } else + { + result = false; + } + break; + } + + default: + { + result = false; + } + } + + return result; +} + +KX_IpoActuator::IpoActType KX_IpoActuator::string2mode(char* modename) { + IpoActType res = KX_ACT_IPO_NODEF; + + if (modename == S_KX_ACT_IPO_PLAY_STRING) { + res = KX_ACT_IPO_PLAY; + } else if (modename == S_KX_ACT_IPO_PINGPONG_STRING) { + res = KX_ACT_IPO_PINGPONG; + } else if (modename == S_KX_ACT_IPO_FLIPPER_STRING) { + res = KX_ACT_IPO_FLIPPER; + } else if (modename == S_KX_ACT_IPO_LOOPSTOP_STRING) { + res = KX_ACT_IPO_LOOPSTOP; + } else if (modename == S_KX_ACT_IPO_LOOPEND_STRING) { + res = KX_ACT_IPO_LOOPEND; + } else if (modename == S_KX_ACT_IPO_KEY2KEY_STRING) { + res = KX_ACT_IPO_KEY2KEY; + } else if (modename == S_KX_ACT_IPO_FROM_PROP_STRING) { + res = KX_ACT_IPO_FROM_PROP; + } + + return res; +} + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + + + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_IpoActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_IpoActuator", + sizeof(KX_IpoActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_IpoActuator::Parents[] = { + &KX_IpoActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_IpoActuator::Methods[] = { + {"set", (PyCFunction) KX_IpoActuator::sPySet, + METH_VARARGS, Set_doc}, + {"setProperty", (PyCFunction) KX_IpoActuator::sPySetProperty, + METH_VARARGS, SetProperty_doc}, + {"setStart", (PyCFunction) KX_IpoActuator::sPySetStart, + METH_VARARGS, SetStart_doc}, + {"getStart", (PyCFunction) KX_IpoActuator::sPyGetStart, + METH_VARARGS, GetStart_doc}, + {"setEnd", (PyCFunction) KX_IpoActuator::sPySetEnd, + METH_VARARGS, SetEnd_doc}, + {"getEnd", (PyCFunction) KX_IpoActuator::sPyGetEnd, + METH_VARARGS, GetEnd_doc}, + {"setIpoAsForce", (PyCFunction) KX_IpoActuator::sPySetIpoAsForce, + METH_VARARGS, SetIpoAsForce_doc}, + {"getIpoAsForce", (PyCFunction) KX_IpoActuator::sPyGetIpoAsForce, + METH_VARARGS, GetIpoAsForce_doc}, + {"setType", (PyCFunction) KX_IpoActuator::sPySetType, + METH_VARARGS, SetType_doc}, + {"getType", (PyCFunction) KX_IpoActuator::sPyGetType, + METH_VARARGS, GetType_doc}, + {NULL,NULL} //Sentinel +}; + +PyObject* KX_IpoActuator::_getattr(char* attr) { + _getattr_up(SCA_IActuator); +} + + + +/* set --------------------------------------------------------------------- */ +char KX_IpoActuator::Set_doc[] = +"set(mode, startframe, endframe, force?)\n" +"\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n" +"\t - startframe: first frame to use (int)\n" +"\t - endframe : last frame to use (int)\n" +"\t - force? : interpret this ipo as a force? (KX_TRUE, KX_FALSE)" +"\tSet the properties of the actuator.\n"; +PyObject* KX_IpoActuator::PySet(PyObject* self, + PyObject* args, + PyObject* kwds) { + /* sets modes PLAY, PINGPONG, FLIPPER, LOOPSTOP, LOOPEND */ + /* arg 1 = mode string, arg 2 = startframe, arg3 = stopframe, */ + /* arg4 = force toggle */ + char* mode; + int forceToggle; + IpoActType modenum; + int startFrame, stopFrame; + if(!PyArg_ParseTuple(args, "siii", &mode, &startFrame, + &stopFrame, &forceToggle)) { + return NULL; + } + modenum = string2mode(mode); + + switch (modenum) { + case KX_ACT_IPO_PLAY: + case KX_ACT_IPO_PINGPONG: + case KX_ACT_IPO_FLIPPER: + case KX_ACT_IPO_LOOPSTOP: + case KX_ACT_IPO_LOOPEND: + m_type = modenum; + m_starttime = startFrame; + m_endtime = stopFrame; + m_ipo_as_force = PyArgToBool(forceToggle); + break; + default: + ; /* error */ + } + + Py_Return; +} + +/* set property ----------------------------------------------------------- */ +char KX_IpoActuator::SetProperty_doc[] = +"setProperty(propname)\n" +"\t - propname: name of the property (string)\n" +"\tSet the property to be used in FromProp mode.\n"; +PyObject* KX_IpoActuator::PySetProperty(PyObject* self, + PyObject* args, + PyObject* kwds) { + /* mode is implicit here, but not supported yet... */ + /* args: property */ + char *propertyName; + if(!PyArg_ParseTuple(args, "s", &propertyName)) { + return NULL; + } + + Py_Return; +} + +/* 4. setStart: */ +char KX_IpoActuator::SetStart_doc[] = +"setStart(frame)\n" +"\t - frame: first frame to use (int)\n" +"\tSet the frame from which the ipo starts playing.\n"; +PyObject* KX_IpoActuator::PySetStart(PyObject* self, + PyObject* args, + PyObject* kwds) { + float startArg; + if(!PyArg_ParseTuple(args, "f", &startArg)) { + return NULL; + } + + m_starttime = startArg; + + Py_Return; +} +/* 5. getStart: */ +char KX_IpoActuator::GetStart_doc[] = +"getStart()\n" +"\tReturns the frame from which the ipo starts playing.\n"; +PyObject* KX_IpoActuator::PyGetStart(PyObject* self, + PyObject* args, + PyObject* kwds) { + return PyFloat_FromDouble(m_starttime); +} + +/* 6. setEnd: */ +char KX_IpoActuator::SetEnd_doc[] = +"setEnd(frame)\n" +"\t - frame: last frame to use (int)\n" +"\tSet the frame at which the ipo stops playing.\n"; +PyObject* KX_IpoActuator::PySetEnd(PyObject* self, + PyObject* args, + PyObject* kwds) { + float endArg; + if(!PyArg_ParseTuple(args, "f", &endArg)) { + return NULL; + } + + m_endtime = endArg; + + Py_Return; +} +/* 7. getEnd: */ +char KX_IpoActuator::GetEnd_doc[] = +"getEnd()\n" +"\tReturns the frame at which the ipo stops playing.\n"; +PyObject* KX_IpoActuator::PyGetEnd(PyObject* self, + PyObject* args, + PyObject* kwds) { + return PyFloat_FromDouble(m_endtime); +} + +/* 6. setIpoAsForce: */ +char KX_IpoActuator::SetIpoAsForce_doc[] = +"setIpoAsForce(force?)\n" +"\t - force? : interpret this ipo as a force? (KX_TRUE, KX_FALSE)\n" +"\tSet whether to interpret the ipo as a force rather than a displacement.\n"; +PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self, + PyObject* args, + PyObject* kwds) { + int boolArg; + + if (!PyArg_ParseTuple(args, "i", &boolArg)) { + return NULL; + } + + m_ipo_as_force = PyArgToBool(boolArg); + + Py_Return; +} +/* 7. getIpoAsForce: */ +char KX_IpoActuator::GetIpoAsForce_doc[] = +"getIpoAsForce()\n" +"\tReturns whether to interpret the ipo as a force rather than a displacement.\n"; +PyObject* KX_IpoActuator::PyGetIpoAsForce(PyObject* self, + PyObject* args, + PyObject* kwds) { + return BoolToPyArg(m_ipo_as_force); +} + +/* 8. setType: */ +char KX_IpoActuator::SetType_doc[] = +"setType(mode)\n" +"\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n" +"\tSet the operation mode of the actuator.\n"; +PyObject* KX_IpoActuator::PySetType(PyObject* self, + PyObject* args, + PyObject* kwds) { + int typeArg; + + if (!PyArg_ParseTuple(args, "i", &typeArg)) { + return NULL; + } + + if ( (typeArg > KX_ACT_IPO_NODEF) + && (typeArg < KX_ACT_IPO_KEY2KEY) ) { + m_type = (IpoActType) typeArg; + } + + Py_Return; +} +/* 9. getType: */ +char KX_IpoActuator::GetType_doc[] = +"getType()\n" +"\tReturns the operation mode of the actuator.\n"; +PyObject* KX_IpoActuator::PyGetType(PyObject* self, + PyObject* args, + PyObject* kwds) { + return PyInt_FromLong(m_type); +} + +/* 10. setForceIpoActsLocal: */ +char KX_IpoActuator::SetForceIpoActsLocal_doc[] = +"setForceIpoActsLocal(local?)\n" +"\t - local? : Apply the ipo-as-force in the object's local\n" +"\t coordinates? (KX_TRUE, KX_FALSE)\n" +"\tSet whether to apply the force in the object's local\n" +"\tcoordinates rather than the world global coordinates.\n"; +PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self, + PyObject* args, + PyObject* kwds) { + int boolArg; + + if (!PyArg_ParseTuple(args, "i", &boolArg)) { + return NULL; + } + + m_force_ipo_local = PyArgToBool(boolArg); + + Py_Return; +} +/* 11. getForceIpoActsLocal: */ +char KX_IpoActuator::GetForceIpoActsLocal_doc[] = +"getForceIpoActsLocal()\n" +"\tReturn whether to apply the force in the object's local\n" +"\tcoordinates rather than the world global coordinates.\n"; +PyObject* KX_IpoActuator::PyGetForceIpoActsLocal(PyObject* self, + PyObject* args, + PyObject* kwds) { + return BoolToPyArg(m_force_ipo_local); +} + + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h new file mode 100644 index 00000000000..134de3817b4 --- /dev/null +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -0,0 +1,141 @@ +/** + * Do an object ipo + * + * $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_IPOACTUATOR +#define __KX_IPOACTUATOR + +#include "SCA_IActuator.h" + +class KX_IpoActuator : public SCA_IActuator +{ + Py_Header; + + bool m_bNegativeEvent; + + /** Begin frame of the ipo. */ + float m_starttime; + + /** End frame of the ipo. */ + float m_endtime; + + /** Include children in the transforms? */ + bool m_recurse; + + /** Current active frame of the ipo. */ + float m_localtime; + + /** play backwards or forwards? (positive means forward). */ + float m_direction; + + /** Name of the property (only used in from_prop mode). */ + STR_String m_propname; + + /** Interpret the ipo as a force? */ + bool m_ipo_as_force; + + /** Apply a force-ipo locally? */ + bool m_force_ipo_local; + +public: + enum IpoActType + { + KX_ACT_IPO_NODEF = 0, + KX_ACT_IPO_PLAY, + KX_ACT_IPO_PINGPONG, + KX_ACT_IPO_FLIPPER, + KX_ACT_IPO_LOOPSTOP, + KX_ACT_IPO_LOOPEND, + KX_ACT_IPO_KEY2KEY, + KX_ACT_IPO_FROM_PROP, + KX_ACT_IPO_MAX + }; + + static STR_String S_KX_ACT_IPO_PLAY_STRING; + static STR_String S_KX_ACT_IPO_PINGPONG_STRING; + static STR_String S_KX_ACT_IPO_FLIPPER_STRING; + static STR_String S_KX_ACT_IPO_LOOPSTOP_STRING; + static STR_String S_KX_ACT_IPO_LOOPEND_STRING; + static STR_String S_KX_ACT_IPO_KEY2KEY_STRING; + static STR_String S_KX_ACT_IPO_FROM_PROP_STRING; + + IpoActType string2mode(char* modename); + + IpoActType m_type; + + KX_IpoActuator(SCA_IObject* gameobj, + const STR_String& propname, + float starttime, + float endtime, + bool recurse, + int acttype, + bool ipo_as_force, + bool force_ipo_local, + PyTypeObject* T=&Type); + virtual ~KX_IpoActuator() {}; + + virtual CValue* GetReplica() { + KX_IpoActuator* replica = new KX_IpoActuator(*this);//m_float,GetName()); + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; + }; + + void SetStart(float starttime); + void SetEnd(float endtime); + virtual bool Update(double curtime,double deltatime); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + //KX_PYMETHOD_DOC + KX_PYMETHOD_DOC(KX_IpoActuator,Set); + KX_PYMETHOD_DOC(KX_IpoActuator,SetProperty); +/* KX_PYMETHOD_DOC(KX_IpoActuator,SetKey2Key); */ + KX_PYMETHOD_DOC(KX_IpoActuator,SetStart); + KX_PYMETHOD_DOC(KX_IpoActuator,GetStart); + KX_PYMETHOD_DOC(KX_IpoActuator,SetEnd); + KX_PYMETHOD_DOC(KX_IpoActuator,GetEnd); + KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAsForce); + KX_PYMETHOD_DOC(KX_IpoActuator,GetIpoAsForce); + KX_PYMETHOD_DOC(KX_IpoActuator,SetType); + KX_PYMETHOD_DOC(KX_IpoActuator,GetType); + KX_PYMETHOD_DOC(KX_IpoActuator,SetForceIpoActsLocal); + KX_PYMETHOD_DOC(KX_IpoActuator,GetForceIpoActsLocal); + +}; + +#endif //__KX_IPOACTUATOR diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp new file mode 100644 index 00000000000..c03e4e3d964 --- /dev/null +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -0,0 +1,1250 @@ +/* + * $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 ***** + * The engine ties all game modules together. + */ +#ifdef WIN32 +#pragma warning (disable : 4786) +#endif //WIN32 + +#include <iostream> + +#include "KX_KetsjiEngine.h" + +#include "ListValue.h" +#include "IntValue.h" +#include "VectorValue.h" +#include "BoolValue.h" +#include "FloatValue.h" + +#define KX_NUM_ITERATIONS 4 +#include "RAS_BucketManager.h" +#include "RAS_Rect.h" +#include "RAS_IRasterizer.h" +#include "RAS_IRenderTools.h" +#include "RAS_ICanvas.h" +#include "STR_String.h" +#include "MT_Vector3.h" +#include "MT_Transform.h" +#include "SCA_IInputDevice.h" +#include "KX_Scene.h" +#include "MT_CmMatrix4x4.h" +#include "KX_Camera.h" +#include "KX_PythonInit.h" +#include "KX_PyConstraintBinding.h" +#include "PHY_IPhysicsEnvironment.h" + +#include "SND_Scene.h" +#include "SND_IAudioDevice.h" + +#include "NG_NetworkScene.h" +#include "NG_NetworkDeviceInterface.h" + +#include "KX_WorldInfo.h" +#include "KX_ISceneConverter.h" +#include "KX_TimeCategoryLogger.h" + +#include "RAS_FramingManager.h" + +// If define: little test for Nzc: guarded drawing. If the canvas is +// not valid, skip rendering this frame. +//#define NZC_GUARDED_OUTPUT + + +const char KX_KetsjiEngine::m_profileLabels[tc_numCategories][15] = { + "Physics:", // tc_physics + "Logic", // tc_logic + "Network:", // tc_network + "Scenegraph:", // tc_scenegraph + "Sound:", // tc_sound + "Rasterizer:", // tc_rasterizer + "Services:", // tc_services + "Overhead:", // tc_overhead + "Outside:" // tc_outside +}; + + + + +/** + * Constructor of the Ketsji Engine + */ +KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system) +: m_bInitialized(false), + m_activecam(0), + m_rasterizer(NULL) +{ + m_kxsystem = system; + m_bFixedTime = false; + + // Initialize the time logger + m_logger = new KX_TimeCategoryLogger (25); + + for (int i = tc_first; i < tc_numCategories; i++) + m_logger->AddCategory((KX_TimeCategory)i); + + // Set up timing info display variables + m_show_framerate = false; + m_show_profile = false; + m_show_debug_properties = false; + m_propertiesPresent = false; + + // Default behavior is to hide the cursor every frame. + m_hideCursor = false; + + m_overrideFrameColor = false; + m_overrideFrameColorR = (float)0; + m_overrideFrameColorG = (float)0; + m_overrideFrameColorB = (float)0; + + m_cameraZoom = 1.0; + m_drawingmode = 5; /* textured drawing mode */ + m_overrideCam = false; + + m_exitcode = KX_EXIT_REQUEST_NO_REQUEST; + m_exitstring = ""; +} + + + +/** + * Destructor of the Ketsji Engine, release all memory + */ +KX_KetsjiEngine::~KX_KetsjiEngine() +{ + if (m_logger) + delete m_logger; +} + + + +void KX_KetsjiEngine::SetKeyboardDevice(SCA_IInputDevice* keyboarddevice) +{ + assert(keyboarddevice); + m_keyboarddevice = keyboarddevice; +} + + + +void KX_KetsjiEngine::SetMouseDevice(SCA_IInputDevice* mousedevice) +{ + assert(mousedevice); + m_mousedevice = mousedevice; +} + + + +void KX_KetsjiEngine::SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice) +{ + assert(networkdevice); + m_networkdevice = networkdevice; +} + + + +void KX_KetsjiEngine::SetAudioDevice(SND_IAudioDevice* audiodevice) +{ + assert(audiodevice); + m_audiodevice = audiodevice; +} + + + +void KX_KetsjiEngine::SetCanvas(RAS_ICanvas* canvas) +{ + assert(canvas); + m_canvas = canvas; +} + + + +void KX_KetsjiEngine::SetRenderTools(RAS_IRenderTools* rendertools) +{ + assert(rendertools); + m_rendertools = rendertools; +} + + + +void KX_KetsjiEngine::SetRasterizer(RAS_IRasterizer* rasterizer) +{ + assert(rasterizer); + m_rasterizer = rasterizer; +} + + + +void KX_KetsjiEngine::SetPythonDictionary(PyObject* pythondictionary) +{ + assert(pythondictionary); + m_pythondictionary = pythondictionary; +} + + + +void KX_KetsjiEngine::SetSceneConverter(KX_ISceneConverter* sceneconverter) +{ + assert(sceneconverter); + m_sceneconverter = sceneconverter; +} + + + +/** + * Ketsji Init(), Initializes datastructures and converts data from + * Blender into Ketsji native (realtime) format also sets up the + * graphics context + */ +void KX_KetsjiEngine::StartEngine() +{ + m_previoustime = 0.0; + m_missedtime = 0.0; + m_firstframe = true; + + // for all scenes, initialize the scenegraph for the first time + m_lasttime = m_kxsystem->GetTimeInSeconds()*100.0; + + m_bInitialized = true; +} + + + +#define DELTALENGTH 25 + +double KX_KetsjiEngine::CalculateAverage(double newdelta) +{ + if (m_deltatimes.size() < DELTALENGTH) + { + m_deltatimes.push_back(newdelta); + } else + { + // + double totaltime = 0.0; + double newlasttime,lasttime = newdelta; + double peakmin = 10000; + double peakmax = -10000; + + for (int i=m_deltatimes.size()-1;i>=0;i--) + { newlasttime = m_deltatimes[i]; + totaltime += newlasttime; + if (peakmin > newlasttime) + peakmin = newlasttime; + if (peakmax < newlasttime) + peakmax = newlasttime; + + m_deltatimes[i] = lasttime; + lasttime = newlasttime; + }; + double averagetime; + + if (peakmin < peakmax) + { + averagetime = ((totaltime - peakmin) - peakmax) / (double) (m_deltatimes.size()-2); + } else + { + averagetime = totaltime / (double) m_deltatimes.size(); + } + return averagetime; + } + + return newdelta; +} + + + +bool KX_KetsjiEngine::BeginFrame() +{ + bool result = false; + + RAS_Rect vp; + KX_Scene* firstscene = *m_scenes.begin(); + const RAS_FrameSettings &framesettings = firstscene->GetFramingType(); + + // set the area used for rendering + m_rasterizer->SetRenderArea(); + + RAS_FramingManager::ComputeViewport(framesettings, m_canvas->GetDisplayArea(), vp); + + if (m_canvas->BeginDraw()) + { + result = true; + + m_canvas->SetViewPort(vp.GetLeft(), vp.GetBottom(), vp.GetRight(), vp.GetTop()); + SetBackGround( firstscene->GetWorldInfo() ); + m_rasterizer->BeginFrame( m_drawingmode , m_kxsystem->GetTimeInSeconds()); + m_rendertools->BeginFrame( m_rasterizer); + } + + return result; +} + + +void KX_KetsjiEngine::EndFrame() +{ + // Show profiling info + m_logger->StartLog(tc_overhead, m_kxsystem->GetTimeInSeconds(), true); + if (m_show_framerate || m_show_profile || (m_show_debug_properties && m_propertiesPresent)) + { + RenderDebugProperties(); + } + // Go to next profiling measurement, time spend after this call is shown in the next frame. + m_logger->NextMeasurement(m_kxsystem->GetTimeInSeconds()); + + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + m_rasterizer->EndFrame(); + // swap backbuffer (drawing into this buffer) <-> front/visible buffer + m_rasterizer->SwapBuffers(); + m_rendertools->EndFrame(m_rasterizer); + + m_canvas->EndDraw(); +} + + + +void KX_KetsjiEngine::NextFrame() +{ + m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true); + + double deltatime = 0.02; + double curtime; + + if (m_bFixedTime) + { + curtime = m_previoustime + deltatime; + } + else + { + curtime = m_kxsystem->GetTimeInSeconds(); + if (m_previoustime) + deltatime = curtime - m_previoustime; + + if (deltatime > 0.1) + deltatime = 0.1; + + deltatime = CalculateAverage(deltatime); + } + + m_previoustime = curtime; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + + + + /* Suspension holds the physics and logic processing for an + * entire scene. Objects can be suspended individually, and + * the settings for that preceed the logic and physics + * update. */ + m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true); + scene->UpdateObjectActivity(); + + if (!scene->IsSuspended()) + { + m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true); + scene->GetNetworkScene()->proceed(curtime, deltatime); + + // set Python hooks for each scene + PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment()); + PHY_SetActiveScene(scene); + + // Process sensors, and controllers + m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true); + scene->LogicBeginFrame(curtime,deltatime); + + // Scenegraph needs to be updated again, because Logic Controllers + // can affect the local matrices. + m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); + scene->UpdateParents(curtime); + + // Process actuators + + // Do some cleanup work for this logic frame + m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true); + scene->LogicUpdateFrame(curtime,deltatime); + scene->LogicEndFrame(); + + // Actuators can affect the scenegraph + m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); + scene->UpdateParents(curtime); + + // Perform physics calculations on the scene. This can involve + // many iterations of the physics solver. + m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true); + scene->GetPhysicsEnvironment()->proceed(deltatime); + + // Update scenegraph after physics step. This maps physics calculations + // into node positions. + m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true); + scene->UpdateParents(curtime); + + } // suspended + + DoSound(scene); + + m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true); + } + + // update system devices + m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true); + + if (m_keyboarddevice) + m_keyboarddevice->NextFrame(); + + if (m_mousedevice) + m_mousedevice->NextFrame(); + + if (m_networkdevice) + m_networkdevice->NextFrame(); + + if (m_audiodevice) + m_audiodevice->NextFrame(); + + // scene management + ProcessScheduledScenes(); + + // Start logging time spend outside main loop + m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true); +} + + + +void KX_KetsjiEngine::Render() +{ + KX_Scene* firstscene = *m_scenes.begin(); + const RAS_FrameSettings &framesettings = firstscene->GetFramingType(); + + m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true); + + // hiding mouse cursor each frame + // (came back when going out of focus and then back in again) + if (m_hideCursor) + m_canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + + // clear the entire game screen with the border color + // only once per frame + m_canvas->BeginDraw(); + if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) { + m_canvas->SetViewPort(0, 0, m_canvas->GetWidth(), m_canvas->GetHeight()); + if (m_overrideFrameColor) + { + // Do not use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + m_overrideFrameColorR, + m_overrideFrameColorG, + m_overrideFrameColorB, + 1.0 + ); + } + else + { + // Use the framing bar color set in the Blender scenes + m_canvas->ClearColor( + framesettings.BarRed(), + framesettings.BarGreen(), + framesettings.BarBlue(), + 1.0 + ); + } + // clear the -whole- viewport + m_canvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER); + } + + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_LEFTEYE); + + // BeginFrame() sets the actual drawing area. You can use a part of the window + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + m_rendertools->SetAuxilaryClientInfo(scene); + + //Initialize scene viewport. + SetupRenderFrame(scene); + + // do the rendering + RenderFrame(scene); + } + + // only one place that checks for stereo + if(m_rasterizer->Stereo()) + { + m_rasterizer->SetEye(RAS_IRasterizer::RAS_STEREO_RIGHTEYE); + + if (!BeginFrame()) + return; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++) + // for each scene, call the proceed functions + { + KX_Scene* scene = *sceneit; + + // pass the scene's worldsettings to the rasterizer + SetWorldSettings(scene->GetWorldInfo()); + + if (scene->IsClearingZBuffer()) + m_rasterizer->ClearDepthBuffer(); + + //pass the scene, for picking and raycasting (shadows) + m_rendertools->SetAuxilaryClientInfo(scene); + + //Initialize scene viewport. + SetupRenderFrame(scene); + + // do the rendering + RenderFrame(scene); + } + } // if(m_rasterizer->Stereo()) + + EndFrame(); +} + + + +void KX_KetsjiEngine::RequestExit(int exitrequestmode) +{ + m_exitcode = exitrequestmode; +} + + + +void KX_KetsjiEngine::SetNameNextGame(const STR_String& nextgame) +{ + m_exitstring = nextgame; +} + + + +int KX_KetsjiEngine::GetExitCode() +{ + // if a gameactuator has set an exitcode or if there are no scenes left + if (!m_exitcode) + { + if (m_scenes.begin()==m_scenes.end()) + m_exitcode = KX_EXIT_REQUEST_NO_SCENES_LEFT; + } + + return m_exitcode; +} + + + +const STR_String& KX_KetsjiEngine::GetExitString() +{ + return m_exitstring; +} + + + +void KX_KetsjiEngine::DoSound(KX_Scene* scene) +{ + m_logger->StartLog(tc_sound, m_kxsystem->GetTimeInSeconds(), true); + + KX_Camera* cam = scene->GetActiveCamera(); + MT_Point3 listenerposition = cam->NodeGetWorldPosition(); + MT_Vector3 listenervelocity = cam->GetLinearVelocity(); + MT_Matrix3x3 listenerorientation = cam->NodeGetWorldOrientation(); + + SND_Scene* soundscene = scene->GetSoundScene(); + soundscene->SetListenerTransform( + listenerposition, + listenervelocity, + listenerorientation); + + soundscene->Proceed(); +} + + + +void KX_KetsjiEngine::SetBackGround(KX_WorldInfo* wi) +{ + if (wi->hasWorld()) + { + if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) + { + m_rasterizer->SetBackColor( + wi->getBackColorRed(), + wi->getBackColorGreen(), + wi->getBackColorBlue(), + 0.0 + ); + } + } +} + + + +void KX_KetsjiEngine::SetWorldSettings(KX_WorldInfo* wi) +{ + if (wi->hasWorld()) + { + if (m_drawingmode == RAS_IRasterizer::KX_TEXTURED) + { + if (wi->hasMist()) + { + m_rasterizer->SetFog( + wi->getMistStart(), + wi->getMistDistance(), + wi->getMistColorRed(), + wi->getMistColorGreen(), + wi->getMistColorBlue() + ); + } + else + { + m_rasterizer->DisableFog(); + } + } + } +} + + + +void KX_KetsjiEngine::SetDrawType(int drawingmode) +{ + m_drawingmode = drawingmode; +} + + + +void KX_KetsjiEngine::EnableCameraOverride(const STR_String& forscene) +{ + m_overrideCam = true; + m_overrideSceneName = forscene; +} + + + +void KX_KetsjiEngine::SetCameraZoom(float camzoom) +{ + m_cameraZoom = camzoom; +} + + + +void KX_KetsjiEngine::SetCameraOverrideUseOrtho(bool useOrtho) +{ + m_overrideCamUseOrtho = useOrtho; +} + + + +void KX_KetsjiEngine::SetCameraOverrideProjectionMatrix(const MT_CmMatrix4x4& mat) +{ + m_overrideCamProjMat = mat; +} + + +void KX_KetsjiEngine::SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat) +{ + m_overrideCamViewMat = mat; +} + + +void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene) +{ + // In this function we make sure the rasterizer settings are upto + // date. We compute the viewport so that logic + // using this information is upto date. + + // Note we postpone computation of the projection matrix + // so that we are using the latest camera position. + + RAS_Rect viewport; + + if ( + m_overrideCam || + (scene->GetName() != m_overrideSceneName) || + m_overrideCamUseOrtho + ) { + RAS_FramingManager::ComputeViewport( + scene->GetFramingType(), + m_canvas->GetDisplayArea(), + viewport + ); + } else { + viewport.SetLeft(0); + viewport.SetBottom(0); + viewport.SetRight(int(m_canvas->GetWidth())); + viewport.SetTop(int(m_canvas->GetHeight())); + } + // store the computed viewport in the scene + + scene->SetSceneViewport(viewport); + + // set the viewport for this frame and scene + m_canvas->SetViewPort( + viewport.GetLeft(), + viewport.GetBottom(), + viewport.GetRight(), + viewport.GetTop() + ); + +} + + +// update graphics +void KX_KetsjiEngine::RenderFrame(KX_Scene* scene) +{ + float left, right, bottom, top, nearfrust, farfrust; + KX_Camera* cam = scene->GetActiveCamera(); + + m_rasterizer->DisplayFog(); + + if (m_overrideCam && (scene->GetName() == m_overrideSceneName) && m_overrideCamUseOrtho) { + MT_CmMatrix4x4 projmat = m_overrideCamProjMat; + m_rasterizer->SetProjectionMatrix(projmat); + } else { + RAS_FrameFrustum frustum; + + RAS_FramingManager::ComputeFrustum( + scene->GetFramingType(), + m_canvas->GetDisplayArea(), + scene->GetSceneViewport(), + cam->GetLens(), + cam->GetCameraNear(), + cam->GetCameraFar(), + frustum + ); + + left = frustum.x1 * m_cameraZoom; + right = frustum.x2 * m_cameraZoom; + bottom = frustum.y1 * m_cameraZoom; + top = frustum.y2 * m_cameraZoom; + nearfrust = frustum.camnear; + farfrust = frustum.camfar; + + MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix( + left, right, bottom, top, nearfrust, farfrust); + + m_rasterizer->SetProjectionMatrix(projmat); + cam->SetProjectionMatrix(projmat); + } + + MT_Scalar cammat[16]; + cam->GetWorldToCamera().getValue(cammat); + MT_Matrix4x4 viewmat; + viewmat.setValue(cammat); // this _should transpose ... + // if finally transposed take care of correct usage + // in RAS_OpenGLRasterizer ! (row major vs column major) + + m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(), + cam->GetCameraLocation(), cam->GetCameraOrientation()); + cam->SetModelviewMatrix(viewmat); + + scene->UpdateMeshTransformations(); + + // The following actually reschedules all vertices to be + // redrawn. There is a cache between the actual rescheduling + // and this call though. Visibility is imparted when this call + // runs through the individual objects. + scene->CalculateVisibleMeshes(m_rasterizer); + + scene->RenderBuckets(cam->GetWorldToCamera(), m_rasterizer, m_rendertools); +} + + + +void KX_KetsjiEngine::StopEngine() +{ + if (m_bInitialized) + { + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++) + { + KX_Scene* scene = *sceneit; + delete scene; + } + m_scenes.clear(); + + // cleanup all the stuff + m_rasterizer->Exit(); + } +} + +// Scene Management is able to switch between scenes +// and have several scene's running in parallel +void KX_KetsjiEngine::AddScene(KX_Scene* scene) +{ + m_scenes.push_back(scene); + PostProcessScene(scene); + SceneListsChanged(); +} + + + +void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene) +{ + bool override_camera = (m_overrideCam && (scene->GetName() == m_overrideSceneName)); + + // if there is no activecamera, or the camera is being + // overridden we need to construct a temporarily camera + if (!scene->GetActiveCamera() || override_camera) + { + KX_Camera* activecam = NULL; + + RAS_CameraData camdata; + camdata.m_lens = 35.0f; + camdata.m_clipstart = 0.1f; + camdata.m_clipend = 100.0f; + activecam = new KX_Camera(scene,KX_Scene::m_callbacks,camdata); + activecam->SetName("__default__cam__"); + + // set transformation + if (override_camera) { + const MT_CmMatrix4x4& cammatdata = m_overrideCamViewMat; + MT_Transform trans = MT_Transform(cammatdata.getPointer()); + MT_Transform camtrans; + camtrans.invert(trans); + + activecam->NodeSetLocalPosition(camtrans.getOrigin()); + activecam->NodeSetLocalOrientation(camtrans.getBasis()); + activecam->NodeUpdateGS(0,true); + } else { + activecam->NodeSetLocalPosition(MT_Point3(0.0, 0.0, 0.0)); + activecam->NodeSetLocalOrientation(MT_Vector3(0.0, 0.0, 0.0)); + activecam->NodeUpdateGS(0,true); + } + + scene->AddCamera(activecam); + scene->SetActiveCamera(activecam); + scene->GetObjectList()->Add(activecam->AddRef()); + scene->GetRootParentList()->Add(activecam->AddRef()); + } + + scene->UpdateParents(0.0); +} + + + +void KX_KetsjiEngine::RenderDebugProperties() +{ + STR_String debugtxt; + int xcoord = 10; // mmmm, these constants were taken from blender source + int ycoord = 14; // to 'mimic' behaviour + + float tottime = m_logger->GetAverage(); + if (tottime < 1e-6f) { + tottime = 1e-6f; + } + + /* Framerate display */ + if (m_show_framerate) { + debugtxt.Format("swap : %.3f (%.3f frames per second)", tottime, 1.0/tottime); + m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, + debugtxt.Ptr(), + xcoord, + ycoord, + m_canvas->GetWidth() /* RdV, TODO ?? */, + m_canvas->GetHeight() /* RdV, TODO ?? */); + ycoord += 14; + } + + /* Profile and framerate display */ + if (m_show_profile) + { + for (int j = tc_first; j < tc_numCategories; j++) + { + debugtxt.Format(m_profileLabels[j]); + m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, + debugtxt.Ptr(), + xcoord,ycoord, + m_canvas->GetWidth(), + m_canvas->GetHeight()); + double time = m_logger->GetAverage((KX_TimeCategory)j); + debugtxt.Format("%2.2f %%", time/tottime * 100.f); + m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, + debugtxt.Ptr(), + xcoord + 60 ,ycoord, + m_canvas->GetWidth(), + m_canvas->GetHeight()); + ycoord += 14; + } + } + + /* Property display*/ + if (m_show_debug_properties && m_propertiesPresent) + { + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++) + { + KX_Scene* scene = *sceneit; + /* the 'normal' debug props */ + vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties(); + + for (vector<SCA_DebugProp*>::iterator it = debugproplist.begin(); + !(it==debugproplist.end());it++) + { + CValue* propobj = (*it)->m_obj; + STR_String objname = propobj->GetName(); + STR_String propname = (*it)->m_name; + CValue* propval = propobj->GetProperty(propname); + if (propval) + { + STR_String text = propval->GetText(); + debugtxt = objname + "." + propname + " = " + text; + m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, + debugtxt.Ptr(), + xcoord, + ycoord, + m_canvas->GetWidth(), + m_canvas->GetHeight()); + ycoord += 14; + } + } + } + } +} + + +KX_SceneList* KX_KetsjiEngine::CurrentScenes() +{ + return &m_scenes; +} + + + +KX_Scene* KX_KetsjiEngine::FindScene(const STR_String& scenename) +{ + KX_SceneList::iterator sceneit = m_scenes.begin(); + + // bit risky :) better to split the second clause + while ( (sceneit != m_scenes.end()) + && ((*sceneit)->GetName() != scenename)) + { + sceneit++; + } + + return ((sceneit == m_scenes.end()) ? NULL : *sceneit); +} + + + +void KX_KetsjiEngine::ConvertAndAddScene(const STR_String& scenename,bool overlay) +{ + // only add scene when it doesn't exist! + if (FindScene(scenename)) + { + STR_String tmpname = scenename; + printf("warning: scene %s already exists, not added!\n",tmpname.Ptr()); + } + else + { + if (overlay) + { + m_addingOverlayScenes.insert(scenename); + } + else + { + m_addingBackgroundScenes.insert(scenename); + } + } +} + + + + +void KX_KetsjiEngine::RemoveScene(const STR_String& scenename) +{ + if (FindScene(scenename)) + { + m_removingScenes.insert(scenename); + } + else + { + STR_String tmpname = scenename; + printf("warning: scene %s does not exist, not removed!\n",tmpname.Ptr()); + } +} + + + +void KX_KetsjiEngine::RemoveScheduledScenes() +{ + if (m_removingScenes.size()) + { + set<STR_String>::iterator scenenameit; + for (scenenameit=m_removingScenes.begin();scenenameit != m_removingScenes.end();scenenameit++) + { + STR_String scenename = *scenenameit; + + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++) + { + KX_Scene* scene = *sceneit; + if (scene->GetName()==scenename) + { + delete scene; + m_scenes.erase(sceneit); + break; + } + } + } + m_removingScenes.clear(); + } +} + + + +KX_Scene* KX_KetsjiEngine::CreateScene(const STR_String& scenename) +{ + + KX_Scene* tmpscene = new KX_Scene(m_keyboarddevice, + m_mousedevice, + m_networkdevice, + m_audiodevice, + scenename); + + m_sceneconverter->ConvertScene(scenename, + tmpscene, + m_pythondictionary, + m_keyboarddevice, + m_rendertools, + m_canvas); + + return tmpscene; +} + + + +void KX_KetsjiEngine::AddScheduledScenes() +{ + set<STR_String>::iterator scenenameit; + + if (m_addingOverlayScenes.size()) + { + for (scenenameit = m_addingOverlayScenes.begin(); + scenenameit != m_addingOverlayScenes.end(); + scenenameit++) + { + STR_String scenename = *scenenameit; + KX_Scene* tmpscene = CreateScene(scenename); + m_scenes.push_back(tmpscene); + PostProcessScene(tmpscene); + } + m_addingOverlayScenes.clear(); + } + + if (m_addingBackgroundScenes.size()) + { + for (scenenameit = m_addingBackgroundScenes.begin(); + scenenameit != m_addingBackgroundScenes.end(); + scenenameit++) + { + STR_String scenename = *scenenameit; + KX_Scene* tmpscene = CreateScene(scenename); + m_scenes.insert(m_scenes.begin(),tmpscene); + PostProcessScene(tmpscene); + + } + m_addingBackgroundScenes.clear(); + } +} + + + +void KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene) +{ + m_replace_scenes.insert(std::make_pair(oldscene,newscene)); +} + +// replace scene is not the same as removing and adding because the +// scene must be in exact the same place (to maintain drawingorder) +// (nzc) - should that not be done with a scene-display list? It seems +// stupid to rely on the mem allocation order... +void KX_KetsjiEngine::ReplaceScheduledScenes() +{ + if (m_replace_scenes.size()) + { + set<pair<STR_String,STR_String> >::iterator scenenameit; + + for (scenenameit = m_replace_scenes.begin(); + scenenameit != m_replace_scenes.end(); + scenenameit++) + { + STR_String oldscenename = (*scenenameit).first; + STR_String newscenename = (*scenenameit).second; + int i=0; + /* Scenes are not supposed to be included twice... I think */ + KX_SceneList::iterator sceneit; + for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++) + { + KX_Scene* scene = *sceneit; + if (scene->GetName() == oldscenename) + { + delete scene; + KX_Scene* tmpscene = CreateScene(newscenename); + m_scenes[i]=tmpscene; + PostProcessScene(tmpscene); + } + i++; + } + } + m_replace_scenes.clear(); + } +} + + + +void KX_KetsjiEngine::SuspendScene(const STR_String& scenename) +{ + KX_Scene* scene = FindScene(scenename); + if (scene) scene->Suspend(); +} + + + +void KX_KetsjiEngine::ResumeScene(const STR_String& scenename) +{ + KX_Scene* scene = FindScene(scenename); + if (scene) scene->Resume(); +} + + + +void KX_KetsjiEngine::SetUseFixedTime(bool bUseFixedTime) +{ + m_bFixedTime = bUseFixedTime; +} + + + +bool KX_KetsjiEngine::GetUseFixedTime(void) const +{ + return m_bFixedTime; +} + + + +void KX_KetsjiEngine::SetTimingDisplay(bool frameRate, bool profile, bool properties) +{ + m_show_framerate = frameRate; + m_show_profile = profile; + m_show_debug_properties = properties; +} + + + +void KX_KetsjiEngine::GetTimingDisplay(bool& frameRate, bool& profile, bool& properties) const +{ + frameRate = m_show_framerate; + profile = m_show_profile; + properties = m_show_debug_properties; +} + + + +void KX_KetsjiEngine::ProcessScheduledScenes(void) +{ + // Check whether there will be changes to the list of scenes + if (m_addingOverlayScenes.size() || + m_addingBackgroundScenes.size() || + m_replace_scenes.size() || + m_removingScenes.size()) { + + // Change the scene list + ReplaceScheduledScenes(); + RemoveScheduledScenes(); + AddScheduledScenes(); + + // Notify + SceneListsChanged(); + } +} + + + +void KX_KetsjiEngine::SceneListsChanged(void) +{ + m_propertiesPresent = false; + KX_SceneList::iterator sceneit = m_scenes.begin(); + while ((sceneit != m_scenes.end()) && (!m_propertiesPresent)) + { + KX_Scene* scene = *sceneit; + vector<SCA_DebugProp*>& debugproplist = scene->GetDebugProperties(); + m_propertiesPresent = !debugproplist.empty(); + sceneit++; + } +} + + +void KX_KetsjiEngine::SetHideCursor(bool hideCursor) +{ + m_hideCursor = hideCursor; +} + + +bool KX_KetsjiEngine::GetHideCursor(void) const +{ + return m_hideCursor; +} + + +void KX_KetsjiEngine::SetUseOverrideFrameColor(bool overrideFrameColor) +{ + m_overrideFrameColor = overrideFrameColor; +} + + +bool KX_KetsjiEngine::GetUseOverrideFrameColor(void) const +{ + return m_overrideFrameColor; +} + + +void KX_KetsjiEngine::SetOverrideFrameColor(float r, float g, float b) +{ + m_overrideFrameColorR = r; + m_overrideFrameColorG = g; + m_overrideFrameColorB = b; +} + + +void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const +{ + r = m_overrideFrameColorR; + g = m_overrideFrameColorG; + b = m_overrideFrameColorB; +} + diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h new file mode 100644 index 00000000000..4246bc28b50 --- /dev/null +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -0,0 +1,316 @@ +/* + * $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_KETSJI_ENGINE +#define __KX_KETSJI_ENGINE + +#include "MT_CmMatrix4x4.h" +#include "MT_Matrix4x4.h" +#include "STR_String.h" +#include "KX_ISystem.h" +#include "KX_Scene.h" +#include "KX_Python.h" +#include "KX_WorldInfo.h" +#include <vector> +#include <set> + +class KX_TimeCategoryLogger; + +#define LEFT_EYE 1 +#define RIGHT_EYE 2 + +enum KX_ExitRequestMode +{ + KX_EXIT_REQUEST_NO_REQUEST = 0, + KX_EXIT_REQUEST_QUIT_GAME, + KX_EXIT_REQUEST_RESTART_GAME, + KX_EXIT_REQUEST_START_OTHER_GAME, + KX_EXIT_REQUEST_NO_SCENES_LEFT, + KX_EXIT_REQUEST_BLENDER_ESC, + KX_EXIT_REQUEST_OUTSIDE, + KX_EXIT_REQUEST_MAX +}; + +class KX_KetsjiEngine +{ + +private: + class RAS_ICanvas* m_canvas; // 2D Canvas (2D Rendering Device Context) + class RAS_IRasterizer* m_rasterizer; // 3D Rasterizer (3D Rendering) + class KX_ISystem* m_kxsystem; + class RAS_IRenderTools* m_rendertools; + class KX_ISceneConverter* m_sceneconverter; + class NG_NetworkDeviceInterface* m_networkdevice; + class SND_IAudioDevice* m_audiodevice; + PyObject* m_pythondictionary; + class SCA_IInputDevice* m_keyboarddevice; + class SCA_IInputDevice* m_mousedevice; + + /** Lists of scenes scheduled to be removed at the end of the frame. */ + std::set<STR_String> m_removingScenes; + /** Lists of overley scenes scheduled to be added at the end of the frame. */ + std::set<STR_String> m_addingOverlayScenes; + /** Lists of background scenes scheduled to be added at the end of the frame. */ + std::set<STR_String> m_addingBackgroundScenes; + /** Lists of scenes scheduled to be replaced at the end of the frame. */ + std::set<std::pair<STR_String,STR_String> > m_replace_scenes; + + /* The current list of scenes. */ + KX_SceneList m_scenes; + /* State variable recording the presence of object debug info in the current scene list. */ + bool m_propertiesPresent; + + bool m_bInitialized; + int m_activecam; + bool m_bFixedTime; + + bool m_firstframe; + double m_previoustime; + double m_missedtime; + double m_lasttime; // old style time + double m_dtime; + std::vector<double> m_deltatimes; + + int m_exitcode; + STR_String m_exitstring; + /** + * Some drawing parameters, the drawing mode + * (wire/flat/texture), and the camera zoom + * factor. + */ + int m_drawingmode; + float m_cameraZoom; + + bool m_overrideCam; + STR_String m_overrideSceneName; + + bool m_overrideCamUseOrtho; + MT_CmMatrix4x4 m_overrideCamProjMat; + MT_CmMatrix4x4 m_overrideCamViewMat; + + bool m_stereo; + int m_curreye; + + /** Categories for profiling display. */ + typedef enum + { + tc_first = 0, + tc_physics = 0, + tc_logic, + tc_network, + tc_scenegraph, + tc_sound, + tc_rasterizer, + tc_services, // time spend in miscelaneous activities + tc_overhead, // profile info drawing overhead + tc_outside, // time spend outside main loop + tc_numCategories + } KX_TimeCategory; + + /** Time logger. */ + KX_TimeCategoryLogger* m_logger; + + /** Labels for profiling display. */ + static const char m_profileLabels[tc_numCategories][15]; + /** Show the framerate on the game display? */ + bool m_show_framerate; + /** Show profiling info on the game display? */ + bool m_show_profile; + /** Show any debug (scene) object properties on the game display? */ + bool m_showProperties; + /** Show background behind text for readability? */ + bool m_showBackground; + + bool m_show_debug_properties; + + /** Hide cursor every frame? */ + bool m_hideCursor; + + /** Override framing bars color? */ + bool m_overrideFrameColor; + /** Red component of framing bar color. */ + float m_overrideFrameColorR; + /** Green component of framing bar color. */ + float m_overrideFrameColorG; + /** Blue component of framing bar color. */ + float m_overrideFrameColorB; + + double CalculateAverage(double newdeltatime); + + void SetupRenderFrame(KX_Scene *scene); + void RenderFrame(KX_Scene* scene); + void RenderDebugProperties(); + void SetBackGround(KX_WorldInfo* worldinfo); + void SetWorldSettings(KX_WorldInfo* worldinfo); + void DoSound(KX_Scene* scene); + +public: + + KX_KetsjiEngine(class KX_ISystem* system); + virtual ~KX_KetsjiEngine(); + + // set the devices and stuff. the client must take care of creating these + void SetKeyboardDevice(SCA_IInputDevice* keyboarddevice); + void SetMouseDevice(SCA_IInputDevice* mousedevice); + void SetNetworkDevice(NG_NetworkDeviceInterface* networkdevice); + void SetAudioDevice(SND_IAudioDevice* audiodevice); + void SetCanvas(RAS_ICanvas* canvas); + void SetRenderTools(RAS_IRenderTools* rendertools); + void SetRasterizer(RAS_IRasterizer* rasterizer); + void SetPythonDictionary(PyObject* pythondictionary); + void SetSceneConverter(KX_ISceneConverter* sceneconverter); + + void NextFrame(); + void Render(); + + void StartEngine(); + void StopEngine(); + void Export(const STR_String& filename); + + void RequestExit(int exitrequestmode); + void SetNameNextGame(const STR_String& nextgame); + int GetExitCode(); + const STR_String& GetExitString(); + + KX_SceneList* CurrentScenes(); + KX_Scene* FindScene(const STR_String& scenename); + void AddScene(class KX_Scene* scene); + void ConvertAndAddScene(const STR_String& scenename,bool overlay); + + void RemoveScene(const STR_String& scenename); + void ReplaceScene(const STR_String& oldscene,const STR_String& newscene); + void SuspendScene(const STR_String& scenename); + void ResumeScene(const STR_String& scenename); + + void SetDrawType(int drawingtype); + void SetCameraZoom(float camzoom); + + void EnableCameraOverride(const STR_String& forscene); + + void SetCameraOverrideUseOrtho(bool useOrtho); + void SetCameraOverrideProjectionMatrix(const MT_CmMatrix4x4& mat); + void SetCameraOverrideViewMatrix(const MT_CmMatrix4x4& mat); + + /** + * Sets display of all frames. + * @param bUseFixedTime New setting for display all frames. + */ + void SetUseFixedTime(bool bUseFixedTime); + + /** + * Returns display of all frames. + * @return Current setting for display all frames. + */ + bool GetUseFixedTime(void) const; + + /** + * Activates or deactivates timing information display. + * @param frameRate Display for frame rate on or off. + * @param profile Display for individual components on or off. + * @param properties Display of scene object debug properties on or off. + */ + void SetTimingDisplay(bool frameRate, bool profile, bool properties); + + /** + * Returns status of timing information display. + * @param frameRate Display for frame rate on or off. + * @param profile Display for individual components on or off. + * @param properties Display of scene object debug properties on or off. + */ + void GetTimingDisplay(bool& frameRate, bool& profile, bool& properties) const; + + /** + * Sets cursor hiding on every frame. + * @param hideCursor Turns hiding on or off. + */ + void SetHideCursor(bool hideCursor); + + /** + * Returns the current setting for cursor hiding. + * @return The current setting for cursor hiding. + */ + bool GetHideCursor(void) const; + + /** + * Enables/disables the use of the framing bar color of the Blender file's scenes. + * @param overrideFrameColor The new setting. + */ + void SetUseOverrideFrameColor(bool overrideFrameColor); + + /** + * Enables/disables the use of the framing bar color of the Blender file's scenes. + * @param useSceneFrameColor The new setting. + */ + bool GetUseOverrideFrameColor(void) const; + + /** + * Set the color used for framing bar color instead of the one in the Blender file's scenes. + * @param r Red component of the override color. + * @param g Green component of the override color. + * @param b Blue component of the override color. + */ + void SetOverrideFrameColor(float r, float g, float b); + + /** + * Returns the color used for framing bar color instead of the one in the Blender file's scenes. + * @param r Red component of the override color. + * @param g Green component of the override color. + * @param b Blue component of the override color. + */ + void GetOverrideFrameColor(float& r, float& g, float& b) const; + +protected: + /** + * Processes all scheduled scene activity. + * At the end, if the scene lists have changed, + * SceneListsChanged(void) is called. + * @see SceneListsChanged(void). + */ + void ProcessScheduledScenes(void); + + /** + * This method is invoked when the scene lists have changed. + */ + void SceneListsChanged(void); + + void RemoveScheduledScenes(void); + void AddScheduledScenes(void); + void ReplaceScheduledScenes(void); + void PostProcessScene(class KX_Scene* scene); + KX_Scene* CreateScene(const STR_String& scenename); + + bool BeginFrame(); + void EndFrame(); +}; + +#endif //__KX_KETSJI_ENGINE + diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp new file mode 100644 index 00000000000..25e756ae66c --- /dev/null +++ b/source/gameengine/Ketsji/KX_Light.cpp @@ -0,0 +1,75 @@ +/** + * $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 + +#include "KX_Light.h" +#include "RAS_IRenderTools.h" + + +KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks, + class RAS_IRenderTools* rendertools, + const RAS_LightObject& lightobj + ) + : + KX_GameObject(sgReplicationInfo,callbacks), + m_rendertools(rendertools) +{ + m_lightobj = lightobj; + m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr(); + m_rendertools->AddLight(&m_lightobj); +}; + + +KX_LightObject::~KX_LightObject() +{ + + m_rendertools->RemoveLight(&m_lightobj); +} + + +CValue* KX_LightObject::GetReplica() +{ + + KX_LightObject* replica = new KX_LightObject(*this); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + ProcessReplica(replica); + + replica->m_lightobj.m_worldmatrix = replica->GetOpenGLMatrixPtr(); + m_rendertools->AddLight(&replica->m_lightobj); + return replica; +} diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h new file mode 100644 index 00000000000..0ee91040c84 --- /dev/null +++ b/source/gameengine/Ketsji/KX_Light.h @@ -0,0 +1,50 @@ +/** + * $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_LIGHT +#define __KX_LIGHT + +#include "RAS_LightObject.h" +#include "KX_GameObject.h" + +class KX_LightObject : public KX_GameObject +{ + RAS_LightObject m_lightobj; + class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj + +public: + KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj); + virtual ~KX_LightObject(); + virtual CValue* GetReplica(); + RAS_LightObject* GetLightData() { return &m_lightobj;} +}; + +#endif //__KX_LIGHT diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.cpp b/source/gameengine/Ketsji/KX_LightIpoSGController.cpp new file mode 100644 index 00000000000..3dd26947a79 --- /dev/null +++ b/source/gameengine/Ketsji/KX_LightIpoSGController.cpp @@ -0,0 +1,118 @@ +/** + * $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_LightIpoSGController.h" + +#include "KX_ScalarInterpolator.h" +#include "KX_Light.h" + +#include "RAS_LightObject.h" + + +bool KX_LightIpoSGController::Update(double currentTime) +{ + if (m_modified) + { + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + (*i)->Execute(m_ipotime);//currentTime); + } + + RAS_LightObject *lightobj; + + SG_Spatial* ob = (SG_Spatial*)m_pObject; + KX_LightObject* kxlight = (KX_LightObject*) ob->GetSGClientObject(); + lightobj = kxlight->GetLightData(); + //lightobj = (KX_Light*) + + if (m_modify_energy) { + lightobj->m_energy = m_energy; + } + + if (m_modify_color) { + lightobj->m_red = m_col_rgb[0]; + lightobj->m_green = m_col_rgb[1]; + lightobj->m_blue = m_col_rgb[2]; + } + + if (m_modify_dist) { + lightobj->m_distance = m_dist; + } + + m_modified=false; + } + return false; +} + + +void KX_LightIpoSGController::AddInterpolator(KX_IInterpolator* interp) +{ + this->m_interpolators.push_back(interp); +} + +SG_Controller* KX_LightIpoSGController::GetReplica(class SG_Node* destnode) +{ + KX_LightIpoSGController* iporeplica = new KX_LightIpoSGController(*this); + // clear object that ipo acts on + iporeplica->ClearObject(); + + // dirty hack, ask Gino for a better solution in the ipo implementation + // hacken en zagen, in what we call datahiding, not written for replication :( + + T_InterpolatorList oldlist = m_interpolators; + iporeplica->m_interpolators.clear(); + + T_InterpolatorList::iterator i; + for (i = oldlist.begin(); !(i == oldlist.end()); ++i) { + KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i)); + iporeplica->AddInterpolator(copyipo); + + MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget(); + int orgbase = (int)this; + int orgloc = (int)scaal; + int offset = orgloc-orgbase; + int newaddrbase = (int)iporeplica + offset; + MT_Scalar* blaptr = (MT_Scalar*) newaddrbase; + copyipo->SetNewTarget((MT_Scalar*)blaptr); + } + + return iporeplica; +} + +KX_LightIpoSGController::~KX_LightIpoSGController() +{ + + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + delete (*i); + } + +} diff --git a/source/gameengine/Ketsji/KX_LightIpoSGController.h b/source/gameengine/Ketsji/KX_LightIpoSGController.h new file mode 100644 index 00000000000..2b115fcc00f --- /dev/null +++ b/source/gameengine/Ketsji/KX_LightIpoSGController.h @@ -0,0 +1,99 @@ +/** + * $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_LIGHTIPOSGCONTROLLER_H +#define KX_LIGHTIPOSGCONTROLLER_H + +#include "SG_Controller.h" +#include "SG_Spatial.h" + +#include "KX_IInterpolator.h" + +struct RAS_LightObject; + +class KX_LightIpoSGController : public SG_Controller +{ +public: + MT_Scalar m_energy; + MT_Scalar m_col_rgb[3]; + MT_Scalar m_dist; + +private: + T_InterpolatorList m_interpolators; + unsigned short m_modify_energy : 1; + unsigned short m_modify_color : 1; + unsigned short m_modify_dist : 1; + bool m_modified; + + double m_ipotime; +public: + KX_LightIpoSGController() : m_ipotime(0.0), + m_modify_energy(false), + m_modify_color(false), + m_modify_dist(false), + m_modified(true) + {} + + virtual ~KX_LightIpoSGController(); + + virtual SG_Controller* GetReplica(class SG_Node* destnode); + + virtual bool Update(double time); + + virtual void SetSimulatedTime(double time) { + m_ipotime = time; + m_modified = true; + } + + void SetModifyEnergy(bool modify) { + m_modify_energy = modify; + } + + void SetModifyColor(bool modify) { + m_modify_color = modify; + } + + void SetModifyDist(bool modify) { + m_modify_dist = modify; + } + + void + SetOption( + int option, + int value + ){ + // intentionally empty + }; + + void AddInterpolator(KX_IInterpolator* interp); +}; + +#endif // KX_LIGHTIPOSGCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp new file mode 100644 index 00000000000..f17e5820d52 --- /dev/null +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -0,0 +1,193 @@ +/** + * $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_MeshProxy.h" + +#include "RAS_IPolygonMaterial.h" +#include "RAS_MeshObject.h" +#include "KX_VertexProxy.h" + + +PyTypeObject KX_MeshProxy::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_MeshProxy", + sizeof(KX_MeshProxy), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_MeshProxy::Parents[] = { + &KX_MeshProxy::Type, + &SCA_IObject::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_MeshProxy::Methods[] = { +{"getNumMaterials", (PyCFunction)KX_MeshProxy::sPyGetNumMaterials,METH_VARARGS}, +{"getMaterialName", (PyCFunction)KX_MeshProxy::sPyGetMaterialName,METH_VARARGS}, +{"getTextureName", (PyCFunction)KX_MeshProxy::sPyGetTextureName,METH_VARARGS}, +{"getVertexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetVertexArrayLength,METH_VARARGS}, +{"getVertex", (PyCFunction)KX_MeshProxy::sPyGetVertex,METH_VARARGS}, +//{"getIndexArrayLength", (PyCFunction)KX_MeshProxy::sPyGetIndexArrayLength,METH_VARARGS}, + + {NULL,NULL} //Sentinel +}; + +PyObject* +KX_MeshProxy::_getattr(char* attr) +{ + _getattr_up(SCA_IObject); +} + + + +KX_MeshProxy::KX_MeshProxy(RAS_MeshObject* mesh) + : m_meshobj(mesh) +{ + +} + +KX_MeshProxy::~KX_MeshProxy() +{ + +} + + + +// stuff for cvalue related things +CValue* KX_MeshProxy::Calc(VALUE_OPERATOR op, CValue *val) { return NULL;} +CValue* KX_MeshProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) { return NULL;} + +const STR_String & KX_MeshProxy::GetText() {return m_meshobj->GetName();}; +float KX_MeshProxy::GetNumber() { return -1;} +STR_String KX_MeshProxy::GetName() { return m_meshobj->GetName();} +void KX_MeshProxy::SetName(STR_String name) { }; +CValue* KX_MeshProxy::GetReplica() { return NULL;} +void KX_MeshProxy::ReplicaSetName(STR_String name) {}; + + +// stuff for python integration + +PyObject* KX_MeshProxy::PyGetNumMaterials(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int num = m_meshobj->NumMaterials(); + return PyInt_FromLong(num); +} + +PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int matid= 1; + STR_String matname; + + if (PyArg_ParseTuple(args,"i",&matid)) + { + matname = m_meshobj->GetMaterialName(matid); + } + + return PyString_FromString(matname.Ptr()); + +} + + +PyObject* KX_MeshProxy::PyGetTextureName(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int matid= 1; + STR_String matname; + + if (PyArg_ParseTuple(args,"i",&matid)) + { + matname = m_meshobj->GetTextureName(matid); + } + + return PyString_FromString(matname.Ptr()); + +} + +PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int matid= -1; + int length = -1; + + + if (PyArg_ParseTuple(args,"i",&matid)) + { + RAS_IPolyMaterial* mat = m_meshobj->GetMaterialBucket(matid)->GetPolyMaterial(); + if (mat) + { + length = m_meshobj->GetVertexArrayLength(mat); + } + } + + return PyInt_FromLong(length); + +} + + +PyObject* KX_MeshProxy::PyGetVertex(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int vertexindex= 1; + int matindex= 1; + PyObject* vertexob = NULL; + + if (PyArg_ParseTuple(args,"ii",&matindex,&vertexindex)) + { + RAS_TexVert* vertex = m_meshobj->GetVertex(matindex,vertexindex); + if (vertex) + { + vertexob = new KX_VertexProxy(vertex); + } + } + + return vertexob; + +} diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h new file mode 100644 index 00000000000..a6c5b7558a2 --- /dev/null +++ b/source/gameengine/Ketsji/KX_MeshProxy.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 __KX_MESHPROXY +#define __KX_MESHPROXY + +#include "SCA_IObject.h" + +class KX_MeshProxy : public SCA_IObject +{ + Py_Header; + + class RAS_MeshObject* m_meshobj; +public: + KX_MeshProxy(class RAS_MeshObject* mesh); + virtual ~KX_MeshProxy(); + + // stuff for cvalue related things + virtual CValue* Calc(VALUE_OPERATOR op, CValue *val) ; + virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val); + virtual const STR_String & GetText(); + virtual float GetNumber(); + virtual STR_String GetName(); + virtual void SetName(STR_String name); // Set the name of the value + virtual void ReplicaSetName(STR_String name); + virtual CValue* GetReplica(); + +// stuff for python integration + virtual PyObject* _getattr(char *attr); + KX_PYMETHOD(KX_MeshProxy,GetNumMaterials); + KX_PYMETHOD(KX_MeshProxy,GetMaterialName); + KX_PYMETHOD(KX_MeshProxy,GetTextureName); + + // both take materialid (int) + KX_PYMETHOD(KX_MeshProxy,GetVertexArrayLength); + KX_PYMETHOD(KX_MeshProxy,GetVertex); +}; +#endif //__KX_MESHPROXY diff --git a/source/gameengine/Ketsji/KX_MotionState.cpp b/source/gameengine/Ketsji/KX_MotionState.cpp new file mode 100644 index 00000000000..50b1943e5f0 --- /dev/null +++ b/source/gameengine/Ketsji/KX_MotionState.cpp @@ -0,0 +1,91 @@ +/** + * $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_MotionState.h" +#include "SG_Spatial.h" + +KX_MotionState::KX_MotionState(SG_Spatial* node) : m_node(node) +{ + +} + +KX_MotionState::~KX_MotionState() +{ +} + +void KX_MotionState::getWorldPosition(float& posX,float& posY,float& posZ) +{ + MT_Point3 pos = m_node->GetWorldPosition(); + posX = pos[0]; + posY = pos[1]; + posZ = pos[2]; +} + +void KX_MotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ) +{ + MT_Vector3 scale = m_node->GetWorldScaling(); + scaleX = scale[0]; + scaleY = scale[1]; + scaleZ = scale[2]; +} + +void KX_MotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal) +{ + MT_Quaternion orn = m_node->GetWorldOrientation().getRotation(); + quatIma0 = orn[0]; + quatIma1 = orn[1]; + quatIma2 = orn[2]; + quatReal = orn[3]; +} + +void KX_MotionState::setWorldPosition(float posX,float posY,float posZ) +{ + m_node->SetLocalPosition(MT_Point3(posX,posY,posZ)); + +} + +void KX_MotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal) +{ + MT_Quaternion orn; + orn[0] = quatIma0; + orn[1] = quatIma1; + orn[2] = quatIma2; + orn[3] = quatReal; + + m_node->SetLocalOrientation(orn); +} + +void KX_MotionState::calculateWorldTransformations() +{ + m_node->ComputeWorldTransforms(NULL); +} + + diff --git a/source/gameengine/Ketsji/KX_MotionState.h b/source/gameengine/Ketsji/KX_MotionState.h new file mode 100644 index 00000000000..3d0f9bd40be --- /dev/null +++ b/source/gameengine/Ketsji/KX_MotionState.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_MOTIONSTATE +#define __KX_MOTIONSTATE + +#include "PHY_IMotionState.h" + +class KX_MotionState : public PHY_IMotionState +{ + class SG_Spatial* m_node; + +public: + KX_MotionState(class SG_Spatial* spatial); + virtual ~KX_MotionState(); + + virtual void getWorldPosition(float& posX,float& posY,float& posZ); + virtual void getWorldScaling(float& scaleX,float& scaleY,float& scaleZ); + virtual void getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal); + virtual void setWorldPosition(float posX,float posY,float posZ); + virtual void setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal); + + virtual void calculateWorldTransformations(); +}; + +#endif //__KX_MOTIONSTATE diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp new file mode 100644 index 00000000000..006215b9fe8 --- /dev/null +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp @@ -0,0 +1,353 @@ +/** + * $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 ***** + * KX_MouseFocusSensor determines mouse in/out/over events. + */ + +#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 "MT_Point3.h" + +#include "KX_ClientObjectInfo.h" + + +#include "RAS_FramingManager.h" +#include "RAS_ICanvas.h" +#include "RAS_IRasterizer.h" + +#include "SCA_IScene.h" + +#include "KX_Scene.h" +#include "KX_Camera.h" + +#include "KX_MouseFocusSensor.h" + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr, + int startx, + int starty, + short int mousemode, + bool focusmode, + RAS_ICanvas* canvas, + KX_Scene* kxscene, + SCA_IObject* gameobj, + PyTypeObject* T) + : SCA_MouseSensor(eventmgr, startx, starty, mousemode, gameobj, T), + m_focusmode(focusmode), + m_gp_canvas(canvas), + m_kxscene(kxscene) +{ + /* Or postpone? I think a sumo scene and kx scene go pretty much + * together, so it should be safe to do it here. */ + m_mouse_over_in_previous_frame = false; + m_positive_event = false; +} + +bool KX_MouseFocusSensor::Evaluate(CValue* event) +{ + bool result = false; + bool obHasFocus = false; + +// cout << "evaluate focus mouse sensor "<<endl; + + if (m_focusmode) { + /* Focus behaviour required. Test mouse-on. The rest is + * equivalent to handling a key. */ + obHasFocus = ParentObjectHasFocus(); + + if (!obHasFocus) { + if (m_mouse_over_in_previous_frame) { + m_positive_event = false; + result = true; + } + } else { + if (!m_mouse_over_in_previous_frame) { + m_positive_event = true; + result = true; + } + } + } else { + /* No focus behaviour required: revert to the basic mode. This + * mode is never used, because the converter never makes this + * sensor for a mouse-key event. It is here for + * completeness. */ + result = SCA_MouseSensor::Evaluate(event); + m_positive_event = (m_val!=0); + } + + m_mouse_over_in_previous_frame = obHasFocus; + + return result; +} + +bool KX_MouseFocusSensor::ParentObjectHasFocus(void) +{ + + bool res = false; + m_hitPosition = MT_Vector3(0,0,0); + m_hitNormal = MT_Vector3(1,0,0); + MT_Point3 resultpoint; + MT_Vector3 resultnormal; + + /* All screen handling in the gameengine is done by GL, + * specifically the model/view and projection parts. The viewport + * part is in the creator. + * + * The theory is this: + * WCS - world coordinates + * -> wcs_camcs_trafo -> + * camCS - camera coordinates + * -> camcs_clip_trafo -> + * clipCS - normalised device coordinates? + * -> normview_win_trafo + * winCS - window coordinates + * + * The first two transforms are respectively the model/view and + * the projection matrix. These are passed to the rasterizer, and + * we store them in the camera for easy access. + * + * For normalised device coords (xn = x/w, yn = y/w/zw) the + * windows coords become (lb = left bottom) + * + * xwin = [(xn + 1.0) * width]/2 + x_lb + * ywin = [(yn + 1.0) * height]/2 + y_lb + * + * Inverting (blender y is flipped!): + * + * xn = 2(xwin - x_lb)/width - 1.0 + * yn = 2(ywin - y_lb)/height - 1.0 + * = 2(height - y_blender - y_lb)/height - 1.0 + * = 1.0 - 2(y_blender - y_lb)/height + * + * */ + + /* Because we don't want to worry about resize events, camera + * changes and all that crap, we just determine this over and + * over. Stop whining. We have lots of other calculations to do + * here as well. These reads are not the main cost. If there is no + * canvas, the test is irrelevant. The 1.0 makes sure the + * calculations don't bomb. Maybe we should explicitly guard for + * division by 0.0...*/ + + /** + * Get the scenes current viewport. + */ + + const RAS_Rect & viewport = m_kxscene->GetSceneViewport(); + + float height = float(viewport.m_y2 - viewport.m_y1 + 1); + float width = float(viewport.m_x2 - viewport.m_x1 + 1); + + float x_lb = float(viewport.m_x1); + float y_lb = float(viewport.m_y1); + + KX_Camera* cam = m_kxscene->GetActiveCamera(); + /* There's some strangeness I don't fully get here... These values + * _should_ be wrong! */ + + /* old: */ + float nearclip = 0.0; + float farclip = -1.0; + + /* build the from and to point in normalised device coordinates + * Looks like normailized device coordinates are [-1,1] in x [-1,1] in y + * [0,-1] in z + * + * The actual z coordinates used don't have to be exact just infront and + * behind of the near and far clip planes. + */ + + MT_Vector4 frompoint = MT_Vector4( + (2 * (m_x-x_lb) / width) - 1.0, + 1.0 - (2 * (m_y - y_lb) / height), + (nearclip + 3 * farclip) / (farclip - nearclip), + 1.0 + ); + MT_Vector4 topoint = MT_Vector4( + (2 * (m_x-x_lb) / width) - 1.0, + 1.0 - (2 * (m_y-y_lb) / height), + (3 * nearclip + farclip) / (farclip - nearclip), + 1.0 + ); + + /* camera to world */ + MT_Matrix4x4 camcs_wcs_matrix; + cam->GetModelviewMatrix(camcs_wcs_matrix); + camcs_wcs_matrix.invert(); + + MT_Matrix4x4 clip_camcs_matrix; + /* badly defined, the first time round.... I wonder why... I might + * want to guard against floating point errors here.*/ + cam->GetProjectionMatrix(clip_camcs_matrix); + clip_camcs_matrix.invert(); + + /* shoot-points: clip to cam to wcs . win to clip was already done.*/ + frompoint = clip_camcs_matrix * frompoint; + topoint = clip_camcs_matrix * topoint; + frompoint = camcs_wcs_matrix * frompoint; + topoint = camcs_wcs_matrix * topoint; + + /* from hom wcs to 3d wcs: */ + MT_Point3 frompoint3 = MT_Point3(frompoint[0]/frompoint[3], + frompoint[1]/frompoint[3], + frompoint[2]/frompoint[3]); + MT_Point3 topoint3 = MT_Point3(topoint[0]/topoint[3], + topoint[1]/topoint[3], + topoint[2]/topoint[3]); + m_prevTargetPoint = topoint3; + + /* 2. Get the object from SuMO*/ + /* Shoot! Beware that the first argument here is an + * ignore-object. We don't ignore anything... */ + KX_GameObject* thisObj = (KX_GameObject*) GetParent(); + + + //SM_Object* hitSMObj = m_sumoScene->rayTest(NULL, + // frompoint3, + // topoint3, + // resultpoint, + // resultnormal); + + KX_GameObject* hitKXObj = 0; + + /* all this casting makes me nervous... */ + //SM_ClientObjectInfo* client_info + // = ( hitSMObj ? + // (SM_ClientObjectInfo*) ((SM_Object*)hitSMObj)->getClientObject() : + // NULL); + //KX_GameObject* hitKXObj = ( client_info ? + // (KX_GameObject*)client_info->m_clientobject : + // NULL); + + + /* Is this me? In the ray test, there are a lot of extra checks + * for aliasing artefacts from self-hits. That doesn't happen + * here, so a simple test suffices. Or does the camera also get + * self-hits? (No, and the raysensor shouldn't do it either, since + * self-hits are excluded by setting the correct ignore-object.) + * Hitspots now become valid. */ + if (hitKXObj == thisObj) + { + m_hitPosition = resultpoint; + m_hitNormal = resultnormal; + res = true; + } + + return res; +} + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_MouseFocusSensor::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_MouseFocusSensor", + sizeof(KX_MouseFocusSensor), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_MouseFocusSensor::Parents[] = { + &KX_MouseFocusSensor::Type, + &SCA_MouseSensor::Type, + &SCA_ISensor::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_MouseFocusSensor::Methods[] = { + {"getRayTarget", (PyCFunction) KX_MouseFocusSensor::sPyGetRayTarget, + METH_VARARGS, GetRayTarget_doc}, + {"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource, + METH_VARARGS, GetRaySource_doc}, + {NULL,NULL} //Sentinel +}; + +PyObject* KX_MouseFocusSensor::_getattr(char* attr) { + _getattr_up(SCA_MouseSensor); +} + +/* getRayTarget */ +char KX_MouseFocusSensor::GetRayTarget_doc[] = +"getRayTarget()\n" +"\tReturns the target of the ray that seeks the focus object,\n" +"\tin worldcoordinates."; +PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *retVal = PyList_New(3); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevTargetPoint[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevTargetPoint[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevTargetPoint[2])); + + return retVal; +} + +/* getRayTarget */ +char KX_MouseFocusSensor::GetRaySource_doc[] = +"getRaySource()\n" +"\tReturns the source of the ray that seeks the focus object,\n" +"\tin worldcoordinates."; +PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *retVal = PyList_New(3); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevSourcePoint[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevSourcePoint[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevSourcePoint[2])); + + return retVal; +} + +/* eof */ + diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h new file mode 100644 index 00000000000..590f69a81b3 --- /dev/null +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -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 ***** + * KX_MouseFocusSensor determines mouse in/out/over events. + */ + +#ifndef __KX_MOUSEFOCUSSENSOR +#define __KX_MOUSEFOCUSSENSOR + +#include "SCA_MouseSensor.h" +/* #include "SCA_IInputDevice.h" */ + +/** + * The mouse focus sensor extends the basic SCA_MouseSensor. It has + * been placed in KX because it needs access to the rasterizer and + * SuMO. + * + * - extend the valid modes? + * - */ +class KX_MouseFocusSensor : public SCA_MouseSensor +{ + + Py_Header; + + public: + + KX_MouseFocusSensor(class SCA_MouseManager* keybdmgr, + int startx, + int starty, + short int mousemode, + bool focusmode, + RAS_ICanvas* canvas, + KX_Scene* kxscene, + SCA_IObject* gameobj, + PyTypeObject* T=&Type ); + + virtual ~KX_MouseFocusSensor() { ; }; + virtual CValue* GetReplica() { + CValue* replica = new KX_MouseFocusSensor(*this); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; + }; + /** + * @attention Overrides default evaluate. + */ + virtual bool Evaluate(CValue* event); + + virtual bool IsPositiveTrigger() { + bool result = m_positive_event; + if (m_invert) result = !result; + return result; + }; + + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + virtual PyObject* _getattr(char *attr); + + KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRayTarget); + KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRaySource); + + /* --------------------------------------------------------------------- */ + + private: + /** + * The focus mode. True for handling focus, false for not handling + * it. */ + bool m_focusmode; + + /** + * Flags whether the previous test showed a mouse-over. + */ + bool m_mouse_over_in_previous_frame; + + /** + * Flags whether the previous test evaluated positive. + */ + bool m_positive_event; + + + /** + * Tests whether the object is in mouse focus in this frame. + */ + bool ParentObjectHasFocus(void); + + /** + * (in game world coordinates) the place where the object was hit. + */ + MT_Point3 m_hitPosition; + + /** + * (in game world coordinates) the position to which to shoot the ray. + */ + MT_Point3 m_prevTargetPoint; + + /** + * (in game world coordinates) the position from which to shoot the ray. + */ + MT_Point3 m_prevSourcePoint; + + /** + * (in game world coordinates) the face normal of the vertex where + * the object was hit. */ + MT_Vector3 m_hitNormal; + + /** + * Ref to the engine, for retrieving a reference to the current + * scene. */ + class KX_KetsjiEngine* m_engine; + + /** + * The active canvas. The size of this canvas determines a part of + * the start position of the picking ray. */ + RAS_ICanvas* m_gp_canvas; + + /** + * The KX scene that holds the camera. The camera position + * determines a part of the start location of the picking ray. */ + KX_Scene* m_kxscene; + +}; + +#endif //__KX_MOUSESENSOR diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp new file mode 100644 index 00000000000..0388f7cc332 --- /dev/null +++ b/source/gameengine/Ketsji/KX_NearSensor.cpp @@ -0,0 +1,262 @@ +/** + * Sense if other objects are near + * + * $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_NearSensor.h" +#include "SCA_LogicManager.h" +#include "KX_GameObject.h" +#include "KX_TouchEventManager.h" +#include "KX_Scene.h" // needed to create a replica + + +#ifdef PHYSICS_NOT_YET + +KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr, + KX_GameObject* gameobj, + double margin, + double resetmargin, + bool bFindMaterial, + const STR_String& touchedpropname, + class KX_Scene* scene, + PyTypeObject* T) + :KX_TouchSensor(eventmgr, + gameobj, + bFindMaterial, + touchedpropname, + scene, + T), + m_Margin(margin), + m_ResetMargin(resetmargin), + m_sumoScene(sumoscene) + +{ + m_client_info.m_type = 4; + m_client_info.m_clientobject = gameobj; + m_client_info.m_auxilary_info = NULL; + sumoObj->setClientObject(&m_client_info); +} + + + +CValue* KX_NearSensor::GetReplica() +{ + KX_NearSensor* replica = new KX_NearSensor(*this); + replica->m_colliders = new CListValue(); + replica->m_bCollision = false; + replica->m_bTriggered= false; + replica->m_hitObject = NULL; + replica->m_bLastTriggered = false; + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +} + + + +void KX_NearSensor::ReParent(SCA_IObject* parent) +{ + 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(m_Margin); + + //sumoObj->setPosition(gameobj->NodeGetWorldPosition()); + //sumoobj->setPosition(m_sumoObj->getPosition()); + //sumoobj->setOrientation(m_sumoObj->getOrientation()); + //newobj->setRigidBody(this->m_sumoObj->isRigidBody()); + + m_sumoObj = sumoObj; + m_solidHandle = m_sumoObj->getObjectHandle(); + + double radius = m_sumoObj->getMargin(); + sumoObj->setMargin(m_sumoObj->getMargin()); + + m_client_info.m_type = 4; + m_client_info.m_clientobject = parent; + m_client_info.m_auxilary_info = NULL; + sumoObj->setClientObject(&m_client_info); + + //m_sumoScene->add(*newobj); + + if (m_sumoObj) + { + DT_SetObjectResponse(m_resptable, + m_sumoObj->getObjectHandle(), + collisionResponse, + DT_SIMPLE_RESPONSE, + this); + } + + SCA_ISensor::ReParent(parent); +} + + + +KX_NearSensor::~KX_NearSensor() +{ + // for nearsensor, the sensor is the 'owner' of sumoobj + // for touchsensor, it's the parent + + m_sumoScene->remove(*m_sumoObj); + + if (m_sumoObj) + delete m_sumoObj; +} + + + +bool KX_NearSensor::Evaluate(CValue* event) +{ + bool result = false; + KX_GameObject* parent = (KX_GameObject*)GetParent(); + + if (m_bTriggered != m_bLastTriggered) + { + m_bLastTriggered = m_bTriggered; + if (m_bTriggered) + { + if (m_sumoObj) + { + m_sumoObj->setMargin(m_ResetMargin); + } + } else + { + if (m_sumoObj) + { + m_sumoObj->setMargin(m_Margin); + } + + } + result = true; + } + + return result; +} + + + +void KX_NearSensor::HandleCollision(void* obj1,void* obj2,const DT_CollData * coll_data) +{ + KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr; + KX_GameObject* parent = (KX_GameObject*)GetParent(); + + // need the mapping from SM_Objects to gameobjects now + + SM_ClientObjectInfo* client_info =(SM_ClientObjectInfo*) (obj1 == m_sumoObj? + ((SM_Object*)obj2)->getClientObject() : + ((SM_Object*)obj1)->getClientObject()); + + KX_GameObject* gameobj = ( client_info ? + (KX_GameObject*)client_info->m_clientobject : + NULL); + + if (gameobj && (gameobj != parent)) + { + if (!m_colliders->SearchValue(gameobj)) + m_colliders->Add(gameobj->AddRef()); + + // only take valid colliders + if (client_info->m_type == 1) + { + if ((m_touchedpropname.Length() == 0) || + (gameobj->GetProperty(m_touchedpropname))) + { + m_bTriggered = true; + m_hitObject = gameobj; + } + } + } else + { + + } +} + + + +// python embedding +PyTypeObject KX_NearSensor::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_NearSensor", + sizeof(KX_NearSensor), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + + + +PyParentObject KX_NearSensor::Parents[] = { + &KX_NearSensor::Type, + &KX_TouchSensor::Type, + &SCA_ISensor::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + + +PyMethodDef KX_NearSensor::Methods[] = { + {"setProperty", + (PyCFunction) KX_NearSensor::sPySetProperty, METH_VARARGS, SetProperty_doc}, + {"getProperty", + (PyCFunction) KX_NearSensor::sPyGetProperty, METH_VARARGS, GetProperty_doc}, + {"getHitObject", + (PyCFunction) KX_NearSensor::sPyGetHitObject, METH_VARARGS, GetHitObject_doc}, + {"getHitObjectList", + (PyCFunction) KX_NearSensor::sPyGetHitObjectList, METH_VARARGS, GetHitObjectList_doc}, + {NULL,NULL} //Sentinel +}; + + +PyObject* +KX_NearSensor::_getattr(char* attr) +{ + _getattr_up(KX_TouchSensor); +} + +#endif //PHYSICS_NOT_YET diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h new file mode 100644 index 00000000000..c87889f1ab7 --- /dev/null +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -0,0 +1,61 @@ +/** + * Sense if other objects are near + * + * $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_NEARSENSOR_H +#define KX_NEARSENSOR_H + +#include "KX_TouchSensor.h" +class KX_Scene; + +class KX_NearSensor : public KX_TouchSensor +{ + Py_Header; + double m_Margin; + double m_ResetMargin; + KX_Scene* m_scene; + +public: + KX_NearSensor(class SCA_EventManager* eventmgr,class KX_GameObject* gameobj,double margin,double resetmargin,bool bFindMaterial,const STR_String& touchedpropname,class KM_Scene* scene,PyTypeObject* T=&Type); + virtual ~KX_NearSensor(); + virtual CValue* GetReplica(); + virtual bool Evaluate(CValue* event); + + virtual void ReParent(SCA_IObject* parent); + //virtual void HandleCollision(void* obj1,void* obj2, + // const DT_CollData * coll_data); + + virtual PyObject* _getattr(char *attr); + +}; +#endif //KX_NEARSENSOR_H diff --git a/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp b/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp new file mode 100644 index 00000000000..d4bb714d75d --- /dev/null +++ b/source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp @@ -0,0 +1,107 @@ +/** + * $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_ObColorIpoSGController.h" + +#include "KX_ScalarInterpolator.h" +#include "KX_GameObject.h" + + +bool KX_ObColorIpoSGController::Update(double currentTime) +{ + if (m_modified) + { + m_rgba[0]=0; + m_rgba[1]=0; + m_rgba[2]=0; + m_rgba[3]=0; + + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + (*i)->Execute(m_ipotime); + } + + + SG_Spatial* ob = (SG_Spatial*)m_pObject; + KX_GameObject* kxgameobj= (KX_GameObject*) ob->GetSGClientObject(); + + kxgameobj->SetObjectColor(m_rgba); + + + m_modified=false; + } + return false; +} + + +void KX_ObColorIpoSGController::AddInterpolator(KX_IInterpolator* interp) +{ + this->m_interpolators.push_back(interp); +} + +SG_Controller* KX_ObColorIpoSGController::GetReplica(class SG_Node* destnode) +{ + KX_ObColorIpoSGController* iporeplica = new KX_ObColorIpoSGController(*this); + // clear object that ipo acts on + iporeplica->ClearObject(); + + // dirty hack, ask Gino for a better solution in the ipo implementation + // hacken en zagen, in what we call datahiding, not written for replication :( + + T_InterpolatorList oldlist = m_interpolators; + iporeplica->m_interpolators.clear(); + + T_InterpolatorList::iterator i; + for (i = oldlist.begin(); !(i == oldlist.end()); ++i) { + KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i)); + iporeplica->AddInterpolator(copyipo); + + MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget(); + int orgbase = (int)this; + int orgloc = (int)scaal; + int offset = orgloc-orgbase; + int newaddrbase = (int)iporeplica + offset; + MT_Scalar* blaptr = (MT_Scalar*) newaddrbase; + copyipo->SetNewTarget((MT_Scalar*)blaptr); + } + + return iporeplica; +} + +KX_ObColorIpoSGController::~KX_ObColorIpoSGController() +{ + + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + delete (*i); + } + +} diff --git a/source/gameengine/Ketsji/KX_ObColorIpoSGController.h b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h new file mode 100644 index 00000000000..df4d8d3bb4f --- /dev/null +++ b/source/gameengine/Ketsji/KX_ObColorIpoSGController.h @@ -0,0 +1,77 @@ +/** + * $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_OBCOLORIPOSGCONTROLLER_H +#define KX_OBCOLORIPOSGCONTROLLER_H + +#include "SG_Controller.h" +#include "SG_Spatial.h" + +#include "KX_IInterpolator.h" + + +class KX_ObColorIpoSGController : public SG_Controller +{ +public: + MT_Vector4 m_rgba; + + +private: + T_InterpolatorList m_interpolators; + bool m_modified; + + double m_ipotime; +public: + KX_ObColorIpoSGController() : m_ipotime(0.0), + + m_modified(true) + {} + virtual ~KX_ObColorIpoSGController(); + virtual SG_Controller* GetReplica(class SG_Node* destnode); + virtual bool Update(double time); + virtual void SetSimulatedTime(double time) { + m_ipotime = time; + m_modified = true; + } + + void + SetOption( + int option, + int value + ){ + // intentionally empty + }; + + + void AddInterpolator(KX_IInterpolator* interp); +}; + +#endif // KX_OBCOLORIPOSGCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp new file mode 100644 index 00000000000..97e167385dc --- /dev/null +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -0,0 +1,400 @@ +/** + * Do translation/rotation actions + * + * $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_ObjectActuator.h" +#include "KX_GameObject.h" +#include "KX_IPhysicsController.h" + + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + + +KX_ObjectActuator:: +KX_ObjectActuator( + SCA_IObject* gameobj, + const MT_Vector3& force, + const MT_Vector3& torque, + const MT_Vector3& dloc, + const MT_Vector3& drot, + const MT_Vector3& linV, + const MT_Vector3& angV, + const KX_LocalFlags& flag, + PyTypeObject* T +) : + SCA_IActuator(gameobj,T), + m_force(force), + m_torque(torque), + m_dloc(dloc), + m_drot(drot), + m_linear_velocity(linV), + m_angular_velocity(angV), + m_active_combined_velocity (false), + m_bitLocalFlag (flag) +{ +} + +bool KX_ObjectActuator::Update(double curtime,double deltatime) +{ + + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + KX_GameObject *parent = static_cast<KX_GameObject *>(GetParent()); + + if (bNegativeEvent) { + // If we previously set the linear velocity we now have to inform + // the physics controller that we no longer wish to apply it and that + // it should reconcile the externally set velocity with it's + // own velocity. + if (m_active_combined_velocity) { + //if (parent->GetSumoObject()) { + //parent->GetPhysicsController()->ResolveCombinedVelocities( + // m_linear_velocity, + // m_angular_velocity, + // (m_bitLocalFlag.LinearVelocity) != 0, + // (m_bitLocalFlag.AngularVelocity) != 0 + //); + m_active_combined_velocity = false; + //} + return false; + } else { + return false; + } + + } else + if (parent) + { + /* Probably better to use some flags, so these MT_zero tests can be */ + /* skipped. */ + if (!MT_fuzzyZero(m_force)) + { + parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0); + } + if (!MT_fuzzyZero(m_torque)) + { + parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0); + } + if (!MT_fuzzyZero(m_dloc)) + { + parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0); + } + if (!MT_fuzzyZero(m_drot)) + { + parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0); + } + if (!MT_fuzzyZero(m_linear_velocity)) + { + if (m_bitLocalFlag.AddOrSetLinV) { + parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0); + } else { + m_active_combined_velocity = true; + parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0); + } + } + if (!MT_fuzzyZero(m_angular_velocity)) + { + parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0); + m_active_combined_velocity = true; + } + + } + return true; +} + + + +CValue* KX_ObjectActuator::GetReplica() +{ + KX_ObjectActuator* replica = new KX_ObjectActuator(*this);//m_float,GetName()); + replica->ProcessReplica(); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +} + + + +/* some 'standard' utilities... */ +bool KX_ObjectActuator::isValid(KX_ObjectActuator::KX_OBJECT_ACT_VEC_TYPE type) +{ + bool res = false; + res = (type > KX_OBJECT_ACT_NODEF) && (type < KX_OBJECT_ACT_MAX); + return res; +} + + + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_ObjectActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_ObjectActuator", + sizeof(KX_ObjectActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_ObjectActuator::Parents[] = { + &KX_ObjectActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_ObjectActuator::Methods[] = { + {"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_VARARGS}, + {"setForce", (PyCFunction) KX_ObjectActuator::sPySetForce, METH_VARARGS}, + {"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_VARARGS}, + {"setTorque", (PyCFunction) KX_ObjectActuator::sPySetTorque, METH_VARARGS}, + {"getDLoc", (PyCFunction) KX_ObjectActuator::sPyGetDLoc, METH_VARARGS}, + {"setDLoc", (PyCFunction) KX_ObjectActuator::sPySetDLoc, METH_VARARGS}, + {"getDRot", (PyCFunction) KX_ObjectActuator::sPyGetDRot, METH_VARARGS}, + {"setDRot", (PyCFunction) KX_ObjectActuator::sPySetDRot, METH_VARARGS}, + {"getLinearVelocity", (PyCFunction) KX_ObjectActuator::sPyGetLinearVelocity, METH_VARARGS}, + {"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS}, + {"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_VARARGS}, + {"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS}, + + + {NULL,NULL} //Sentinel +}; + +PyObject* KX_ObjectActuator::_getattr(char* attr) { + _getattr_up(SCA_IActuator); +}; + +/* 1. set ------------------------------------------------------------------ */ +/* Removed! */ + +/* 2. getForce */ +PyObject* KX_ObjectActuator::PyGetForce(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + PyObject *retVal = PyList_New(4); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_force[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_force[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_force[2])); + PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Force)); + + return retVal; +} +/* 3. setForce */ +PyObject* KX_ObjectActuator::PySetForce(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + float vecArg[3]; + int bToggle = 0; + if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], + &vecArg[2], &bToggle)) { + return NULL; + } + m_force.setValue(vecArg); + m_bitLocalFlag.Force = PyArgToBool(bToggle); + Py_Return; +} + +/* 4. getTorque */ +PyObject* KX_ObjectActuator::PyGetTorque(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + PyObject *retVal = PyList_New(4); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2])); + PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.Torque)); + + return retVal; +} +/* 5. setTorque */ +PyObject* KX_ObjectActuator::PySetTorque(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + float vecArg[3]; + int bToggle = 0; + if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], + &vecArg[2], &bToggle)) { + return NULL; + } + m_torque.setValue(vecArg); + m_bitLocalFlag.Torque = PyArgToBool(bToggle); + Py_Return; +} + +/* 6. getDLoc */ +PyObject* KX_ObjectActuator::PyGetDLoc(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + PyObject *retVal = PyList_New(4); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_dloc[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_dloc[2])); + PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DLoc)); + + return retVal; +} +/* 7. setDLoc */ +PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + float vecArg[3]; + int bToggle = 0; + if(!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], + &vecArg[2], &bToggle)) { + return NULL; + } + m_dloc.setValue(vecArg); + m_bitLocalFlag.DLoc = PyArgToBool(bToggle); + Py_Return; +} + +/* 8. getDRot */ +PyObject* KX_ObjectActuator::PyGetDRot(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + PyObject *retVal = PyList_New(4); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_drot[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_drot[2])); + PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.DRot)); + + return retVal; +} +/* 9. setDRot */ +PyObject* KX_ObjectActuator::PySetDRot(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + float vecArg[3]; + int bToggle = 0; + if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], + &vecArg[2], &bToggle)) { + return NULL; + } + m_drot.setValue(vecArg); + m_bitLocalFlag.DRot = PyArgToBool(bToggle); + Py_Return; +} + +/* 10. getLinearVelocity */ +PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *retVal = PyList_New(4); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2])); + PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity)); + + return retVal; +} + +/* 11. setLinearVelocity */ +PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) { + float vecArg[3]; + int bToggle = 0; + if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], + &vecArg[2], &bToggle)) { + return NULL; + } + m_linear_velocity.setValue(vecArg); + m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle); + Py_Return; +} + + +/* 12. getAngularVelocity */ +PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *retVal = PyList_New(4); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2])); + PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity)); + + return retVal; +} +/* 13. setAngularVelocity */ +PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) { + float vecArg[3]; + int bToggle = 0; + if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1], + &vecArg[2], &bToggle)) { + return NULL; + } + m_angular_velocity.setValue(vecArg); + m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle); + Py_Return; +} + + + + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h new file mode 100644 index 00000000000..d7d780d1f3c --- /dev/null +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -0,0 +1,140 @@ +/** + * Do translation/rotation actions + * + * $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_OBJECTACTUATOR +#define __KX_OBJECTACTUATOR + +#include "SCA_IActuator.h" +#include "MT_Vector3.h" + + +// +// Bitfield that stores the flags for each CValue derived class +// +struct KX_LocalFlags { + KX_LocalFlags() : + Force(false), + Torque(false), + DRot(false), + DLoc(false), + LinearVelocity(false), + AngularVelocity(false), + AddOrSetLinV(false) + { + } + + unsigned short Force : 1; + unsigned short Torque : 1; + unsigned short DRot : 1; + unsigned short DLoc : 1; + unsigned short LinearVelocity : 1; + unsigned short AngularVelocity : 1; + unsigned short AddOrSetLinV : 1; +}; + +class KX_ObjectActuator : public SCA_IActuator +{ + Py_Header; + + MT_Vector3 m_force; + MT_Vector3 m_torque; + MT_Vector3 m_dloc; + MT_Vector3 m_drot; + MT_Vector3 m_linear_velocity; + MT_Vector3 m_angular_velocity; + KX_LocalFlags m_bitLocalFlag; + + // A hack bool -- oh no sorry everyone + // This bool is used to check if we have informed + // the physics object that we are no longer + // setting linear velocity. + + bool m_active_combined_velocity; + +public: + enum KX_OBJECT_ACT_VEC_TYPE { + KX_OBJECT_ACT_NODEF = 0, + KX_OBJECT_ACT_FORCE, + KX_OBJECT_ACT_TORQUE, + KX_OBJECT_ACT_DLOC, + KX_OBJECT_ACT_DROT, + KX_OBJECT_ACT_LINEAR_VELOCITY, + KX_OBJECT_ACT_ANGULAR_VELOCITY, + KX_OBJECT_ACT_MAX + }; + + /** + * Check whether this is a valid vector mode + */ + bool isValid(KX_OBJECT_ACT_VEC_TYPE type); + + KX_ObjectActuator( + SCA_IObject* gameobj, + const MT_Vector3& force, + const MT_Vector3& torque, + const MT_Vector3& dloc, + const MT_Vector3& drot, + const MT_Vector3& linV, + const MT_Vector3& angV, + const KX_LocalFlags& flag, + PyTypeObject* T=&Type + ); + + CValue* GetReplica(); + + void SetForceLoc(const double force[3]) { /*m_force=force;*/ } + bool Update(double curtime,double deltatime); + + + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + + KX_PYMETHOD(KX_ObjectActuator,GetForce); + KX_PYMETHOD(KX_ObjectActuator,SetForce); + KX_PYMETHOD(KX_ObjectActuator,GetTorque); + KX_PYMETHOD(KX_ObjectActuator,SetTorque); + KX_PYMETHOD(KX_ObjectActuator,GetDLoc); + KX_PYMETHOD(KX_ObjectActuator,SetDLoc); + KX_PYMETHOD(KX_ObjectActuator,GetDRot); + KX_PYMETHOD(KX_ObjectActuator,SetDRot); + KX_PYMETHOD(KX_ObjectActuator,GetLinearVelocity); + KX_PYMETHOD(KX_ObjectActuator,SetLinearVelocity); + KX_PYMETHOD(KX_ObjectActuator,GetAngularVelocity); + KX_PYMETHOD(KX_ObjectActuator,SetAngularVelocity); +}; +#endif //__KX_OBJECTACTUATOR diff --git a/source/gameengine/Ketsji/KX_OrientationInterpolator.cpp b/source/gameengine/Ketsji/KX_OrientationInterpolator.cpp new file mode 100644 index 00000000000..bead946ab37 --- /dev/null +++ b/source/gameengine/Ketsji/KX_OrientationInterpolator.cpp @@ -0,0 +1,56 @@ +/** + * $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_OrientationInterpolator.h" + + +#include "MT_Matrix3x3.h" +#include "KX_IScalarInterpolator.h" + +void KX_OrientationInterpolator::Execute(float currentTime) const { + MT_Vector3 eul(m_ipos[0]->GetValue(currentTime), + m_ipos[1]->GetValue(currentTime), + m_ipos[2]->GetValue(currentTime)); + MT_Scalar ci = cos(eul[0]); + MT_Scalar cj = cos(eul[1]); + MT_Scalar ch = cos(eul[2]); + MT_Scalar si = sin(eul[0]); + MT_Scalar sj = sin(eul[1]); + MT_Scalar sh = sin(eul[2]); + MT_Scalar cc = ci*ch; + MT_Scalar cs = ci*sh; + MT_Scalar sc = si*ch; + MT_Scalar ss = si*sh; + + m_target.setValue(cj*ch, sj*sc-cs, sj*cc+ss, + cj*sh, sj*ss+cc, sj*cs-sc, + -sj, cj*si, cj*ci); +} diff --git a/source/gameengine/Ketsji/KX_OrientationInterpolator.h b/source/gameengine/Ketsji/KX_OrientationInterpolator.h new file mode 100644 index 00000000000..9e65e72b125 --- /dev/null +++ b/source/gameengine/Ketsji/KX_OrientationInterpolator.h @@ -0,0 +1,58 @@ +/** + * $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_ORIENTATIONINTERPOLATOR +#define KX_ORIENTATIONINTERPOLATOR + +#include "KX_IInterpolator.h" + +class MT_Matrix3x3; +class KX_IScalarInterpolator; + +class KX_OrientationInterpolator : public KX_IInterpolator { +public: + KX_OrientationInterpolator(MT_Matrix3x3& target, + KX_IScalarInterpolator **ipos) + : m_target(target) + { + m_ipos[0] = ipos[0]; + m_ipos[1] = ipos[1]; + m_ipos[2] = ipos[2]; + } + + virtual void Execute(float currentTime) const; + +private: + MT_Matrix3x3& m_target; + KX_IScalarInterpolator *m_ipos[3]; +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h new file mode 100644 index 00000000000..c9dd613da00 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PhysicsEngineEnums.h @@ -0,0 +1,44 @@ +/** + * $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_PHYSICSENGINEENUMS +#define __KX_PHYSICSENGINEENUMS + +enum e_PhysicsEngine +{ + UseNone=1, + UseSumo, + UseODE, + UseDynamo, + NoSelection +}; + +#endif //__KX_PHYSICSENGINEENUMS diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp new file mode 100644 index 00000000000..b14afbdc678 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp @@ -0,0 +1,161 @@ +/** + * $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 <Python.h> +#include "KX_PhysicsObjectWrapper.h" +#include "PHY_IPhysicsEnvironment.h" +#include "PHY_IPhysicsController.h" + +KX_PhysicsObjectWrapper::KX_PhysicsObjectWrapper( + PHY_IPhysicsController* ctrl, + PHY_IPhysicsEnvironment* physenv,PyTypeObject *T) +: m_ctrl(ctrl),m_physenv(physenv),PyObjectPlus(T) +{ +} + +KX_PhysicsObjectWrapper::~KX_PhysicsObjectWrapper() +{ +} + + +PyObject* KX_PhysicsObjectWrapper::PySetPosition(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + float x,y,z; + if (PyArg_ParseTuple(args,"fff",&x,&y,&z)) + { + m_ctrl->setPosition(x,y,z); + } + Py_INCREF(Py_None); return Py_None; +} + + +PyObject* KX_PhysicsObjectWrapper::PySetLinearVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + float x,y,z; + int local; + if (PyArg_ParseTuple(args,"fffi",&x,&y,&z,&local)) + { + m_ctrl->SetLinearVelocity(x,y,z,local != 0); + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject* KX_PhysicsObjectWrapper::PySetAngularVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + float x,y,z; + int local; + if (PyArg_ParseTuple(args,"fffi",&x,&y,&z,&local)) + { + m_ctrl->SetAngularVelocity(x,y,z,local != 0); + } + Py_INCREF(Py_None); return Py_None; +} + +PyObject* KX_PhysicsObjectWrapper::PySetActive(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int active; + if (PyArg_ParseTuple(args,"i",&active)) + { + m_ctrl->SetActive(active!=0); + } + Py_INCREF(Py_None); return Py_None; +} + + + + +//python specific stuff +PyTypeObject KX_PhysicsObjectWrapper::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_PhysicsObjectWrapper", + sizeof(KX_PhysicsObjectWrapper), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_PhysicsObjectWrapper::Parents[] = { + &KX_PhysicsObjectWrapper::Type, + NULL +}; + +PyObject* KX_PhysicsObjectWrapper::_getattr(char* attr) +{ + _getattr_up(PyObjectPlus); +} + + +int KX_PhysicsObjectWrapper::_setattr(char* attr,PyObject* pyobj) +{ + + PyTypeObject* type = pyobj->ob_type; + int result = 1; + + + if (type == &PyInt_Type) + { + result = 0; + } + if (type == &PyString_Type) + { + result = 0; + } + if (result) + result = PyObjectPlus::_setattr(attr,pyobj); + return result; +}; + + +PyMethodDef KX_PhysicsObjectWrapper::Methods[] = { + {"setPosition",(PyCFunction) KX_PhysicsObjectWrapper::sPySetPosition, METH_VARARGS}, + {"setLinearVelocity",(PyCFunction) KX_PhysicsObjectWrapper::sPySetLinearVelocity, METH_VARARGS}, + {"setAngularVelocity",(PyCFunction) KX_PhysicsObjectWrapper::sPySetAngularVelocity, METH_VARARGS}, + {"setActive",(PyCFunction) KX_PhysicsObjectWrapper::sPySetActive, METH_VARARGS}, + {NULL,NULL} //Sentinel +}; diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h new file mode 100644 index 00000000000..de384cb5932 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h @@ -0,0 +1,58 @@ +/** + * $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 PHYP_PHYSICSOBJECT_WRAPPER +#define PHYP_PHYSICSOBJECT_WRAPPER + +#include "Value.h" +#include "PHY_DynamicTypes.h" + +class KX_PhysicsObjectWrapper : public PyObjectPlus +{ + Py_Header; + + PyObject* _getattr(char* attr); + virtual int _setattr(char *attr, PyObject *value); +public: + KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type); + virtual ~KX_PhysicsObjectWrapper(); + + KX_PYMETHOD(KX_PhysicsObjectWrapper , SetPosition); + KX_PYMETHOD(KX_PhysicsObjectWrapper,SetLinearVelocity); + KX_PYMETHOD(KX_PhysicsObjectWrapper,SetAngularVelocity); + KX_PYMETHOD(KX_PhysicsObjectWrapper,SetActive); + +private: + class PHY_IPhysicsController* m_ctrl; + PHY_IPhysicsEnvironment* m_physenv; +}; + +#endif //PHYP_PHYSICSOBJECT_WRAPPER diff --git a/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h b/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h new file mode 100644 index 00000000000..84a9133d471 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PhysicsPropertiesobsolete.h @@ -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 ***** + */ +#ifndef KX_PROPSH +#define KX_PROPSH + +#include <MT_Scalar.h> + +// Properties of dynamic objects +struct KX_ShapeProps { + MT_Scalar m_mass; // Total mass + MT_Scalar m_inertia; // Inertia, should be a tensor some time + MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum + MT_Scalar m_ang_drag; // Angular drag + MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1] + bool m_do_anisotropic; // Should I do anisotropic friction? + bool m_do_fh; // Should the object have a linear Fh spring? + bool m_do_rot_fh; // Should the object have an angular Fh spring? +}; + + +// Properties of collidable objects (non-ghost objects) +struct KX_MaterialProps { + MT_Scalar m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic + MT_Scalar m_friction; // Coulomb friction (= ratio between the normal en maximum friction force) + MT_Scalar m_fh_spring; // Spring constant (both linear and angular) + MT_Scalar m_fh_damping; // Damping factor (linear and angular) in range [0, 1] + MT_Scalar m_fh_distance; // The range above the surface where Fh is active. + bool m_fh_normal; // Should the object slide off slopes? +}; + +#endif //KX_PROPSH diff --git a/source/gameengine/Ketsji/KX_PositionInterpolator.cpp b/source/gameengine/Ketsji/KX_PositionInterpolator.cpp new file mode 100644 index 00000000000..96af6e3ccf3 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PositionInterpolator.cpp @@ -0,0 +1,42 @@ +/** + * $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_PositionInterpolator.h" + + +#include "MT_Point3.h" +#include "KX_IScalarInterpolator.h" + +void KX_PositionInterpolator::Execute(float currentTime) const { + m_target.setValue(m_ipos[0]->GetValue(currentTime), + m_ipos[1]->GetValue(currentTime), + m_ipos[2]->GetValue(currentTime)); +} diff --git a/source/gameengine/Ketsji/KX_PositionInterpolator.h b/source/gameengine/Ketsji/KX_PositionInterpolator.h new file mode 100644 index 00000000000..cdc8192528a --- /dev/null +++ b/source/gameengine/Ketsji/KX_PositionInterpolator.h @@ -0,0 +1,58 @@ +/** + * $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_POSITIONINTERPOLATOR +#define KX_POSITIONINTERPOLATOR + +#include "KX_IInterpolator.h" + +class MT_Point3; +class KX_IScalarInterpolator; + +class KX_PositionInterpolator : public KX_IInterpolator { +public: + KX_PositionInterpolator(MT_Point3& target, + KX_IScalarInterpolator *ipos[]) : + m_target(target) + { + m_ipos[0] = ipos[0]; + m_ipos[1] = ipos[1]; + m_ipos[2] = ipos[2]; + } + + virtual void Execute(float currentTime) const; + +private: + MT_Point3& m_target; + KX_IScalarInterpolator *m_ipos[3]; +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp new file mode 100644 index 00000000000..67a40639a13 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -0,0 +1,193 @@ +/** + * $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_PyConstraintBinding.h" +#include "PHY_IPhysicsEnvironment.h" +#include "KX_ConstraintWrapper.h" +#include "KX_PhysicsObjectWrapper.h" +#include "PHY_IPhysicsController.h" + + +// nasty glob variable to connect scripting language +// if there is a better way (without global), please do so! +static PHY_IPhysicsEnvironment* g_physics_env = NULL; + +static char PhysicsConstraints_module_documentation[] = +"This is the Python API for the Physics Constraints"; + + +static char gPySetGravity__doc__[] = "setGravity(float x,float y,float z)"; +static char gPyCreateConstraint__doc__[] = "createConstraint(ob1,ob2,float restLength,float restitution,float damping)"; +static char gPyRemoveConstraint__doc__[] = "removeConstraint(constraint id)"; + +static PyObject* gPySetGravity(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + float x,y,z; + int len = PyTuple_Size(args); + if ((len == 3) && PyArg_ParseTuple(args,"fff",&x,&y,&z)) + { + if (g_physics_env) + g_physics_env->setGravity(x,y,z); + } + Py_INCREF(Py_None); return Py_None; +} + + + + +static PyObject* gPyCreateConstraint(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int physicsid=0,physicsid2 = 0,constrainttype=0,extrainfo=0; + int len = PyTuple_Size(args); + int success = 1; + float pivotX=1,pivotY=1,pivotZ=1,axisX=0,axisY=0,axisZ=1; + if (len == 3) + { + success = PyArg_ParseTuple(args,"iii",&physicsid,&physicsid2,&constrainttype); + } + else + if (len ==6) + { + success = PyArg_ParseTuple(args,"iiifff",&physicsid,&physicsid2,&constrainttype, + &pivotX,&pivotY,&pivotZ); + } + else if (len == 9) + { + success = PyArg_ParseTuple(args,"iiiffffff",&physicsid,&physicsid2,&constrainttype, + &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ); + } + else if (len==4) + { + success = PyArg_ParseTuple(args,"iiii",&physicsid,&physicsid2,&constrainttype,&extrainfo); + pivotX=extrainfo; + } + + if (success) + { + if (g_physics_env) + { + + PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) physicsid; + PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2; + if (physctrl) //TODO:check for existance of this pointer! + { + int constraintid = g_physics_env->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ); + + KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,g_physics_env); + + + return wrap; + } + + + } + } + + Py_INCREF(Py_None); return Py_None; +} + + +static PyObject* gPyRemoveConstraint(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int constraintid; + + int len = PyTuple_Size(args); + if (PyArg_ParseTuple(args,"i",&constraintid)) + { + if (g_physics_env) + { + g_physics_env->removeConstraint(constraintid); + } + } + Py_INCREF(Py_None); return Py_None; +} + + + + + +static struct PyMethodDef physicsconstraints_methods[] = { + {"setGravity",(PyCFunction) gPySetGravity, + METH_VARARGS, gPySetGravity__doc__}, + + {"createConstraint",(PyCFunction) gPyCreateConstraint, + METH_VARARGS, gPyCreateConstraint__doc__}, + {"removeConstraint",(PyCFunction) gPyRemoveConstraint, + METH_VARARGS, gPyRemoveConstraint__doc__}, + + //sentinel + { NULL, (PyCFunction) NULL, 0, NULL } +}; + + + +PyObject* initPythonConstraintBinding() +{ + + PyObject* ErrorObject; + PyObject* m; + PyObject* d; + + m = Py_InitModule4("PhysicsConstraints", physicsconstraints_methods, + PhysicsConstraints_module_documentation, + (PyObject*)NULL,PYTHON_API_VERSION); + + // Add some symbolic constants to the module + d = PyModule_GetDict(m); + ErrorObject = PyString_FromString("PhysicsConstraints.error"); + PyDict_SetItemString(d, "error", ErrorObject); + + // XXXX Add constants here + + // Check for errors + if (PyErr_Occurred()) + { + Py_FatalError("can't initialize module PhysicsConstraints"); + } + + return d; +} + + +void KX_RemovePythonConstraintBinding() +{ +} + +void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env) +{ + g_physics_env = env; +} diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.h b/source/gameengine/Ketsji/KX_PyConstraintBinding.h new file mode 100644 index 00000000000..f584649b579 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.h @@ -0,0 +1,43 @@ +/** + * $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 PHY_PYTHON_CONSTRAINTBINDING +#define PHY_PYTHON_CONSTRAINTBINDING + + +#include <Python.h> + + +PyObject* initPythonConstraintBinding(); +void PHY_RemovePythonConstraintBinding(); +void PHY_SetActiveEnvironment(class PHY_IPhysicsEnvironment* env); + +#endif //PHY_PYTHON_CONSTRAINTBINDING diff --git a/source/gameengine/Ketsji/KX_Python.h b/source/gameengine/Ketsji/KX_Python.h new file mode 100644 index 00000000000..705b01aa606 --- /dev/null +++ b/source/gameengine/Ketsji/KX_Python.h @@ -0,0 +1,38 @@ +/** + * $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_PYTHON_H +#define KX_PYTHON_H + +//#define USE_DL_EXPORT +#include "Python.h" + +#endif // KX_PYTHON_H diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp new file mode 100644 index 00000000000..7b6c3a823ca --- /dev/null +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -0,0 +1,832 @@ +/** + * $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 ***** + * Initialize Python thingies. + */ + +#ifdef WIN32 +#pragma warning (disable : 4786) +#endif //WIN32 + +#include "KX_PythonInit.h" + +#include "SCA_IInputDevice.h" +#include "SCA_PropertySensor.h" +#include "SCA_RandomActuator.h" +#include "KX_ConstraintActuator.h" +#include "KX_IpoActuator.h" +#include "RAS_IRasterizer.h" +#include "RAS_ICanvas.h" +#include "MT_Vector3.h" +#include "MT_Point3.h" +#include "ListValue.h" +#include "KX_Scene.h" +#include "SND_DeviceManager.h" + + +static void setSandbox(TPythonSecurityLevel level); + + +// 'local' copy of canvas ptr, for window height/width python scripts +static RAS_ICanvas* gp_Canvas = NULL; +static KX_Scene* gp_KetsjiScene = NULL; +static RAS_IRasterizer* gp_Rasterizer = NULL; + +/* Macro for building the keyboard translation */ +//#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(SCA_IInputDevice::KX_##name)) +#define KX_MACRO_addToDict(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(name)) +/* For the defines for types from logic bricks, we do stuff explicitly... */ +#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, PyInt_FromLong(name2)) + + +// temporarily python stuff, will be put in another place later ! +#include "KX_Python.h" +#include "SCA_PythonController.h" +// List of methods defined in the module + +static PyObject* ErrorObject; +STR_String gPyGetRandomFloat_doc="getRandomFloat returns a random floating point value in the range [0..1)"; + +static PyObject* gPyGetRandomFloat(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return PyFloat_FromDouble(MT_random()); +} + + + +MT_Point3 GlobalConvertPythonPylist(PyObject* pylist) +{ + bool error=false; + MT_Point3 pos; + if (pylist->ob_type == &CListValue::Type) + { + CListValue* listval = (CListValue*) pylist; + if (listval->GetCount() == 3) + { + int index; + for (index=0;index<3;index++) + { + pos[index] = listval->GetValue(index)->GetNumber(); + } + } else + { + error = true; + } + + } else + { + + // assert the list is long enough... + int numitems = PyList_Size(pylist); + if (numitems == 3) + { + int index; + for (index=0;index<3;index++) + { + pos[index] = PyFloat_AsDouble(PyList_GetItem(pylist,index)); + } + } + else + { + error = true; + } + + } + return pos; +} + + + +MT_Point3 GlobalConvertPythonVectorArg(PyObject* args) +{ + MT_Point3 pos(0,0,0); + PyObject* pylist; + PyArg_ParseTuple(args,"O",&pylist); + + pos = GlobalConvertPythonPylist(pylist); + + return pos; +} + + + +static PyObject* gPySetGravity(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + MT_Vector3 vec = GlobalConvertPythonVectorArg(args); + + if (gp_KetsjiScene) + gp_KetsjiScene->SetGravity(vec); + + Py_Return; +} + + +static bool usedsp = false; + +// this gets a pointer to an array filled with floats +static PyObject* gPyGetSpectrum(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance(); + + PyObject* resultlist = PyList_New(512); + + if (audiodevice) + { + if (!usedsp) + { + audiodevice->StartUsingDSP(); + usedsp = true; + } + + float* spectrum = audiodevice->GetSpectrum(); + + for (int index = 0; index < 512; index++) + { + PyList_SetItem(resultlist, index, PyFloat_FromDouble(spectrum[index])); + } + } + + return resultlist; +} + + + +static void gPyStartDSP(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance(); + + if (audiodevice) + { + if (!usedsp) + { + audiodevice->StartUsingDSP(); + usedsp = true; + } + } +} + + + +static void gPyStopDSP(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance(); + + if (audiodevice) + { + if (usedsp) + { + audiodevice->StopUsingDSP(); + usedsp = false; + } + } +} + + + +static struct PyMethodDef game_methods[] = { + {"getCurrentController", + (PyCFunction) SCA_PythonController::sPyGetCurrentController, + METH_VARARGS, SCA_PythonController::sPyGetCurrentController__doc__}, + {"addActiveActuator",(PyCFunction) SCA_PythonController::sPyAddActiveActuator, + METH_VARARGS, SCA_PythonController::sPyAddActiveActuator__doc__}, + {"getRandomFloat",(PyCFunction) gPyGetRandomFloat, + METH_VARARGS,gPyGetRandomFloat_doc.Ptr()}, + {"setGravity",(PyCFunction) gPySetGravity, METH_VARARGS,"set Gravitation"}, + {"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_VARARGS,"get audio spectrum"}, + {"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS,"stop using the audio dsp (for performance reasons)"}, + {NULL, (PyCFunction) NULL, 0, NULL } +}; + + +static PyObject* gPyGetWindowHeight(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int height = (gp_Canvas ? gp_Canvas->GetHeight() : 0); + + PyObject* heightval = PyInt_FromLong(height); + return heightval; +} + + + +static PyObject* gPyGetWindowWidth(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + + int width = (gp_Canvas ? gp_Canvas->GetWidth() : 0); + + PyObject* widthval = PyInt_FromLong(width); + return widthval; +} + + + +// temporarility visibility thing, will be moved to rasterizer/renderer later +bool gUseVisibilityTemp = false; + +static PyObject* gPyEnableVisibility(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int visible; + if (PyArg_ParseTuple(args,"i",&visible)) + { + gUseVisibilityTemp = (visible != 0); + } + else + { + Py_Return; + } + Py_Return; +} + + + +static PyObject* gPyShowMouse(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int visible; + if (PyArg_ParseTuple(args,"i",&visible)) + { + if (visible) + { + if (gp_Canvas) + gp_Canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL); + } else + { + if (gp_Canvas) + gp_Canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE); + } + } + + Py_Return; +} + + + +static PyObject* gPySetMousePosition(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int x,y; + if (PyArg_ParseTuple(args,"ii",&x,&y)) + { + if (gp_Canvas) + gp_Canvas->SetMousePosition(x,y); + } + + Py_Return; +} + + + +static PyObject* gPySetBackgroundColor(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + MT_Vector3 vec = GlobalConvertPythonVectorArg(args); + + if (gp_Canvas) + { + gp_Rasterizer->SetBackColor(vec[0],vec[1],vec[2],0.0); + } + Py_Return; +} + + + +static PyObject* gPySetMistColor(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + MT_Vector3 vec = GlobalConvertPythonVectorArg(args); + + if (gp_Rasterizer) + { + gp_Rasterizer->SetFogColor(vec[0],vec[1],vec[2]); + } + Py_Return; +} + + + +static PyObject* gPySetMistStart(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + float miststart; + if (PyArg_ParseTuple(args,"f",&miststart)) + { + if (gp_Rasterizer) + { + gp_Rasterizer->SetFogStart(miststart); + } + } + Py_Return; +} + + + +static PyObject* gPySetMistEnd(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + float mistend; + if (PyArg_ParseTuple(args,"f",&mistend)) + { + if (gp_Rasterizer) + { + gp_Rasterizer->SetFogEnd(mistend); + } + } + Py_Return; +} + + + +static PyObject* gPyMakeScreenshot(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + char* filename; + if (PyArg_ParseTuple(args,"s",&filename)) + { + if (gp_Canvas) + { + gp_Canvas->MakeScreenShot(filename); + } + } + Py_Return; +} + + + +STR_String gPyGetWindowHeight__doc__="getWindowHeight doc"; +STR_String gPyGetWindowWidth__doc__="getWindowWidth doc"; +STR_String gPyEnableVisibility__doc__="enableVisibility doc"; +STR_String gPyMakeScreenshot__doc__="make Screenshot doc"; +STR_String gPyShowMouse__doc__="showMouse(bool visible)"; +STR_String gPySetMousePosition__doc__="setMousePosition(int x,int y)"; + +static struct PyMethodDef rasterizer_methods[] = { + {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, + METH_VARARGS, gPyGetWindowWidth__doc__.Ptr()}, + {"getWindowHeight",(PyCFunction) gPyGetWindowHeight, + METH_VARARGS, gPyGetWindowHeight__doc__.Ptr()}, + {"makeScreenshot",(PyCFunction)gPyMakeScreenshot, + METH_VARARGS, gPyMakeScreenshot__doc__.Ptr()}, + {"enableVisibility",(PyCFunction) gPyEnableVisibility, + METH_VARARGS, gPyEnableVisibility__doc__.Ptr()}, + {"showMouse",(PyCFunction) gPyShowMouse, + METH_VARARGS, gPyShowMouse__doc__.Ptr()}, + {"setMousePosition",(PyCFunction) gPySetMousePosition, + METH_VARARGS, gPySetMousePosition__doc__.Ptr()}, + {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_VARARGS,"set Background Color (rgb)"}, + {"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"}, + {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"}, + {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"}, + + { NULL, (PyCFunction) NULL, 0, NULL } +}; + + + +// Initialization function for the module (*must* be called initGameLogic) + +static char GameLogic_module_documentation[] = +"This is the Python API for the game engine of GameLogic" +; + +static char Rasterizer_module_documentation[] = +"This is the Python API for the game engine of Rasterizer" +; + + + +PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook +{ + PyObject* m; + PyObject* d; + + gp_KetsjiScene = scene; + + gUseVisibilityTemp=false; + + // Create the module and add the functions + m = Py_InitModule4("GameLogic", game_methods, + GameLogic_module_documentation, + (PyObject*)NULL,PYTHON_API_VERSION); + + // Add some symbolic constants to the module + d = PyModule_GetDict(m); + + ErrorObject = PyString_FromString("GameLogic.error"); + PyDict_SetItemString(d, "error", ErrorObject); + + // XXXX Add constants here + /* To use logic bricks, we need some sort of constants. Here, we associate */ + /* constants and sumbolic names. Add them to dictionary d. */ + + /* 1. true and false: needed for everyone */ + KX_MACRO_addTypesToDict(d, KX_TRUE, SCA_ILogicBrick::KX_TRUE); + KX_MACRO_addTypesToDict(d, KX_FALSE, SCA_ILogicBrick::KX_FALSE); + + /* 2. Property sensor */ + KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_EQUAL, SCA_PropertySensor::KX_PROPSENSOR_EQUAL); + KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_NOTEQUAL, SCA_PropertySensor::KX_PROPSENSOR_NOTEQUAL); + KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_INTERVAL, SCA_PropertySensor::KX_PROPSENSOR_INTERVAL); + KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_CHANGED, SCA_PropertySensor::KX_PROPSENSOR_CHANGED); + KX_MACRO_addTypesToDict(d, KX_PROPSENSOR_EXPRESSION, SCA_PropertySensor::KX_PROPSENSOR_EXPRESSION); + + /* 3. Constraint actuator */ + KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX); + KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY); + KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_LOCZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ); + KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX); + KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY); + KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ROTZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ); + + /* 4. Ipo actuator, simple part */ + KX_MACRO_addTypesToDict(d, KX_IPOACT_PLAY, KX_IpoActuator::KX_ACT_IPO_PLAY); + KX_MACRO_addTypesToDict(d, KX_IPOACT_PINGPONG, KX_IpoActuator::KX_ACT_IPO_PINGPONG); + KX_MACRO_addTypesToDict(d, KX_IPOACT_FLIPPER, KX_IpoActuator::KX_ACT_IPO_FLIPPER); + KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPSTOP, KX_IpoActuator::KX_ACT_IPO_LOOPSTOP); + KX_MACRO_addTypesToDict(d, KX_IPOACT_LOOPEND, KX_IpoActuator::KX_ACT_IPO_LOOPEND); + + /* 5. Random distribution types */ + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_CONST, SCA_RandomActuator::KX_RANDOMACT_BOOL_CONST); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_UNIFORM, SCA_RandomActuator::KX_RANDOMACT_BOOL_UNIFORM); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_BOOL_BERNOUILLI, SCA_RandomActuator::KX_RANDOMACT_BOOL_BERNOUILLI); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_CONST, SCA_RandomActuator::KX_RANDOMACT_INT_CONST); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_UNIFORM, SCA_RandomActuator::KX_RANDOMACT_INT_UNIFORM); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_INT_POISSON, SCA_RandomActuator::KX_RANDOMACT_INT_POISSON); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_CONST, SCA_RandomActuator::KX_RANDOMACT_FLOAT_CONST); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_UNIFORM, SCA_RandomActuator::KX_RANDOMACT_FLOAT_UNIFORM); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_NORMAL, SCA_RandomActuator::KX_RANDOMACT_FLOAT_NORMAL); + KX_MACRO_addTypesToDict(d, KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL, SCA_RandomActuator::KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL); + + // Check for errors + if (PyErr_Occurred()) + { + Py_FatalError("can't initialize module GameLogic"); + } + + return d; +} + + + +// Python Sandbox code +// override builtin functions import() and open() + + +PyObject *KXpy_open(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_RuntimeError, "Sandbox: open() function disabled!\nGame Scripts should not use this function."); + return NULL; +} + + + +PyObject *KXpy_import(PyObject *self, PyObject *args) +{ + char *name; + PyObject *globals = NULL; + PyObject *locals = NULL; + PyObject *fromlist = NULL; + PyObject *l, *m, *n; + + if (!PyArg_ParseTuple(args, "s|OOO:m_import", + &name, &globals, &locals, &fromlist)) + return NULL; + + /* check for builtin modules */ + m = PyImport_AddModule("sys"); + l = PyObject_GetAttrString(m, "builtin_module_names"); + n = PyString_FromString(name); + + if (PySequence_Contains(l, n)) { + return PyImport_ImportModuleEx(name, globals, locals, fromlist); + } + + /* quick hack for GamePython modules + TODO: register builtin modules properly by ExtendInittab */ + if (!strcmp(name, "GameLogic") || !strcmp(name, "GameKeys") || + !strcmp(name, "Rasterizer")) { + return PyImport_ImportModuleEx(name, globals, locals, fromlist); + } + + PyErr_Format(PyExc_ImportError, + "Import of external Module %.20s not allowed.", name); + return NULL; + +} + + + +static PyMethodDef meth_open[] = { + { "open", KXpy_open, METH_VARARGS, + "(disabled)"} +}; + + +static PyMethodDef meth_import[] = { + { "import", KXpy_import, METH_VARARGS, + "our own import"} +}; + + + +//static PyObject *g_oldopen = 0; +//static PyObject *g_oldimport = 0; +//static int g_security = 0; + + +void setSandbox(TPythonSecurityLevel level) +{ + PyObject *m = PyImport_AddModule("__builtin__"); + PyObject *d = PyModule_GetDict(m); + PyObject *meth = PyCFunction_New(meth_open, NULL); + + switch (level) { + case psl_Highest: + //if (!g_security) { + //g_oldopen = PyDict_GetItemString(d, "open"); + PyDict_SetItemString(d, "open", meth); + meth = PyCFunction_New(meth_import, NULL); + PyDict_SetItemString(d, "__import__", meth); + //g_security = level; + //} + break; + /* + case psl_Lowest: + if (g_security) { + PyDict_SetItemString(d, "open", g_oldopen); + PyDict_SetItemString(d, "__import__", g_oldimport); + g_security = level; + } + */ + default: + break; + } +} + + + +PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level) +{ + STR_String pname = progname; + Py_SetProgramName(pname.Ptr()); + Py_NoSiteFlag=1; + Py_FrozenFlag=1; + Py_Initialize(); + setSandbox(level); + + PyObject* moduleobj = PyImport_AddModule("__main__"); + return PyModule_GetDict(moduleobj); +} + + + +void exitGamePythonScripting() +{ + Py_Finalize(); +} + + + +PyObject* initRasterizer(RAS_IRasterizer* rasty,RAS_ICanvas* canvas) +{ + gp_Canvas = canvas; + gp_Rasterizer = rasty; + + + PyObject* m; + PyObject* d; + + // Create the module and add the functions + m = Py_InitModule4("Rasterizer", rasterizer_methods, + Rasterizer_module_documentation, + (PyObject*)NULL,PYTHON_API_VERSION); + + // Add some symbolic constants to the module + d = PyModule_GetDict(m); + ErrorObject = PyString_FromString("Rasterizer.error"); + PyDict_SetItemString(d, "error", ErrorObject); + + // XXXX Add constants here + + // Check for errors + if (PyErr_Occurred()) + { + Py_FatalError("can't initialize module Rasterizer"); + } + + return d; +} + + + +/* ------------------------------------------------------------------------- */ +/* GameKeys: symbolic constants for key mapping */ +/* ------------------------------------------------------------------------- */ + +static char GameKeys_module_documentation[] = +"This modules provides defines for key-codes" +; + + + +static struct PyMethodDef gamekeys_methods[] = { + { NULL, (PyCFunction) NULL, 0, NULL } +}; + + + +PyObject* initGameKeys() +{ + PyObject* m; + PyObject* d; + + // Create the module and add the functions + m = Py_InitModule4("GameKeys", gamekeys_methods, + GameKeys_module_documentation, + (PyObject*)NULL,PYTHON_API_VERSION); + + // Add some symbolic constants to the module + d = PyModule_GetDict(m); + + // XXXX Add constants here + + KX_MACRO_addTypesToDict(d, AKEY, SCA_IInputDevice::KX_AKEY); + KX_MACRO_addTypesToDict(d, BKEY, SCA_IInputDevice::KX_BKEY); + KX_MACRO_addTypesToDict(d, CKEY, SCA_IInputDevice::KX_CKEY); + KX_MACRO_addTypesToDict(d, DKEY, SCA_IInputDevice::KX_DKEY); + KX_MACRO_addTypesToDict(d, EKEY, SCA_IInputDevice::KX_EKEY); + KX_MACRO_addTypesToDict(d, FKEY, SCA_IInputDevice::KX_FKEY); + KX_MACRO_addTypesToDict(d, GKEY, SCA_IInputDevice::KX_GKEY); + KX_MACRO_addTypesToDict(d, HKEY, SCA_IInputDevice::KX_HKEY); + KX_MACRO_addTypesToDict(d, IKEY, SCA_IInputDevice::KX_IKEY); + KX_MACRO_addTypesToDict(d, JKEY, SCA_IInputDevice::KX_JKEY); + KX_MACRO_addTypesToDict(d, KKEY, SCA_IInputDevice::KX_KKEY); + KX_MACRO_addTypesToDict(d, LKEY, SCA_IInputDevice::KX_LKEY); + KX_MACRO_addTypesToDict(d, MKEY, SCA_IInputDevice::KX_MKEY); + KX_MACRO_addTypesToDict(d, NKEY, SCA_IInputDevice::KX_NKEY); + KX_MACRO_addTypesToDict(d, OKEY, SCA_IInputDevice::KX_OKEY); + KX_MACRO_addTypesToDict(d, PKEY, SCA_IInputDevice::KX_PKEY); + KX_MACRO_addTypesToDict(d, QKEY, SCA_IInputDevice::KX_QKEY); + KX_MACRO_addTypesToDict(d, RKEY, SCA_IInputDevice::KX_RKEY); + KX_MACRO_addTypesToDict(d, SKEY, SCA_IInputDevice::KX_SKEY); + KX_MACRO_addTypesToDict(d, TKEY, SCA_IInputDevice::KX_TKEY); + KX_MACRO_addTypesToDict(d, UKEY, SCA_IInputDevice::KX_UKEY); + KX_MACRO_addTypesToDict(d, VKEY, SCA_IInputDevice::KX_VKEY); + KX_MACRO_addTypesToDict(d, WKEY, SCA_IInputDevice::KX_WKEY); + KX_MACRO_addTypesToDict(d, XKEY, SCA_IInputDevice::KX_XKEY); + KX_MACRO_addTypesToDict(d, YKEY, SCA_IInputDevice::KX_YKEY); + KX_MACRO_addTypesToDict(d, ZKEY, SCA_IInputDevice::KX_ZKEY); + + KX_MACRO_addTypesToDict(d, ZEROKEY, SCA_IInputDevice::KX_ZEROKEY); + KX_MACRO_addTypesToDict(d, ONEKEY, SCA_IInputDevice::KX_ONEKEY); + KX_MACRO_addTypesToDict(d, TWOKEY, SCA_IInputDevice::KX_TWOKEY); + KX_MACRO_addTypesToDict(d, THREEKEY, SCA_IInputDevice::KX_THREEKEY); + KX_MACRO_addTypesToDict(d, FOURKEY, SCA_IInputDevice::KX_FOURKEY); + KX_MACRO_addTypesToDict(d, FIVEKEY, SCA_IInputDevice::KX_FIVEKEY); + KX_MACRO_addTypesToDict(d, SIXKEY, SCA_IInputDevice::KX_SIXKEY); + KX_MACRO_addTypesToDict(d, SEVENKEY, SCA_IInputDevice::KX_SEVENKEY); + KX_MACRO_addTypesToDict(d, EIGHTKEY, SCA_IInputDevice::KX_EIGHTKEY); + KX_MACRO_addTypesToDict(d, NINEKEY, SCA_IInputDevice::KX_NINEKEY); + + KX_MACRO_addTypesToDict(d, CAPSLOCKKEY, SCA_IInputDevice::KX_CAPSLOCKKEY); + + KX_MACRO_addTypesToDict(d, LEFTCTRLKEY, SCA_IInputDevice::KX_LEFTCTRLKEY); + KX_MACRO_addTypesToDict(d, LEFTALTKEY, SCA_IInputDevice::KX_LEFTALTKEY); + KX_MACRO_addTypesToDict(d, RIGHTALTKEY, SCA_IInputDevice::KX_RIGHTALTKEY); + KX_MACRO_addTypesToDict(d, RIGHTCTRLKEY, SCA_IInputDevice::KX_RIGHTCTRLKEY); + KX_MACRO_addTypesToDict(d, RIGHTSHIFTKEY, SCA_IInputDevice::KX_RIGHTSHIFTKEY); + KX_MACRO_addTypesToDict(d, LEFTSHIFTKEY, SCA_IInputDevice::KX_LEFTSHIFTKEY); + + KX_MACRO_addTypesToDict(d, ESCKEY, SCA_IInputDevice::KX_ESCKEY); + KX_MACRO_addTypesToDict(d, TABKEY, SCA_IInputDevice::KX_TABKEY); + KX_MACRO_addTypesToDict(d, RETKEY, SCA_IInputDevice::KX_RETKEY); + KX_MACRO_addTypesToDict(d, SPACEKEY, SCA_IInputDevice::KX_SPACEKEY); + KX_MACRO_addTypesToDict(d, LINEFEEDKEY, SCA_IInputDevice::KX_LINEFEEDKEY); + KX_MACRO_addTypesToDict(d, BACKSPACEKEY, SCA_IInputDevice::KX_BACKSPACEKEY); + KX_MACRO_addTypesToDict(d, DELKEY, SCA_IInputDevice::KX_DELKEY); + KX_MACRO_addTypesToDict(d, SEMICOLONKEY, SCA_IInputDevice::KX_SEMICOLONKEY); + KX_MACRO_addTypesToDict(d, PERIODKEY, SCA_IInputDevice::KX_PERIODKEY); + KX_MACRO_addTypesToDict(d, COMMAKEY, SCA_IInputDevice::KX_COMMAKEY); + KX_MACRO_addTypesToDict(d, QUOTEKEY, SCA_IInputDevice::KX_QUOTEKEY); + KX_MACRO_addTypesToDict(d, ACCENTGRAVEKEY, SCA_IInputDevice::KX_ACCENTGRAVEKEY); + KX_MACRO_addTypesToDict(d, MINUSKEY, SCA_IInputDevice::KX_MINUSKEY); + KX_MACRO_addTypesToDict(d, SLASHKEY, SCA_IInputDevice::KX_SLASHKEY); + KX_MACRO_addTypesToDict(d, BACKSLASHKEY, SCA_IInputDevice::KX_BACKSLASHKEY); + KX_MACRO_addTypesToDict(d, EQUALKEY, SCA_IInputDevice::KX_EQUALKEY); + KX_MACRO_addTypesToDict(d, LEFTBRACKETKEY, SCA_IInputDevice::KX_LEFTBRACKETKEY); + KX_MACRO_addTypesToDict(d, RIGHTBRACKETKEY, SCA_IInputDevice::KX_RIGHTBRACKETKEY); + + KX_MACRO_addTypesToDict(d, LEFTARROWKEY, SCA_IInputDevice::KX_LEFTARROWKEY); + KX_MACRO_addTypesToDict(d, DOWNARROWKEY, SCA_IInputDevice::KX_DOWNARROWKEY); + KX_MACRO_addTypesToDict(d, RIGHTARROWKEY, SCA_IInputDevice::KX_RIGHTARROWKEY); + KX_MACRO_addTypesToDict(d, UPARROWKEY, SCA_IInputDevice::KX_UPARROWKEY); + + KX_MACRO_addTypesToDict(d, PAD2 , SCA_IInputDevice::KX_PAD2); + KX_MACRO_addTypesToDict(d, PAD4 , SCA_IInputDevice::KX_PAD4); + KX_MACRO_addTypesToDict(d, PAD6 , SCA_IInputDevice::KX_PAD6); + KX_MACRO_addTypesToDict(d, PAD8 , SCA_IInputDevice::KX_PAD8); + + KX_MACRO_addTypesToDict(d, PAD1 , SCA_IInputDevice::KX_PAD1); + KX_MACRO_addTypesToDict(d, PAD3 , SCA_IInputDevice::KX_PAD3); + KX_MACRO_addTypesToDict(d, PAD5 , SCA_IInputDevice::KX_PAD5); + KX_MACRO_addTypesToDict(d, PAD7 , SCA_IInputDevice::KX_PAD7); + KX_MACRO_addTypesToDict(d, PAD9 , SCA_IInputDevice::KX_PAD9); + + KX_MACRO_addTypesToDict(d, PADPERIOD, SCA_IInputDevice::KX_PADPERIOD); + KX_MACRO_addTypesToDict(d, PADSLASHKEY, SCA_IInputDevice::KX_PADSLASHKEY); + KX_MACRO_addTypesToDict(d, PADASTERKEY, SCA_IInputDevice::KX_PADASTERKEY); + + + KX_MACRO_addTypesToDict(d, PAD0, SCA_IInputDevice::KX_PAD0); + KX_MACRO_addTypesToDict(d, PADMINUS, SCA_IInputDevice::KX_PADMINUS); + KX_MACRO_addTypesToDict(d, PADENTER, SCA_IInputDevice::KX_PADENTER); + KX_MACRO_addTypesToDict(d, PADPLUSKEY, SCA_IInputDevice::KX_PADPLUSKEY); + + + KX_MACRO_addTypesToDict(d, F1KEY , SCA_IInputDevice::KX_F1KEY); + KX_MACRO_addTypesToDict(d, F2KEY , SCA_IInputDevice::KX_F2KEY); + KX_MACRO_addTypesToDict(d, F3KEY , SCA_IInputDevice::KX_F3KEY); + KX_MACRO_addTypesToDict(d, F4KEY , SCA_IInputDevice::KX_F4KEY); + KX_MACRO_addTypesToDict(d, F5KEY , SCA_IInputDevice::KX_F5KEY); + KX_MACRO_addTypesToDict(d, F6KEY , SCA_IInputDevice::KX_F6KEY); + KX_MACRO_addTypesToDict(d, F7KEY , SCA_IInputDevice::KX_F7KEY); + KX_MACRO_addTypesToDict(d, F8KEY , SCA_IInputDevice::KX_F8KEY); + KX_MACRO_addTypesToDict(d, F9KEY , SCA_IInputDevice::KX_F9KEY); + KX_MACRO_addTypesToDict(d, F10KEY, SCA_IInputDevice::KX_F10KEY); + KX_MACRO_addTypesToDict(d, F11KEY, SCA_IInputDevice::KX_F11KEY); + KX_MACRO_addTypesToDict(d, F12KEY, SCA_IInputDevice::KX_F12KEY); + + KX_MACRO_addTypesToDict(d, PAUSEKEY, SCA_IInputDevice::KX_PAUSEKEY); + KX_MACRO_addTypesToDict(d, INSERTKEY, SCA_IInputDevice::KX_INSERTKEY); + KX_MACRO_addTypesToDict(d, HOMEKEY , SCA_IInputDevice::KX_HOMEKEY); + KX_MACRO_addTypesToDict(d, PAGEUPKEY, SCA_IInputDevice::KX_PAGEUPKEY); + KX_MACRO_addTypesToDict(d, PAGEDOWNKEY, SCA_IInputDevice::KX_PAGEDOWNKEY); + KX_MACRO_addTypesToDict(d, ENDKEY, SCA_IInputDevice::KX_ENDKEY); + + + // Check for errors + if (PyErr_Occurred()) + { + Py_FatalError("can't initialize module GameKeys"); + } + + return d; +} + +void PHY_SetActiveScene(class KX_Scene* scene) +{ + gp_KetsjiScene = scene; +} diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h new file mode 100644 index 00000000000..f5de003c6a6 --- /dev/null +++ b/source/gameengine/Ketsji/KX_PythonInit.h @@ -0,0 +1,55 @@ +/** + * $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_PYTHON_INIT +#define __KX_PYTHON_INIT + +#include "KX_Python.h" +#include "STR_String.h" + +typedef enum { + psl_Lowest = 0, + psl_Highest +} TPythonSecurityLevel; + +extern bool gUseVisibilityTemp; + + +PyObject* initGameLogic(class KX_Scene* ketsjiscene); +PyObject* initGameKeys(); +PyObject* initRasterizer(class RAS_IRasterizer* rasty,class RAS_ICanvas* canvas); +PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLevel level); +void exitGamePythonScripting(); +void exitGamePythonScripting(); +void PHY_SetActiveScene(class KX_Scene* scene); + + +#endif //__KX_PYTHON_INIT diff --git a/source/gameengine/Ketsji/KX_Python_dynamic.h b/source/gameengine/Ketsji/KX_Python_dynamic.h new file mode 100644 index 00000000000..705b01aa606 --- /dev/null +++ b/source/gameengine/Ketsji/KX_Python_dynamic.h @@ -0,0 +1,38 @@ +/** + * $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_PYTHON_H +#define KX_PYTHON_H + +//#define USE_DL_EXPORT +#include "Python.h" + +#endif // KX_PYTHON_H diff --git a/source/gameengine/Ketsji/KX_Python_static.h b/source/gameengine/Ketsji/KX_Python_static.h new file mode 100644 index 00000000000..d147794d8fe --- /dev/null +++ b/source/gameengine/Ketsji/KX_Python_static.h @@ -0,0 +1,38 @@ +/** + * $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_PYTHON_H +#define KX_PYTHON_H + +#define USE_DL_EXPORT +#include "Python.h" + +#endif // KX_PYTHON_H diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp new file mode 100644 index 00000000000..27142987f4f --- /dev/null +++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp @@ -0,0 +1,220 @@ +/** + * $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_RadarSensor.h" + +#include "KX_GameObject.h" +/** + * RadarSensor constructor. Creates a near-sensor derived class, with a cone collision shape. + */ + +#ifdef PHYSICS_NOT_YET + +KX_RadarSensor::KX_RadarSensor(class SCA_EventManager* eventmgr, + class KX_GameObject* gameobj, + double coneradius, + double coneheight, + int axis, + double margin, + double resetmargin, + bool bFindMaterial, + const STR_String& touchedpropname, + class KX_Scene* kxscene, + PyTypeObject* T) + + : KX_NearSensor( + eventmgr, + gameobj, + margin, + resetmargin, + bFindMaterial, + touchedpropname, + kxscene, + T), + m_coneheight(coneheight), + m_coneradius(coneradius), + m_axis(axis) +{ + m_client_info.m_type = 3; + m_client_info.m_clientobject = gameobj; + m_client_info.m_auxilary_info = NULL; + sumoObj->setClientObject(&m_client_info); +} + + +KX_RadarSensor::~KX_RadarSensor() +{ + +} + +/** + * Transforms the collision object. A cone is not correctly centered + * for usage. */ +void KX_RadarSensor::SynchronizeTransform() +{ + // Getting the parent location was commented out. Why? + MT_Transform trans; + trans.setOrigin(((KX_GameObject*)GetParent())->NodeGetWorldPosition()); + trans.setBasis(((KX_GameObject*)GetParent())->NodeGetWorldOrientation()); + // What is the default orientation? pointing in the -y direction? + // is the geometry correctly converted? + + // a collision cone is oriented + // center the cone correctly + // depends on the radar 'axis' + switch (m_axis) + { + case 0: // X Axis + { + MT_Quaternion rotquatje(MT_Vector3(0,0,1),MT_radians(90)); + trans.rotate(rotquatje); + trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0)); + break; + }; + case 1: // Y Axis + { + MT_Quaternion rotquatje(MT_Vector3(1,0,0),MT_radians(-180)); + trans.rotate(rotquatje); + trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0)); + break; + }; + case 2: // Z Axis + { + MT_Quaternion rotquatje(MT_Vector3(1,0,0),MT_radians(-90)); + trans.rotate(rotquatje); + trans.translate(MT_Vector3 (0, -m_coneheight/2.0 ,0)); + break; + }; + default: + { + } + } + m_cone_origin = trans.getOrigin(); + m_cone_target = trans(MT_Point3(0, -m_coneheight/2.0 ,0)); + + m_sumoObj->setPosition(trans.getOrigin()); + m_sumoObj->setOrientation(trans.getRotation()); + m_sumoObj->calcXform(); +} + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_RadarSensor::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_RadarSensor", + sizeof(KX_RadarSensor), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_RadarSensor::Parents[] = { + &KX_RadarSensor::Type, + &KX_NearSensor::Type, + &KX_TouchSensor::Type, + &SCA_ISensor::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_RadarSensor::Methods[] = { + {"getConeOrigin", (PyCFunction) KX_RadarSensor::sPyGetConeOrigin, + METH_VARARGS, GetConeOrigin_doc}, + {"getConeTarget", (PyCFunction) KX_RadarSensor::sPyGetConeTarget, + METH_VARARGS, GetConeTarget_doc}, + {"getConeHeight", (PyCFunction) KX_RadarSensor::sPyGetConeHeight, + METH_VARARGS, GetConeHeight_doc}, + {NULL,NULL,NULL,NULL} //Sentinel +}; + +PyObject* KX_RadarSensor::_getattr(char* attr) { + _getattr_up(KX_TouchSensor); +} + +/* getConeOrigin */ +char KX_RadarSensor::GetConeOrigin_doc[] = +"getConeOrigin()\n" +"\tReturns the origin of the cone with which to test. The origin\n" +"\tis in the middle of the cone."; +PyObject* KX_RadarSensor::PyGetConeOrigin(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *retVal = PyList_New(3); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2])); + + return retVal; +} + +/* getConeOrigin */ +char KX_RadarSensor::GetConeTarget_doc[] = +"getConeTarget()\n" +"\tReturns the center of the bottom face of the cone with which to test.\n"; +PyObject* KX_RadarSensor::PyGetConeTarget(PyObject* self, + PyObject* args, + PyObject* kwds) { + PyObject *retVal = PyList_New(3); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2])); + + return retVal; +} + +/* getConeOrigin */ +char KX_RadarSensor::GetConeHeight_doc[] = +"getConeHeight()\n" +"\tReturns the height of the cone with which to test.\n"; +PyObject* KX_RadarSensor::PyGetConeHeight(PyObject* self, + PyObject* args, + PyObject* kwds) { + return PyFloat_FromDouble(m_coneheight); +} + + +#endif //PHYSICS_NOT_YET diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h new file mode 100644 index 00000000000..3a69c6565b2 --- /dev/null +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -0,0 +1,93 @@ +/** + * $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_RADAR_SENSOR_H +#define __KX_RADAR_SENSOR_H + +#include "KX_NearSensor.h" +#include "MT_Point3.h" + +/** +* Radar 'cone' sensor. Very similar to a near-sensor, but instead of a sphere, a cone is used. +*/ +class KX_RadarSensor : public KX_NearSensor +{ + protected: + Py_Header; + + MT_Scalar m_coneradius; + + /** + * Height of the cone. + */ + MT_Scalar m_coneheight; + int m_axis; + + /** + * The previous position of the origin of the cone. + */ + MT_Point3 m_cone_origin; + + /** + * The previous direction of the cone (origin to bottom plane). + */ + MT_Point3 m_cone_target; + +public: + KX_RadarSensor(class SCA_EventManager* eventmgr, + class KX_GameObject* gameobj, + double coneradius, + double coneheight, + int axis, + double margin, + double resetmargin, + class SM_Object* sumoObj, + bool bFindMaterial, + const STR_String& touchedpropname, + class SM_Scene* sumoscene, + PyTypeObject* T=&Type); + KX_RadarSensor(); + virtual ~KX_RadarSensor(); + virtual void SynchronizeTransform(); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + + KX_PYMETHOD_DOC(KX_RadarSensor,GetConeOrigin); + KX_PYMETHOD_DOC(KX_RadarSensor,GetConeTarget); + KX_PYMETHOD_DOC(KX_RadarSensor,GetConeHeight); + +}; + +#endif //__KX_RADAR_SENSOR_H diff --git a/source/gameengine/Ketsji/KX_RayEventManager.cpp b/source/gameengine/Ketsji/KX_RayEventManager.cpp new file mode 100644 index 00000000000..d57f97efb44 --- /dev/null +++ b/source/gameengine/Ketsji/KX_RayEventManager.cpp @@ -0,0 +1,55 @@ +/** + * Manager for ray events + * + * $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_RayEventManager.h" +#include "SCA_LogicManager.h" +#include "SCA_ISensor.h" +#include <vector> +using namespace std; + +#include <iostream> +#include <stdio.h> + +void KX_RayEventManager::NextFrame(double curtime,double deltatime) +{ + for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++) + { + SCA_ISensor *sensor = *i; + sensor->Activate(m_logicmgr, NULL); + } +} + +void KX_RayEventManager::RegisterSensor(SCA_ISensor* sensor) +{ + m_sensors.push_back(sensor); +}; diff --git a/source/gameengine/Ketsji/KX_RayEventManager.h b/source/gameengine/Ketsji/KX_RayEventManager.h new file mode 100644 index 00000000000..abfbf6cb0f8 --- /dev/null +++ b/source/gameengine/Ketsji/KX_RayEventManager.h @@ -0,0 +1,52 @@ +/** + * Manager for ray events + * + * $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_RAYEVENTMGR +#define __KX_RAYEVENTMGR +#include "SCA_EventManager.h" +#include <vector> +using namespace std; +class KX_RayEventManager : public SCA_EventManager +{ + + class SCA_LogicManager* m_logicmgr; +public: + KX_RayEventManager(class SCA_LogicManager* logicmgr) + : m_logicmgr(logicmgr), + SCA_EventManager(RAY_EVENTMGR) + {} + virtual void NextFrame(double curtime,double deltatime); + virtual void RegisterSensor(SCA_ISensor* sensor); +}; +#endif //__KX_RAYEVENTMGR diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp new file mode 100644 index 00000000000..eac362a0b1c --- /dev/null +++ b/source/gameengine/Ketsji/KX_RaySensor.cpp @@ -0,0 +1,381 @@ +/** + * Cast a ray and feel for objects + * + * $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_RaySensor.h" +#include "SCA_EventManager.h" +#include "SCA_RandomEventManager.h" +#include "SCA_LogicManager.h" +#include "SCA_IObject.h" +#include "KX_ClientObjectInfo.h" +#include "KX_GameObject.h" +#include "KX_Scene.h" + + +KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr, + SCA_IObject* gameobj, + const STR_String& propname, + bool bFindMaterial, + double distance, + int axis, + KX_Scene* ketsjiScene, + PyTypeObject* T) + : SCA_ISensor(gameobj,eventmgr, T), + m_propertyname(propname), + m_bFindMaterial(bFindMaterial), + m_distance(distance), + m_axis(axis), + m_ketsjiScene(ketsjiScene), + m_rayHit(false), + m_bTriggered(false), + m_hitObject(NULL) + + +{ + +} + + + +KX_RaySensor::~KX_RaySensor() +{ + /* Nothing to be done here. */ +} + + + +CValue* KX_RaySensor::GetReplica() +{ + CValue* replica = new KX_RaySensor(*this); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +} + + + +bool KX_RaySensor::IsPositiveTrigger() +{ + bool result = m_rayHit; + + if (m_invert) + result = !result; + + return result; +} + + + +bool KX_RaySensor::Evaluate(CValue* event) +{ + bool result = false; + m_rayHit = false; + m_hitObject = NULL; + m_hitPosition = MT_Vector3(0,0,0); + m_hitNormal = MT_Vector3(1,0,0); + + KX_GameObject* obj = (KX_GameObject*)GetParent(); + MT_Point3 frompoint = obj->NodeGetWorldPosition(); + MT_Matrix3x3 matje = obj->NodeGetWorldOrientation(); + MT_Matrix3x3 invmat = matje.inverse(); + + MT_Vector3 todir; + switch (m_axis) + { + case 1: // X + { + todir[0] = invmat[0][0]; + todir[1] = invmat[0][1]; + todir[2] = invmat[0][2]; + break; + } + case 0: // Y + { + todir[0] = invmat[1][0]; + todir[1] = invmat[1][1]; + todir[2] = invmat[1][2]; + break; + } + case 2: // Z + { + todir[0] = invmat[2][0]; + todir[1] = invmat[2][1]; + todir[2] = invmat[2][2]; + break; + } + case 3: // -X + { + todir[0] = invmat[0][0] * -1; + todir[1] = invmat[0][1] * -1; + todir[2] = invmat[0][2] * -1; + break; + } + case 4: // -Y + { + todir[0] = invmat[1][0] * -1; + todir[1] = invmat[1][1] * -1; + todir[2] = invmat[1][2] * -1; + break; + } + case 5: // -Z + { + todir[0] = invmat[2][0] * -1; + todir[1] = invmat[2][1] * -1; + todir[2] = invmat[2][2] * -1; + break; + } + } + todir.normalize(); + m_rayDirection = todir; + + + + MT_Point3 topoint = frompoint + (m_distance) * todir; + MT_Point3 resultpoint; + MT_Vector3 resultnormal; + bool ready = false; + /* + do { + + + + SM_Object* hitObj = m_sumoScene->rayTest(obj->GetSumoObject(), + frompoint, + topoint, + resultpoint, + resultnormal); + if (hitObj) + { + KX_ClientObjectInfo* info = (SM_ClientObjectInfo*)hitObj->getClientObject(); + SCA_IObject* hitgameobj = (SCA_IObject*)info->m_clientobject; + bool bFound = false; + + if (hitgameobj == obj) + { + // false hit + MT_Scalar marg = obj->GetSumoObject()->getMargin() ; + frompoint = resultpoint + marg * todir; + } + else + { + ready = true; + if (m_propertyname.Length() == 0) + { + bFound = true; + } + else + { + if (m_bFindMaterial) + { + if (info->m_auxilary_info) + { + bFound = (m_propertyname== ((char*)info->m_auxilary_info)); + } + } + else + { + if (hitgameobj->GetProperty(m_propertyname) != NULL) + { + bFound = true; + } + } + } + + if (bFound) + { + m_rayHit = true; + m_hitObject = hitgameobj; + m_hitPosition = resultpoint; + m_hitNormal = resultnormal; + + } + } + } + else + { + ready = true; + } + } + while (!ready); + */ + + + /* now pass this result to some controller */ + if (m_rayHit) + { + if (!m_bTriggered) + { + // notify logicsystem that ray is now hitting + result = true; + m_bTriggered = true; + } + else + { + + } + } + else + { + if (m_bTriggered) + { + m_bTriggered = false; + // notify logicsystem that ray is not hitting anymore + result = true; + } + } + + return result; +} + + + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_RaySensor::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_RaySensor", + sizeof(KX_RaySensor), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_RaySensor::Parents[] = { + &KX_RaySensor::Type, + &SCA_ISensor::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_RaySensor::Methods[] = { + {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_VARARGS, GetHitObject_doc}, + {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_VARARGS, GetHitPosition_doc}, + {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_VARARGS, GetHitNormal_doc}, + {"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_VARARGS, GetRayDirection_doc}, + {NULL,NULL} //Sentinel +}; + +char KX_RaySensor::GetHitObject_doc[] = +"getHitObject()\n" +"\tReturns the name of the object that was hit by this ray.\n"; +PyObject* KX_RaySensor::PyGetHitObject(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + if (m_hitObject) + { + return m_hitObject->AddRef(); + } + Py_Return; +} + + +char KX_RaySensor::GetHitPosition_doc[] = +"getHitPosition()\n" +"\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n"; +PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + MT_Point3 pos = m_hitPosition; + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index])); + } + return resultlist; + +} + +char KX_RaySensor::GetRayDirection_doc[] = +"getRayDirection()\n" +"\tReturns the direction from the ray (in worldcoordinates) .\n"; +PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + MT_Vector3 dir = m_rayDirection; + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(dir[index])); + } + return resultlist; + +} + +char KX_RaySensor::GetHitNormal_doc[] = +"getHitNormal()\n" +"\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n"; +PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + MT_Vector3 pos = m_hitNormal; + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index])); + } + return resultlist; + +} + + + +PyObject* KX_RaySensor::_getattr(char* attr) { + _getattr_up(SCA_ISensor); +} diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h new file mode 100644 index 00000000000..7eb16bd6d5b --- /dev/null +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -0,0 +1,79 @@ +/** + * Cast a ray and feel for objects + * + * $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_RAYSENSOR_H +#define __KX_RAYSENSOR_H + +#include "SCA_ISensor.h" +#include "MT_Point3.h" + +class KX_RaySensor : public SCA_ISensor +{ + Py_Header; + STR_String m_propertyname; + bool m_bFindMaterial; + double m_distance; + class KX_Scene* m_ketsjiScene; + bool m_bTriggered; + int m_axis; + bool m_rayHit; + MT_Point3 m_hitPosition; + SCA_IObject* m_hitObject; + MT_Vector3 m_hitNormal; + MT_Vector3 m_rayDirection; + +public: + KX_RaySensor(class SCA_EventManager* eventmgr, + SCA_IObject* gameobj, + const STR_String& propname, + bool fFindMaterial, + double distance, + int axis, + class KX_Scene* ketsjiScene, + PyTypeObject* T = &Type); + virtual ~KX_RaySensor(); + virtual CValue* GetReplica(); + + virtual bool Evaluate(CValue* event); + virtual bool IsPositiveTrigger(); + + KX_PYMETHOD_DOC(KX_RaySensor,GetHitObject); + KX_PYMETHOD_DOC(KX_RaySensor,GetHitPosition); + KX_PYMETHOD_DOC(KX_RaySensor,GetHitNormal); + KX_PYMETHOD_DOC(KX_RaySensor,GetRayDirection); + + virtual PyObject* _getattr(char *attr); + +}; +#endif //__KX_RAYSENSOR_H diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp new file mode 100644 index 00000000000..4e73f4e27ca --- /dev/null +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp @@ -0,0 +1,335 @@ +// +// Add an object when this actuator is triggered +// +// $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 ***** +// Previously existed as: + +// \source\gameengine\GameLogic\SCA_AddObjectActuator.cpp + +// Please look here for revision history. + + +#include "KX_SCA_AddObjectActuator.h" +#include "SCA_IScene.h" +#include "KX_GameObject.h" +#include "KX_IPhysicsController.h" + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj, + CValue* original, + int time, + SCA_IScene* scene, + const MT_Vector3& linvel, + bool local, + PyTypeObject* T) + : + SCA_IActuator(gameobj, T), + m_OriginalObject(original), + m_scene(scene), + m_linear_velocity(linvel), + m_localFlag(local) +{ + m_lastCreatedObject = NULL; + m_timeProp = time; +} + + + +KX_SCA_AddObjectActuator::~KX_SCA_AddObjectActuator() +{ + if (m_lastCreatedObject) + m_lastCreatedObject->Release(); +} + + + +bool KX_SCA_AddObjectActuator::Update(double curtime, + double deltatime) +{ + bool result = false; + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) return false; // do nothing on negative events + if (m_OriginalObject) + { + // Add an identical object, with properties inherited from the original object + // Now it needs to be added to the current scene. + SCA_IObject* replica = m_scene->AddReplicaObject(m_OriginalObject,GetParent(),m_timeProp ); + KX_GameObject * game_obj = static_cast<KX_GameObject *>(replica); + game_obj->setLinearVelocity(m_linear_velocity,m_localFlag); + + //if (game_obj->GetSumoObject()) + //{ + // If this is object is also controlled by physics. + // we have to inform the physics controller that + // we no longer take control of the object. + // game_obj->GetPhysicsController()->ResolveCombinedVelocities(m_linear_velocity, + // MT_Vector3(0,0,0), + // m_localFlag, + // false); + //} + + // keep a copy of the last object, to allow python scripters to change it + if (m_lastCreatedObject) + m_lastCreatedObject->Release(); + + m_lastCreatedObject = replica; + m_lastCreatedObject->AddRef(); + } + + return false; +} + + + +SCA_IObject* KX_SCA_AddObjectActuator::GetLastCreatedObject() const +{ + return m_lastCreatedObject; +} + + + +CValue* KX_SCA_AddObjectActuator::GetReplica() +{ + KX_SCA_AddObjectActuator* replica = new KX_SCA_AddObjectActuator(*this); + + if (replica == NULL) + return NULL; + + // this will copy properties and so on... + replica->ProcessReplica(); + replica->m_lastCreatedObject=NULL; + CValue::AddDataToReplica(replica); + + return replica; +} + + + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_SCA_AddObjectActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_SCA_AddObjectActuator", + sizeof(KX_SCA_AddObjectActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, + __repr, + 0, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_SCA_AddObjectActuator::Parents[] = { + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; +PyMethodDef KX_SCA_AddObjectActuator::Methods[] = { + {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_VARARGS, SetObject_doc}, + {"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_VARARGS, SetTime_doc}, + {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, GetObject_doc}, + {"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_VARARGS, GetTime_doc}, + {"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_VARARGS, GetLinearVelocity_doc}, + {"setLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetLinearVelocity, METH_VARARGS, SetLinearVelocity_doc}, + {"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_VARARGS,"getLastCreatedObject() : get the object handle to the last created object\n"}, + {NULL,NULL} //Sentinel +}; + + +PyObject* KX_SCA_AddObjectActuator::_getattr(char* attr) +{ + _getattr_up(SCA_IActuator); +} + +/* 1. setObject */ +char KX_SCA_AddObjectActuator::SetObject_doc[] = +"setObject(name)\n" +"\t- name: string\n" +"\tSets the object that will be added. There has to be an object\n" +"\tof this name. If not, this function does nothing.\n"; + + + +PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + char* objectname; + + if (!PyArg_ParseTuple(args, "s", &objectname)) + return NULL; + + CValue* gameobj = SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname)); + + m_OriginalObject= (CValue*)gameobj; + + Py_Return; +} + + + +/* 2. setTime */ +char KX_SCA_AddObjectActuator::SetTime_doc[] = +"setTime(duration)\n" +"\t- duration: integer\n" +"\tSets the lifetime of the object that will be added, in frames. \n" +"\tIf the duration is negative, it is set to 0.\n"; + + +PyObject* KX_SCA_AddObjectActuator::PySetTime(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int deltatime; + + if (!PyArg_ParseTuple(args, "i", &deltatime)) + return NULL; + + m_timeProp = deltatime; + if (m_timeProp < 0) m_timeProp = 0; + + Py_Return; +} + + + +/* 3. getTime */ +char KX_SCA_AddObjectActuator::GetTime_doc[] = +"GetTime()\n" +"\tReturns the lifetime of the object that will be added.\n"; + + +PyObject* KX_SCA_AddObjectActuator::PyGetTime(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return PyInt_FromLong(m_timeProp); +} + + +/* 4. getObject */ +char KX_SCA_AddObjectActuator::GetObject_doc[] = +"getObject()\n" +"\tReturns the name of the object that will be added.\n"; + + + +PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return PyString_FromString(m_OriginalObject->GetName()); +} + + + +/* 5. getLinearVelocity */ +char KX_SCA_AddObjectActuator::GetLinearVelocity_doc[] = +"GetLinearVelocity()\n" +"\tReturns the linear velocity that will be assigned to \n" +"\tthe created object.\n"; + + + +PyObject* KX_SCA_AddObjectActuator::PyGetLinearVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + PyObject *retVal = PyList_New(3); + + PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0])); + PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1])); + PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2])); + + return retVal; +} + + + +/* 6. setLinearVelocity */ +char KX_SCA_AddObjectActuator::SetLinearVelocity_doc[] = +"setLinearVelocity(vx, vy, vz)\n" +"\t- vx: float\n" +"\t- vy: float\n" +"\t- vz: float\n" +"\tAssign this velocity to the created object. \n"; + + +PyObject* KX_SCA_AddObjectActuator::PySetLinearVelocity(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + float vecArg[3]; + if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2])) + return NULL; + + m_linear_velocity.setValue(vecArg); + Py_Return; +} + + + +/* 7. GetLastCreatedObject */ +char KX_SCA_AddObjectActuator::GetLastCreatedObject_doc[] = +"getLastCreatedObject()\n" +"\tReturn the last created object. \n"; + + +PyObject* KX_SCA_AddObjectActuator::PyGetLastCreatedObject(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + SCA_IObject* result = this->GetLastCreatedObject(); + if (result) + { + result->AddRef(); + return result; + } + // don't return NULL to python anymore, it gives trouble in the scripts + Py_Return; +} diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h new file mode 100644 index 00000000000..9810669034c --- /dev/null +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h @@ -0,0 +1,133 @@ +// +// Add object to the game world on action of this actuator. A copy is made +// of a referenced object. The copy inherits some properties from the owner +// of this actuator. +// +// $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 ***** +// +// Previously existed as: +// \source\gameengine\GameLogic\SCA_AddObjectActuator.h +// Please look here for revision history. + +#ifndef __KX_SCA_AddObjectActuator +#define __KX_SCA_AddObjectActuator + +/* Actuator tree */ +#include "SCA_IActuator.h" +#include "SCA_LogicManager.h" + +#include "MT_Vector3.h" + +class SCA_IScene; + +class KX_SCA_AddObjectActuator : public SCA_IActuator +{ + Py_Header; + + /// Time field: lifetime of the new object + int m_timeProp; + + /// Original object reference (object to replicate) + CValue* m_OriginalObject; + + /// Object will be added to the following scene + SCA_IScene* m_scene; + + /// Linear velocity upon creation of the object. + MT_Vector3 m_linear_velocity; + + /// Apply the velocity locally + bool m_localFlag; + + SCA_IObject* m_lastCreatedObject; + +public: + + /** + * This class also has the default constructors + * available. Use with care! + */ + + KX_SCA_AddObjectActuator( + SCA_IObject *gameobj, + CValue* original, + int time, + SCA_IScene* scene, + const MT_Vector3& linvel, + bool local, + PyTypeObject* T=&Type + ); + + ~KX_SCA_AddObjectActuator(void); + + CValue* + GetReplica( + ) ; + + bool + Update( + double curtime, + double deltatime + ); + + PyObject* + _getattr( + char *attr + ); + + SCA_IObject* + GetLastCreatedObject( + ) const ; + + /* 1. setObject */ + KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,SetObject); + /* 2. setTime */ + KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,SetTime); + /* 3. getTime */ + KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetTime); + /* 4. getObject */ + KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetObject); + /* 5. getLinearVelocity */ + KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetLinearVelocity); + /* 6. setLinearVelocity */ + KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,SetLinearVelocity); + /* 7. getLastCreatedObject */ + KX_PYMETHOD_DOC(KX_SCA_AddObjectActuator,GetLastCreatedObject); + + +}; /* end of class KX_SCA_AddObjectActuator : public KX_EditObjectActuator */ + +#endif + + + + + diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp new file mode 100644 index 00000000000..ca1c4d04084 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp @@ -0,0 +1,137 @@ +/** + * $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 ***** + */ + +// + +// Remove the actuator's parent when triggered +// +// Previously existed as: +// \source\gameengine\GameLogic\SCA_EndObjectActuator.cpp +// Please look here for revision history. + +#include "SCA_IActuator.h" +#include "KX_SCA_EndObjectActuator.h" +#include "SCA_IScene.h" + +KX_SCA_EndObjectActuator::KX_SCA_EndObjectActuator(SCA_IObject *gameobj, + SCA_IScene* scene, + PyTypeObject* T): + SCA_IActuator(gameobj, T), + m_scene(scene) +{ + // intentionally empty +} /* End of constructor */ + + + +KX_SCA_EndObjectActuator::~KX_SCA_EndObjectActuator() +{ + // there's nothing to be done here, really.... +} /* end of destructor */ + + + +bool KX_SCA_EndObjectActuator::Update(double curtime, + double deltatime + ) +{ + bool result = false; + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) + return false; // do nothing on negative events + m_scene->DelayedRemoveObject(GetParent()); + + return false; +} + + + +CValue* KX_SCA_EndObjectActuator::GetReplica() +{ + KX_SCA_EndObjectActuator* replica = + new KX_SCA_EndObjectActuator(*this); + if (replica == NULL) return NULL; + + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; +}; + + + +/* ------------------------------------------------------------------------- */ +/* Python functions : integration hooks */ +/* ------------------------------------------------------------------------- */ + +PyTypeObject KX_SCA_EndObjectActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_SCA_EndObjectActuator", + sizeof(KX_SCA_EndObjectActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + + +PyParentObject KX_SCA_EndObjectActuator::Parents[] = { + &KX_SCA_EndObjectActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + + +PyMethodDef KX_SCA_EndObjectActuator::Methods[] = { + {NULL,NULL} //Sentinel +}; + + +PyObject* KX_SCA_EndObjectActuator::_getattr(char* attr) +{ + _getattr_up(SCA_IActuator); +} + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h new file mode 100644 index 00000000000..39ee911b48f --- /dev/null +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h @@ -0,0 +1,80 @@ +// +// Add object to the game world on action of this actuator +// +// $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 ***** +// +// Previously existed as: +// \source\gameengine\GameLogic\SCA_EndObjectActuator.h +// Please look here for revision history. + +#ifndef __KX_SCA_ENDOBJECTACTUATOR +#define __KX_SCA_ENDOBJECTACTUATOR + +#include "SCA_IActuator.h" + +class SCA_IScene; + +class KX_SCA_EndObjectActuator : public SCA_IActuator +{ + Py_Header; + SCA_IScene* m_scene; + + public: + KX_SCA_EndObjectActuator( + SCA_IObject* gameobj, + SCA_IScene* scene, + PyTypeObject* T=&Type + ); + + ~KX_SCA_EndObjectActuator(); + + CValue* + GetReplica( + ); + + bool + Update( + double curtime, + double deltatime + ); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + PyObject* + _getattr( + char *attr + ); + +}; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */ + +#endif diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp new file mode 100644 index 00000000000..731ddeff80d --- /dev/null +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp @@ -0,0 +1,182 @@ +// +// Replace the mesh for this actuator's parent +// +// $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 ***** + +// +// Previously existed as: + +// \source\gameengine\GameLogic\SCA_ReplaceMeshActuator.cpp + +// Please look here for revision history. + + +#include "KX_SCA_ReplaceMeshActuator.h" + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ + + PyTypeObject + +KX_SCA_ReplaceMeshActuator:: + +Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_SCA_ReplaceMeshActuator", + sizeof(KX_SCA_ReplaceMeshActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, + __repr, + 0, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_SCA_ReplaceMeshActuator::Parents[] = { + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + + +PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = { + {"setMesh", (PyCFunction) KX_SCA_ReplaceMeshActuator::sPySetMesh, METH_VARARGS, SetMesh_doc}, + {NULL,NULL} //Sentinel +}; + + + +PyObject* KX_SCA_ReplaceMeshActuator::_getattr(char* attr) +{ + _getattr_up(SCA_IActuator); +} + + + +/* 1. setMesh */ +char KX_SCA_ReplaceMeshActuator::SetMesh_doc[] = + "setMesh(name)\n" + "\t- name: string\n" + "\tSet the mesh that will be substituted for the current one.\n"; + +PyObject* KX_SCA_ReplaceMeshActuator::PySetMesh(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + char* meshname; + + if (!PyArg_ParseTuple(args, "s", &meshname)) + { + return NULL; + } + + void* mesh = SCA_ILogicBrick::m_sCurrentLogicManager->GetMeshByName(STR_String(meshname)); + + if (m_mesh) { + m_mesh= (class RAS_MeshObject*)mesh; + Py_Return; + } + + return NULL; +} + + + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_SCA_ReplaceMeshActuator::KX_SCA_ReplaceMeshActuator(SCA_IObject *gameobj, + class RAS_MeshObject *mesh, + SCA_IScene* scene, + PyTypeObject* T) : + + SCA_IActuator(gameobj, T), + m_scene(scene), + m_mesh(mesh) +{ +} /* End of constructor */ + + + +KX_SCA_ReplaceMeshActuator::~KX_SCA_ReplaceMeshActuator() +{ + // there's nothing to be done here, really.... +} /* end of destructor */ + + + +bool KX_SCA_ReplaceMeshActuator::Update(double curtime, + double deltatime) +{ + bool result = false; + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) + return false; // do nothing on negative events + + if (m_mesh) m_scene->ReplaceMesh(GetParent(),m_mesh); + + return false; +} + + + +CValue* KX_SCA_ReplaceMeshActuator::GetReplica() +{ + KX_SCA_ReplaceMeshActuator* replica = + new KX_SCA_ReplaceMeshActuator(*this); + + if (replica == NULL) + return NULL; + + replica->ProcessReplica(); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +}; + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h new file mode 100644 index 00000000000..ada21d06847 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -0,0 +1,88 @@ +// +// Add object to the game world on action of this actuator +// +// $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 ***** +// +// Previously existed as: +// \source\gameengine\GameLogic\SCA_ReplaceMeshActuator.h +// Please look here for revision history. +// + +#ifndef __KX_SCA_REPLACEMESHACTUATOR +#define __KX_SCA_REPLACEMESHACTUATOR + +#include "SCA_IActuator.h" +#include "SCA_PropertyActuator.h" +#include "SCA_LogicManager.h" +#include "SCA_IScene.h" + +#include "RAS_MeshObject.h" + +class KX_SCA_ReplaceMeshActuator : public SCA_IActuator +{ + Py_Header; + + // mesh reference (mesh to replace) + RAS_MeshObject* m_mesh; + SCA_IScene* m_scene; + + public: + KX_SCA_ReplaceMeshActuator( + SCA_IObject* gameobj, + RAS_MeshObject *mesh, + SCA_IScene* scene, + PyTypeObject* T=&Type + ); + + ~KX_SCA_ReplaceMeshActuator( + ); + + CValue* + GetReplica( + ); + + bool + Update( + double curtime, + double deltatime + ); + + PyObject* + _getattr( + char *attr + ); + + /* 1. setMesh */ + KX_PYMETHOD_DOC(KX_SCA_ReplaceMeshActuator,SetMesh); + +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp new file mode 100644 index 00000000000..16529a91471 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp @@ -0,0 +1,328 @@ +/** + * $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_SG_NodeRelationships.h" + + +/** + * Implementation of classes defined in KX_SG_NodeRelationships.h + */ + +/** + * first of all KX_NormalParentRelation + */ + + KX_NormalParentRelation * +KX_NormalParentRelation:: +New( +) { + return new KX_NormalParentRelation(); +} + + void +KX_NormalParentRelation:: +UpdateChildCoordinates( + SG_Spatial * child, + const SG_Spatial * parent +){ + assert(child != NULL); + + // This way of accessing child coordinates is a bit cumbersome + // be nice to have non constant reference access to these values. + + const MT_Vector3 & child_scale = child->GetLocalScale(); + const MT_Point3 & child_pos = child->GetLocalPosition(); + const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); + + // the childs world locations which we will update. + + MT_Vector3 child_w_scale; + MT_Point3 child_w_pos; + MT_Matrix3x3 child_w_rotation; + + if (parent) { + + const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); + const MT_Point3 & p_world_pos = parent->GetWorldPosition(); + const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); + + child_w_scale = p_world_scale * child_scale; + child_w_rotation = p_world_rotation * child_rotation; + + child_w_pos = p_world_pos + p_world_scale * + (p_world_rotation * child_pos); + } else { + + child_w_scale = child_scale; + child_w_pos = child_pos; + child_w_rotation = child_rotation; + } + + child->SetWorldScale(child_w_scale); + child->SetWorldPosition(child_w_pos); + child->SetWorldOrientation(child_w_rotation); +} + + SG_ParentRelation * +KX_NormalParentRelation:: +NewCopy( +){ + return new KX_NormalParentRelation(); +} + +KX_NormalParentRelation:: +~KX_NormalParentRelation( +){ + //nothing to do +} + + +KX_NormalParentRelation:: +KX_NormalParentRelation( +){ + // nothing to do +} + +/** + * Next KX_VertexParentRelation + */ + + + KX_VertexParentRelation * +KX_VertexParentRelation:: +New( +){ + return new KX_VertexParentRelation(); +} + +/** + * Method inherited from KX_ParentRelation + */ + + void +KX_VertexParentRelation:: +UpdateChildCoordinates( + SG_Spatial * child, + const SG_Spatial * parent +){ + + assert(child != NULL); + + const MT_Vector3 & child_scale = child->GetLocalScale(); + const MT_Point3 & child_pos = child->GetLocalPosition(); + const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); + + // the childs world locations which we will update. + + MT_Vector3 child_w_scale; + MT_Point3 child_w_pos; + MT_Matrix3x3 child_w_rotation; + + if (parent) { + + // This is a vertex parent so we do not inherit orientation + // information. + + const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); + const MT_Point3 & p_world_pos = parent->GetWorldPosition(); + const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); + + child_w_scale = child_scale; + child_w_rotation = child_rotation; + child_w_pos = p_world_pos + child_pos; + + } else { + + child_w_scale = child_scale; + child_w_pos = child_pos; + child_w_rotation = child_rotation; + } + + child->SetWorldScale(child_w_scale); + child->SetWorldPosition(child_w_pos); + child->SetWorldOrientation(child_w_rotation); +} + +/** + * Method inherited from KX_ParentRelation + */ + + SG_ParentRelation * +KX_VertexParentRelation:: +NewCopy( +){ + return new KX_VertexParentRelation(); +}; + +KX_VertexParentRelation:: +~KX_VertexParentRelation( +){ + //nothing to do +} + + +KX_VertexParentRelation:: +KX_VertexParentRelation( +){ + //nothing to do +} + + +/** + * Slow parent relationship + */ + + KX_SlowParentRelation * +KX_SlowParentRelation:: +New( + MT_Scalar relaxation +){ + return new KX_SlowParentRelation(relaxation); +} + +/** + * Method inherited from KX_ParentRelation + */ + + void +KX_SlowParentRelation:: +UpdateChildCoordinates( + SG_Spatial * child, + const SG_Spatial * parent +){ + assert(child != NULL); + + const MT_Vector3 & child_scale = child->GetLocalScale(); + const MT_Point3 & child_pos = child->GetLocalPosition(); + const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation(); + + // the childs world locations which we will update. + + MT_Vector3 child_w_scale; + MT_Point3 child_w_pos; + MT_Matrix3x3 child_w_rotation; + + if (parent) { + + // This is a slow parent relation + // first compute the normal child world coordinates. + + MT_Vector3 child_n_scale; + MT_Point3 child_n_pos; + MT_Matrix3x3 child_n_rotation; + + const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); + const MT_Point3 & p_world_pos = parent->GetWorldPosition(); + const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); + + child_n_scale = p_world_scale * child_scale; + child_n_rotation = p_world_rotation * child_rotation; + + child_n_pos = p_world_pos + p_world_scale * + (p_world_rotation * child_pos); + + + if (m_initialized) { + + // get the current world positions + + child_w_scale = child->GetWorldScaling(); + child_w_pos = child->GetWorldPosition(); + child_w_rotation = child->GetWorldOrientation(); + + // now 'interpolate' the normal coordinates with the last + // world coordinates to get the new world coordinates. + + // problem 1: + // The child world scale needs to be initialized in some way for this + // to make sense + // problem 2: + // This is way of doing interpolation is nonsense + + int i; + + MT_Scalar weight = MT_Scalar(1)/(m_relax + 1); + for (i=0;i <3 ;i++) { + child_w_scale[i] = (m_relax * child_w_scale[i] + child_n_scale[i]) * weight; + child_w_pos[i] = (m_relax * child_w_pos[i] + child_n_pos[i]) * weight; + child_w_rotation[0][i] = (m_relax * child_w_rotation[0][i] + child_n_rotation[0][i]) * weight; + child_w_rotation[1][i] = (m_relax * child_w_rotation[1][i] + child_n_rotation[1][i]) * weight; + child_w_rotation[2][i] = (m_relax * child_w_rotation[2][i] + child_n_rotation[2][i]) * weight; + } + } else { + child_w_scale = child_n_scale; + child_w_pos = child_n_pos; + child_w_rotation = child_n_rotation; + m_initialized = true; + } + + } else { + + child_w_scale = child_scale; + child_w_pos = child_pos; + child_w_rotation = child_rotation; + } + + child->SetWorldScale(child_w_scale); + child->SetWorldPosition(child_w_pos); + child->SetWorldOrientation(child_w_rotation); +} + +/** + * Method inherited from KX_ParentRelation + */ + + SG_ParentRelation * +KX_SlowParentRelation:: +NewCopy( +){ + return new KX_SlowParentRelation(m_relax); +} + +KX_SlowParentRelation:: +KX_SlowParentRelation( + MT_Scalar relaxation +): + m_relax(relaxation), + m_initialized(false) +{ + //nothing to do +} + +KX_SlowParentRelation:: +~KX_SlowParentRelation( +){ + //nothing to do +} + + + + diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.h b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h new file mode 100644 index 00000000000..c6c3dbaf315 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.h @@ -0,0 +1,214 @@ +/** + * @mainpage KX_SG_NodeRelationships + + * @section + * + * This file provides common concrete implementations of + * SG_ParentRelation used by the game engine. These are + * KX_SlowParentRelation a slow parent relationship. + * KX_NormalParentRelation a normal parent relationship where + * orientation and position are inherited from the parent by + * the child. + * KX_VertexParentRelation only location information is + * inherited by the child. + * + * @see SG_ParentRelation for more information about this + * interface + * + * $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 "SG_Spatial.h" +#include "SG_ParentRelation.h" + + +class KX_NormalParentRelation : public SG_ParentRelation +{ + +public : + + /** + * Allocate and construct a new KX_NormalParentRelation + * on the heap. + */ + + static + KX_NormalParentRelation * + New( + ); + + /** + * Method inherited from KX_ParentRelation + */ + + void + UpdateChildCoordinates( + SG_Spatial * child, + const SG_Spatial * parent + ); + + /** + * Method inherited from KX_ParentRelation + */ + + SG_ParentRelation * + NewCopy( + ); + + ~KX_NormalParentRelation( + ); + +private : + + KX_NormalParentRelation( + ); + +}; + + +class KX_VertexParentRelation : public SG_ParentRelation +{ + +public : + + /** + * Allocate and construct a new KX_VertexParentRelation + * on the heap. + */ + + static + KX_VertexParentRelation * + New( + ); + + /** + * Method inherited from KX_ParentRelation + */ + + void + UpdateChildCoordinates( + SG_Spatial * child, + const SG_Spatial * parent + ); + + /** + * Method inherited from KX_ParentRelation + */ + + SG_ParentRelation * + NewCopy( + ); + + ~KX_VertexParentRelation( + ); + +private : + + KX_VertexParentRelation( + ); + +}; + + +class KX_SlowParentRelation : public SG_ParentRelation +{ + +public : + + /** + * Allocate and construct a new KX_VertexParentRelation + * on the heap. + */ + + static + KX_SlowParentRelation * + New( + MT_Scalar relaxation + ); + + /** + * Method inherited from KX_ParentRelation + */ + + void + UpdateChildCoordinates( + SG_Spatial * child, + const SG_Spatial * parent + ); + + /** + * Method inherited from KX_ParentRelation + */ + + SG_ParentRelation * + NewCopy( + ); + + ~KX_SlowParentRelation( + ); + +private : + + KX_SlowParentRelation( + MT_Scalar relaxation + ); + + // the relaxation coefficient. + + MT_Scalar m_relax; + + /** + * Looks like a hack flag to me. + * We need to compute valid world coordinates the first + * time we update spatial data of the child. This is done + * by just doing a normal parent relation the first time + * UpdateChildCoordinates is called and then doing the + * slow parent relation + */ + + bool m_initialized; + +}; + + + + + + + + + + + + + + diff --git a/source/gameengine/Ketsji/KX_ScalarInterpolator.cpp b/source/gameengine/Ketsji/KX_ScalarInterpolator.cpp new file mode 100644 index 00000000000..e1c72c74a41 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ScalarInterpolator.cpp @@ -0,0 +1,38 @@ +/** + * $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_ScalarInterpolator.h" + +#include "KX_IScalarInterpolator.h" + +void KX_ScalarInterpolator::Execute(float currentTime) const { + *m_target = m_ipo->GetValue(currentTime); +} diff --git a/source/gameengine/Ketsji/KX_ScalarInterpolator.h b/source/gameengine/Ketsji/KX_ScalarInterpolator.h new file mode 100644 index 00000000000..85c8900e8ab --- /dev/null +++ b/source/gameengine/Ketsji/KX_ScalarInterpolator.h @@ -0,0 +1,63 @@ +/** + * $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 +#define KX_SCALARINTERPOLATOR + +#include "MT_Scalar.h" +#include "KX_IInterpolator.h" + +class KX_IScalarInterpolator; + +class KX_ScalarInterpolator : public KX_IInterpolator { +public: + KX_ScalarInterpolator(MT_Scalar* target, + KX_IScalarInterpolator *ipo) : + m_target(target), + m_ipo(ipo) + {} + + virtual ~KX_ScalarInterpolator() {} + virtual void Execute(float currentTime) const; + void SetNewTarget(MT_Scalar* newtarget) + { + m_target=newtarget; + } + MT_Scalar* GetTarget() + { + return m_target; + } +private: + MT_Scalar* m_target; + KX_IScalarInterpolator *m_ipo; +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_ScalingInterpolator.cpp b/source/gameengine/Ketsji/KX_ScalingInterpolator.cpp new file mode 100644 index 00000000000..87bd9455d74 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ScalingInterpolator.cpp @@ -0,0 +1,42 @@ +/** + * $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_ScalingInterpolator.h" + + +#include "MT_Vector3.h" +#include "KX_IScalarInterpolator.h" + +void KX_ScalingInterpolator::Execute(float currentTime) const { + m_target.setValue(m_ipos[0]->GetValue(currentTime), + m_ipos[1]->GetValue(currentTime), + m_ipos[2]->GetValue(currentTime)); +} diff --git a/source/gameengine/Ketsji/KX_ScalingInterpolator.h b/source/gameengine/Ketsji/KX_ScalingInterpolator.h new file mode 100644 index 00000000000..fd7e00d7b24 --- /dev/null +++ b/source/gameengine/Ketsji/KX_ScalingInterpolator.h @@ -0,0 +1,61 @@ +/** + * $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_SCALINGINTERPOLATOR +#define KX_SCALINGINTERPOLATOR + +#include "KX_IInterpolator.h" + +class MT_Vector3; +class KX_IScalarInterpolator; + +class KX_ScalingInterpolator : public KX_IInterpolator { +public: + KX_ScalingInterpolator(MT_Vector3& target, + KX_IScalarInterpolator *ipos[]) + : m_target(target) + { + m_ipos[0] = ipos[0]; + m_ipos[1] = ipos[1]; + m_ipos[2] = ipos[2]; + } + + virtual void Execute(float currentTime) const; + +private: + MT_Vector3& m_target; + KX_IScalarInterpolator *m_ipos[3]; +}; + +#endif + + + diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp new file mode 100644 index 00000000000..508ada3a5a9 --- /dev/null +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -0,0 +1,977 @@ +/* + * $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 ***** + * Ketsji scene. Holds references to all scene data. + */ + +#ifdef WIN32 +#pragma warning (disable : 4786) +#endif //WIN32 + +#include "KX_KetsjiEngine.h" +#include "RAS_IPolygonMaterial.h" +#include "KX_Scene.h" +#include "ListValue.h" +#include "SCA_LogicManager.h" +#include "SCA_TimeEventManager.h" +#include "SCA_AlwaysEventManager.h" +#include "SCA_RandomEventManager.h" +#include "KX_RayEventManager.h" +#include "KX_TouchEventManager.h" +#include "SCA_KeyboardManager.h" +#include "SCA_MouseManager.h" +#include "SCA_PropertyEventManager.h" +#include "KX_Camera.h" + +#include "RAS_MeshObject.h" +#include "RAS_IRasterizer.h" +#include "RAS_BucketManager.h" + +#include "FloatValue.h" +#include "SCA_IController.h" +#include "SCA_IActuator.h" +#include "SG_Node.h" +#include "SYS_System.h" +#include "SG_Controller.h" +#include "SG_IObject.h" + +#include "KX_SG_NodeRelationships.h" + +#include "KX_NetworkEventManager.h" +#include "NG_NetworkScene.h" +#include "PHY_IPhysicsEnvironment.h" +#include "KX_IPhysicsController.h" + + +void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene) +{ + KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj); + + return (void*)replica; +} + +void* KX_SceneDestructionFunc(SG_IObject* node,void* gameobj,void* scene) +{ + ((KX_Scene*)scene)->RemoveNodeDestructObject(node,(KX_GameObject*)gameobj); + + return NULL; +}; + + +SG_Callbacks KX_Scene::m_callbacks = SG_Callbacks(KX_SceneReplicationFunc,KX_SceneDestructionFunc); + +// temporarily var until there is a button in the userinterface +// (defined in KX_PythonInit.cpp) +extern bool gUseVisibilityTemp; + + + + +KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice, + class SCA_IInputDevice* mousedevice, + class NG_NetworkDeviceInterface *ndi, + class SND_IAudioDevice* adi, + const STR_String& sceneName): + + m_mousemgr(NULL), + m_keyboardmgr(NULL), + m_active_camera(NULL), + m_ueberExecutionPriority(0), + m_adi(adi), + m_sceneName(sceneName), + m_networkDeviceInterface(ndi), + m_physicsEnvironment(0) +{ + + + m_activity_culling = false; + m_suspend = false; + m_isclearingZbuffer = true; + m_tempObjectList = new CListValue(); + m_objectlist = new CListValue(); + m_parentlist = new CListValue(); + m_lightlist= new CListValue(); + m_euthanasyobjects = new CListValue(); + + m_logicmgr = new SCA_LogicManager(); + + m_timemgr = new SCA_TimeEventManager(m_logicmgr); + m_keyboardmgr = new SCA_KeyboardManager(m_logicmgr,keyboarddevice); + m_mousemgr = new SCA_MouseManager(m_logicmgr,mousedevice); + +// m_solidScene = DT_CreateScene(); +// m_respTable = DT_CreateRespTable(); + + SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr); + //KX_TouchEventManager* touchmgr = new KX_TouchEventManager(m_logicmgr, m_respTable, m_solidScene); + SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr); + SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr); + KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr); + + KX_NetworkEventManager* netmgr = new KX_NetworkEventManager(m_logicmgr, ndi); + + m_logicmgr->RegisterEventManager(alwaysmgr); + m_logicmgr->RegisterEventManager(propmgr); + m_logicmgr->RegisterEventManager(m_keyboardmgr); + m_logicmgr->RegisterEventManager(m_mousemgr); + //m_logicmgr->RegisterEventManager(touchmgr); + m_logicmgr->RegisterEventManager(m_timemgr); + m_logicmgr->RegisterEventManager(rndmgr); + m_logicmgr->RegisterEventManager(raymgr); + m_logicmgr->RegisterEventManager(netmgr); + + //m_sumoScene = new SM_Scene(); + //m_sumoScene->setSecondaryRespTable(m_respTable); + m_soundScene = new SND_Scene(adi); + assert (m_networkDeviceInterface != NULL); + m_networkScene = new NG_NetworkScene(m_networkDeviceInterface); + + m_rootnode = NULL; + + m_bucketmanager=new RAS_BucketManager(); + + m_canvasDesignWidth = 0; + m_canvasDesignHeight = 0; +} + + + +KX_Scene::~KX_Scene() +{ +// int numobj = m_objectlist->GetCount(); + + //int numrootobjects = GetRootParentList()->GetCount(); + for (int i = 0; i < GetRootParentList()->GetCount(); i++) + { + KX_GameObject* parentobj = (KX_GameObject*) GetRootParentList()->GetValue(i); + this->RemoveObject(parentobj); + } + + if(m_objectlist) + m_objectlist->Release(); + + if (m_parentlist) + m_parentlist->Release(); + + if (m_lightlist) + m_lightlist->Release(); + + if (m_tempObjectList) + m_tempObjectList->Release(); + + if (m_euthanasyobjects) + m_euthanasyobjects->Release(); + + if (m_logicmgr) + delete m_logicmgr; + + if (m_physicsEnvironment) + delete m_physicsEnvironment; + + if (m_soundScene) + delete m_soundScene; + + if (m_networkScene) + delete m_networkScene; + + if (m_bucketmanager) + { + delete m_bucketmanager; + } +} + + + + +void KX_Scene::SetProjectionMatrix(MT_CmMatrix4x4& pmat) +{ + m_projectionmat = pmat; +} + + + +RAS_BucketManager* KX_Scene::GetBucketManager() +{ + return m_bucketmanager; +} + + + +CListValue* KX_Scene::GetObjectList() +{ + return m_objectlist; +} + + + +CListValue* KX_Scene::GetRootParentList() +{ + return m_parentlist; +} + + + +CListValue* KX_Scene::GetLightList() +{ + return m_lightlist; +} + +SCA_LogicManager* KX_Scene::GetLogicManager() +{ + return m_logicmgr; +} + +SCA_TimeEventManager* KX_Scene::GetTimeEventManager() +{ + return m_timemgr; +} + + + + +void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings) +{ + m_frame_settings = frame_settings; +}; + +/** + * Return a const reference to the framing + * type set by the above call. + * The contents are not guarenteed to be sensible + * if you don't call the above function. + */ +const RAS_FrameSettings& KX_Scene::GetFramingType() const +{ + return m_frame_settings; +}; + + + +/** + * Store the current scene's viewport on the + * game engine canvas. + */ +void KX_Scene::SetSceneViewport(const RAS_Rect &viewport) +{ + m_viewport = viewport; +} + + + +const RAS_Rect& KX_Scene::GetSceneViewport() const +{ + return m_viewport; +} + + + +void KX_Scene::SetWorldInfo(class KX_WorldInfo* worldinfo) +{ + m_worldinfo = worldinfo; +} + + + +class KX_WorldInfo* KX_Scene::GetWorldInfo() +{ + return m_worldinfo; +} + + + +SND_Scene* KX_Scene::GetSoundScene() +{ + return m_soundScene; +} + +const STR_String& KX_Scene::GetName() +{ + return m_sceneName; +} + + +void KX_Scene::Suspend() +{ + m_suspend = true; +} + +void KX_Scene::Resume() +{ + m_suspend = false; +} + +void KX_Scene::SetActivityCulling(bool b) +{ + m_activity_culling = b; +} + +bool KX_Scene::IsSuspended() +{ + return m_suspend; +} + +bool KX_Scene::IsClearingZBuffer() +{ + return m_isclearingZbuffer; +} + +void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer) +{ + m_isclearingZbuffer = isclearingZbuffer; +} + +void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gameobj) +{ + KX_GameObject* orgobj = (KX_GameObject*)gameobj; + NewRemoveObject(orgobj); + + if (node) + delete node; +} + +KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CValue* gameobj) +{ + KX_GameObject* orgobj = (KX_GameObject*)gameobj; + KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica(); + m_map_gameobject_to_replica.insert(orgobj, newobj); + + // also register 'timers' (time properties) of the replica + int numprops = newobj->GetPropertyCount(); + + for (int i = 0; i < numprops; i++) + { + CValue* prop = newobj->GetProperty(i); + + if (prop->GetProperty("timer")) + this->m_timemgr->AddTimeProperty(prop); + } + + if (node) + { + newobj->SetSGNode((SG_Node*)node); + } + else + { + m_rootnode = new SG_Node(newobj,this,KX_Scene::m_callbacks); + + // this fixes part of the scaling-added object bug + SG_Node* orgnode = orgobj->GetSGNode(); + m_rootnode->SetLocalScale(orgnode->GetLocalScale()); + m_rootnode->SetLocalPosition(orgnode->GetLocalPosition()); + m_rootnode->SetLocalOrientation(orgnode->GetLocalOrientation()); + + // define the relationship between this node and it's parent. + KX_NormalParentRelation * parent_relation = + KX_NormalParentRelation::New(); + m_rootnode->SetParentRelation(parent_relation); + + newobj->SetSGNode(m_rootnode); + } + + SG_IObject* replicanode = newobj->GetSGNode(); + SG_Node* rootnode = (replicanode == m_rootnode ? NULL : m_rootnode); + + replicanode->SetSGClientObject(newobj); + + // this is the list of object that are send to the graphics pipeline + m_objectlist->Add(newobj); + newobj->Bucketize(); + + // logic cannot be replicated, until the whole hierarchy is replicated. + m_logicHierarchicalGameObjects.push_back(newobj); + //replicate controllers of this node + SGControllerList scenegraphcontrollers = orgobj->GetSGNode()->GetSGControllerList(); + replicanode->RemoveAllControllers(); + SGControllerList::iterator cit; + //int numcont = scenegraphcontrollers.size(); + + for (cit = scenegraphcontrollers.begin();!(cit==scenegraphcontrollers.end());++cit) + { + // controller replication is quite complicated + // only replicate ipo and physics controller for now + + SG_Controller* replicacontroller = (*cit)->GetReplica((SG_Node*) replicanode); + if (replicacontroller) + { + replicacontroller->SetObject(replicanode); + replicanode->AddSGController(replicacontroller); + } + } + + return newobj; +} + + + +// before calling this method KX_Scene::ReplicateLogic(), make sure to +// have called 'GameObject::ReParentLogic' for each object this +// hierarchy that's because first ALL bricks must exist in the new +// replica of the hierarchy in order to make cross-links work properly +// ! +void KX_Scene::ReplicateLogic(KX_GameObject* newobj) +{ + // also relink the controller to sensors/actuators + SCA_ControllerList& controllers = newobj->GetControllers(); + //SCA_SensorList& sensors = newobj->GetSensors(); + //SCA_ActuatorList& actuators = newobj->GetActuators(); + + for (SCA_ControllerList::iterator itc = controllers.begin(); !(itc==controllers.end());itc++) + { + SCA_IController* cont = (*itc); + cont->SetUeberExecutePriority(m_ueberExecutionPriority); + vector<SCA_ISensor*> linkedsensors = cont->GetLinkedSensors(); + vector<SCA_IActuator*> linkedactuators = cont->GetLinkedActuators(); + + // disconnect the sensors and actuators + cont->UnlinkAllSensors(); + cont->UnlinkAllActuators(); + + // now relink each sensor + for (vector<SCA_ISensor*>::iterator its = linkedsensors.begin();!(its==linkedsensors.end());its++) + { + SCA_ISensor* oldsensor = (*its); + STR_String name = oldsensor->GetName(); + //find this name in the list + SCA_ISensor* newsensor = newobj->FindSensor(name); + + if (newsensor) + { + // relink this newsensor to the controller + m_logicmgr->RegisterToSensor(cont,newsensor); + } + else + { + // it can be linked somewhere in the hierarchy or... + for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin(); + !(git==m_logicHierarchicalGameObjects.end());++git) + { + newsensor = (*git)->FindSensor(name); + if (newsensor) + break; + } + + if (newsensor) + { + // relink this newsensor to the controller somewhere else within this + // hierarchy + m_logicmgr->RegisterToSensor(cont,newsensor); + } + else + { + // must be an external sensor, so... + m_logicmgr->RegisterToSensor(cont,oldsensor); + } + } + } + + // now relink each actuator + for (vector<SCA_IActuator*>::iterator ita = linkedactuators.begin();!(ita==linkedactuators.end());ita++) + { + SCA_IActuator* oldactuator = (*ita); + STR_String name = oldactuator->GetName(); + //find this name in the list + SCA_IActuator* newactuator = newobj->FindActuator(name); + if (newactuator) + { + // relink this newsensor to the controller + m_logicmgr->RegisterToActuator(cont,newactuator); + newactuator->SetUeberExecutePriority(m_ueberExecutionPriority); + } + else + { + // it can be linked somewhere in the hierarchy or... + for (vector<KX_GameObject*>::iterator git = m_logicHierarchicalGameObjects.begin(); + !(git==m_logicHierarchicalGameObjects.end());++git) + { + newactuator= (*git)->FindActuator(name); + if (newactuator) + break; + } + + if (newactuator) + { + // relink this actuator to the controller somewhere else within this + // hierarchy + m_logicmgr->RegisterToActuator(cont,newactuator); + newactuator->SetUeberExecutePriority(m_ueberExecutionPriority); + } + else + { + // must be an external actuator, so... + m_logicmgr->RegisterToActuator(cont,oldactuator); + } + } + } + } +} + + + +SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject, + class CValue* parentobject, + int lifespan) +{ + + m_logicHierarchicalGameObjects.clear(); + m_map_gameobject_to_replica.clear(); + + // todo: place a timebomb in the object, for temporarily objects :) + // lifespan of zero means 'this object lives forever' + KX_GameObject* originalobj = (KX_GameObject*) originalobject; + KX_GameObject* parentobj = (KX_GameObject*) parentobject; + + m_ueberExecutionPriority++; + + // lets create a replica + KX_GameObject* replica = (KX_GameObject*) AddNodeReplicaObject(NULL,originalobj); + + if (lifespan > 0) + { + // add a timebomb to this object + // for now, convert between so called frames and realtime + m_tempObjectList->Add(replica->AddRef()); + replica->SetProperty("::timebomb",new CFloatValue(lifespan*0.02)); + } + + // add to 'rootparent' list (this is the list of top hierarchy objects, updated each frame) + m_parentlist->Add(replica->AddRef()); + + // recurse replication into children nodes + + NodeList& children = originalobj->GetSGNode()->GetSGChildren(); + + replica->GetSGNode()->ClearSGChildren(); + for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit) + { + SG_Node* orgnode = (*childit); + SG_Node* childreplicanode = orgnode->GetSGReplica(); + replica->GetSGNode()->AddChild(childreplicanode); + } + + // relink any pointers as necessary, sort of a temporary solution + vector<KX_GameObject*>::iterator git; + for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git) + { + (*git)->Relink(&m_map_gameobject_to_replica); + } + + // now replicate logic + for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git) + { + (*git)->ReParentLogic(); + } + + // replicate crosslinks etc. between logic bricks + for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git) + { + ReplicateLogic((*git)); + } + + MT_Point3 newpos = ((KX_GameObject*) parentobject)->NodeGetWorldPosition(); + replica->NodeSetLocalPosition(newpos); + + MT_Matrix3x3 newori = ((KX_GameObject*) parentobject)->NodeGetWorldOrientation(); + replica->NodeSetLocalOrientation(newori); + + if (replica->GetPhysicsController()) + { + replica->GetPhysicsController()->setPosition(newpos); + replica->GetPhysicsController()->setOrientation(newori.getRotation()); + } + + // here we want to set the relative scale: the rootnode's scale will override all other + // scalings, so lets better prepare for it + + // get the rootnode's scale + MT_Vector3 newscale = parentobj->GetSGNode()->GetRootSGParent()->GetLocalScale(); + + // set the replica's relative scale with the rootnode's scale + replica->NodeSetRelativeScale(newscale); + + replica->GetSGNode()->UpdateWorldData(0); + + return replica; +} + + + +void KX_Scene::RemoveObject(class CValue* gameobj) +{ + KX_GameObject* newobj = (KX_GameObject*) gameobj; + + // first disconnect child from parent + SG_Node* node = newobj->GetSGNode(); + + if (node) + { + node->DisconnectFromParent(); + + // recursively destruct + node->Destruct(); + } +} + + + +void KX_Scene::DelayedRemoveObject(class CValue* gameobj) +{ + //KX_GameObject* newobj = (KX_GameObject*) gameobj; + if (!m_euthanasyobjects->SearchValue(gameobj)) + { + m_euthanasyobjects->Add(gameobj->AddRef()); + } +} + + + +void KX_Scene::NewRemoveObject(class CValue* gameobj) +{ + KX_GameObject* newobj = (KX_GameObject*) gameobj; + //SM_Object* sumoObj = newobj->GetSumoObject(); + //if (sumoObj) + //{ + // this->GetSumoScene()->remove(*sumoObj); + //} + // remove all sensors/controllers/actuators from logicsystem... + + SCA_SensorList& sensors = newobj->GetSensors(); + for (SCA_SensorList::iterator its = sensors.begin(); + !(its==sensors.end());its++) + { + m_logicmgr->RemoveSensor(*its); + } + + SCA_ControllerList& controllers = newobj->GetControllers(); + for (SCA_ControllerList::iterator itc = controllers.begin(); + !(itc==controllers.end());itc++) + { + (*itc)->UnlinkAllSensors(); + (*itc)->UnlinkAllActuators(); + } + + SCA_ActuatorList& actuators = newobj->GetActuators(); + for (SCA_ActuatorList::iterator ita = actuators.begin(); + !(ita==actuators.end());ita++) + { + m_logicmgr->RemoveDestroyedActuator(*ita); + } + + // now remove the timer properties from the time manager + int numprops = newobj->GetPropertyCount(); + + for (int i = 0; i < numprops; i++) + { + CValue* propval = newobj->GetProperty(i); + if (propval->GetProperty("timer")) + { + m_timemgr->RemoveTimeProperty(propval); + } + } + + newobj->RemoveMeshes(); + if (m_objectlist->RemoveValue(newobj)) + newobj->Release(); + if (m_tempObjectList->RemoveValue(newobj)) + newobj->Release(); + if (m_parentlist->RemoveValue(newobj)) + newobj->Release(); + if (m_euthanasyobjects->RemoveValue(newobj)) + newobj->Release(); +} + + + +void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj) +{ + KX_GameObject* newobj = (KX_GameObject*) gameobj; + newobj->RemoveMeshes(); + newobj->AddMesh((RAS_MeshObject*)meshobj); + newobj->Bucketize(); +} + + + +MT_CmMatrix4x4& KX_Scene::GetViewMatrix() +{ + MT_Scalar cammat[16]; + m_active_camera->GetWorldToCamera().getValue(cammat); + m_viewmat = cammat; + return m_viewmat; +} + + + +MT_CmMatrix4x4& KX_Scene::GetProjectionMatrix() +{ + return m_projectionmat; +} + + +KX_Camera* KX_Scene::FindCamera(KX_Camera* cam) +{ + set<KX_Camera*>::iterator it = m_cameras.begin(); + + while ( (it != m_cameras.end()) + && ((*it) != cam) ) { + it++; + } + + return ((it == m_cameras.end()) ? NULL : (*it)); +} + + +KX_Camera* KX_Scene::FindCamera(STR_String& name) +{ + set<KX_Camera*>::iterator it = m_cameras.begin(); + + while ( (it != m_cameras.end()) + && ((*it)->GetName() != name) ) { + it++; + } + + return ((it == m_cameras.end()) ? NULL : (*it)); +} + +void KX_Scene::AddCamera(KX_Camera* cam) +{ + m_cameras.insert(cam); +} + + +KX_Camera* KX_Scene::GetActiveCamera() +{ + // NULL if not defined + return m_active_camera; +} + + +void KX_Scene::SetActiveCamera(KX_Camera* cam) +{ + // only set if the cam is in the active list? Or add it otherwise? + if (!FindCamera(cam)){ + AddCamera(cam); + if (cam) std::cout << "Added cam " << cam->GetName() << std::endl; + } + + m_active_camera = cam; +} + + + +void KX_Scene::UpdateMeshTransformations() +{ + // do this incrementally in the future + for (int i = 0; i < m_objectlist->GetCount(); i++) + { + KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i); + gameobj->GetOpenGLMatrix(); + gameobj->UpdateNonDynas(); + } +} + +void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty) +{ + + // do this incrementally in the future + for (int i = 0; i < m_objectlist->GetCount(); i++) + { + KX_GameObject* gameobj = (KX_GameObject*)m_objectlist->GetValue(i); + + int nummeshes = gameobj->GetMeshCount(); + + for (int m=0;m<nummeshes;m++) + { + // this adds the vertices to the display list + (gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode(),rasty); + // Visibility/ non-visibility are marked + // elsewhere now. + gameobj->MarkVisible(); + } + } +} + +// logic stuff +void KX_Scene::LogicBeginFrame(double curtime,double deltatime) +{ + // have a look at temp objects ... + int lastobj = m_tempObjectList->GetCount() - 1; + + for (int i = lastobj; i >= 0; i--) + { + CValue* objval = m_tempObjectList->GetValue(i); + CFloatValue* propval = (CFloatValue*) objval->GetProperty("::timebomb"); + + if (propval) + { + float timeleft = propval->GetNumber() - deltatime; + + if (timeleft > 0) + { + propval->SetFloat(timeleft); + } + else + { + DelayedRemoveObject(objval); + // remove obj + } + } + else + { + // all object is the tempObjectList should have a clock + } + } + m_logicmgr->BeginFrame(curtime,deltatime); +} + + + +void KX_Scene::LogicUpdateFrame(double curtime,double deltatime) +{ + m_logicmgr->UpdateFrame(curtime,deltatime); +} + + + +void KX_Scene::LogicEndFrame() +{ + m_logicmgr->EndFrame(); + int numobj = m_euthanasyobjects->GetCount(); + + for (int i = numobj - 1; i >= 0; i--) + { + KX_GameObject* gameobj = (KX_GameObject*)m_euthanasyobjects->GetValue(i); + this->RemoveObject(gameobj); + } + + numobj = m_euthanasyobjects->GetCount(); + if (numobj != 0) + { + // huh? + int ii=0; + } + // numobj is 0 we hope +} + + + +/** + * UpdateParents: SceneGraph transformation update. + */ +void KX_Scene::UpdateParents(double curtime) +{ +// int numrootobjects = GetRootParentList()->GetCount(); + + for (int i=0; i<GetRootParentList()->GetCount(); i++) + { + KX_GameObject* parentobj = (KX_GameObject*)GetRootParentList()->GetValue(i); + parentobj->NodeUpdateGS(curtime,true); + } +} + + + +RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat) +{ + return m_bucketmanager->RAS_BucketManagerFindBucket(polymat); +} + + + +void KX_Scene::RenderBuckets(const MT_Transform & cameratransform, + class RAS_IRasterizer* rasty, + class RAS_IRenderTools* rendertools) +{ + m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools); +} + + + +void KX_Scene::UpdateObjectActivity(void) +{ + if (m_activity_culling) { + /* determine the activity criterium and set objects accordingly */ + int i=0; + + MT_Point3 camloc = GetActiveCamera()->NodeGetWorldPosition(); //GetCameraLocation(); + + for (i=0;i<GetObjectList()->GetCount();i++) + { + KX_GameObject* ob = (KX_GameObject*) GetObjectList()->GetValue(i); + + if (!ob->GetIgnoreActivityCulling()) { + /* Simple test: more than 10 away from the camera, count + * Manhattan distance. */ + MT_Point3 obpos = ob->NodeGetWorldPosition(); + + if ( (fabs(camloc[0] - obpos[0]) > m_activity_box_radius) + || (fabs(camloc[1] - obpos[1]) > m_activity_box_radius) + || (fabs(camloc[2] - obpos[2]) > m_activity_box_radius) ) + { + ob->Suspend(); + } else { + ob->Resume(); + } + } + } + } +} + +void KX_Scene::SetActivityCullingRadius(float f) +{ + if (f < 0.5) + f = 0.5; + m_activity_box_radius = f; +} + +NG_NetworkDeviceInterface* KX_Scene::GetNetworkDeviceInterface() +{ + return m_networkDeviceInterface; +} + +NG_NetworkScene* KX_Scene::GetNetworkScene() +{ + return m_networkScene; +} + +void KX_Scene::SetNetworkDeviceInterface(NG_NetworkDeviceInterface* newInterface) +{ + m_networkDeviceInterface = newInterface; +} + +void KX_Scene::SetNetworkScene(NG_NetworkScene *newScene) +{ + m_networkScene = newScene; +} + + +void KX_Scene::SetGravity(const MT_Vector3& gravity) +{ + GetPhysicsEnvironment()->setGravity(gravity[0],gravity[1],gravity[2]); +} diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h new file mode 100644 index 00000000000..818368561e6 --- /dev/null +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -0,0 +1,480 @@ +/** + * $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_SCENE_H +#define __KX_SCENE_H + + +#include "KX_PhysicsEngineEnums.h" + +#include "MT_CmMatrix4x4.h" + +#include <vector> +#include <set> + +#include "GEN_Map.h" +#include "GEN_HashedPtr.h" +#include "SG_IObject.h" +#include "SCA_IScene.h" +#include "MT_Transform.h" +#include "SND_Scene.h" +#include "RAS_FramingManager.h" +#include "RAS_Rect.h" + +/** + * @section Forward declarations + */ +struct SM_MaterialProps; +struct SM_ShapeProps; + +class CListValue; +class RAS_BucketManager; +class KX_Camera; +class SCA_LogicManager; +class SCA_KeyboardManager; +class SCA_TimeEventManager; +class SCA_MouseManager; +class KX_WorldInfo; +class SND_Scene; +class SND_IAudioDevice; +class NG_NetworkDeviceInterface; +class NG_NetworkScene; +class SG_Node; +class KX_Camera; +class GEN_HashedPtr; +class KX_GameObject; +class SCA_ISystem; +class SCA_IInputDevice; +class RAS_BucketManager; +class RAS_MaterialBucket; +class RAS_IPolyMaterial; +class RAS_IRasterizer; +class RAS_IRenderTools; +class CValue; +class SG_IObject; + +/** + * The KX_Scene holds all data for an independent scene. It relates + * KX_Objects to the specific objects in the modules. + * */ +class KX_Scene : public SCA_IScene +{ + RAS_BucketManager* m_bucketmanager; + CListValue* m_tempObjectList; + + /** + * The list of objects which have been removed during the + * course of one frame. They are actually destroyed in + * LogicEndFrame() via a call to RemoveObject(). + */ + CListValue* m_euthanasyobjects; + + CListValue* m_objectlist; + CListValue* m_parentlist; // all 'root' parents + CListValue* m_lightlist; + + /** + * The set of cameras for this scene + */ + set<class KX_Camera*> m_cameras; + + /** + * Various SCA managers used by the scene + */ + SCA_LogicManager* m_logicmgr; + SCA_KeyboardManager* m_keyboardmgr; + SCA_MouseManager* m_mousemgr; + SCA_TimeEventManager* m_timemgr; + + /** + * physics engine abstraction + */ + + e_PhysicsEngine m_physicsEngine; + class PHY_IPhysicsEnvironment* m_physicsEnvironment; + + /** + * Does this scene clear the z-buffer? + */ + bool m_isclearingZbuffer; + + /** + * The name of the scene + */ + STR_String m_sceneName; + + /** + * stores the worldsettings for a scene + */ + KX_WorldInfo* m_worldinfo; + + /** + * @section Different scenes, linked to ketsji scene + */ + + + /** + * Sound scenes + */ + SND_Scene* m_soundScene; + SND_IAudioDevice* m_adi; + + /** + * Network scene. + */ + NG_NetworkDeviceInterface* m_networkDeviceInterface; + NG_NetworkScene* m_networkScene; + + /** + * A temoprary variable used to parent objects together on + * replication. Don't get confused by the name it is not + * the scene's root node! + */ + SG_Node* m_rootnode; + + /** + * The active camera for the scene + */ + KX_Camera* m_active_camera; + + /** + * The projection and view matrices of this scene + * The projection matrix is computed externally by KX_Engine + * The view mat is stored as a side effect of GetViewMatrix() + * and is totally unnessary. + */ + MT_CmMatrix4x4 m_projectionmat; + MT_CmMatrix4x4 m_viewmat; + + /** Desired canvas width set at design time. */ + unsigned int m_canvasDesignWidth; + /** Desired canvas height set at design time. */ + unsigned int m_canvasDesignHeight; + + /** + * Another temporary variable outstaying its welcome + * used in AddReplicaObject to map game objects to their + * replicas so pointers can be updated. + */ + GEN_Map <GEN_HashedPtr, void*> m_map_gameobject_to_replica; + + /** + * Another temporary variable outstaying its welcome + * used in AddReplicaObject to keep a record of all added + * objects. Logic can only be updated when all objects + * have been updated. This stores a list of the new objects. + */ + std::vector<KX_GameObject*> m_logicHierarchicalGameObjects; + + /** + * Pointer to system variable passed in in constructor + * only used in constructor so we do not need to keep it + * around in this class. + */ + + SCA_ISystem* m_kxsystem; + + /** + * The execution priority of replicated object actuators? + */ + int m_ueberExecutionPriority; + + /** + * Activity 'bubble' settings : + * Suspend (freeze) the entire scene. + */ + bool m_suspend; + + /** + * Radius in Manhattan distance of the box for activity culling. + */ + float m_activity_box_radius; + + /** + * Toggle to enable or disable activity culling. + */ + bool m_activity_culling; + + /** + * The framing settings used by this scene + */ + + RAS_FrameSettings m_frame_settings; + + /** + * This scenes viewport into the game engine + * canvas.Maintained externally, initially [0,0] -> [0,0] + */ + RAS_Rect m_viewport; + +public: + KX_Scene(class SCA_IInputDevice* keyboarddevice, + class SCA_IInputDevice* mousedevice, + class NG_NetworkDeviceInterface* ndi, + class SND_IAudioDevice* adi, + const STR_String& scenename ); + + virtual + ~KX_Scene(); + + RAS_BucketManager* GetBucketManager(); + RAS_MaterialBucket* FindBucket(RAS_IPolyMaterial* polymat); + void RenderBuckets(const MT_Transform& cameratransform, + RAS_IRasterizer* rasty, + RAS_IRenderTools* rendertools); + /** + * Update all transforms according to the scenegraph. + */ + void UpdateParents(double curtime); + SCA_IObject* AddReplicaObject(CValue* gameobj, + CValue* locationobj, + int lifespan=0); + KX_GameObject* AddNodeReplicaObject(SG_IObject* node, + CValue* gameobj); + void RemoveNodeDestructObject(SG_IObject* node, + CValue* gameobj); + void RemoveObject(CValue* gameobj); + void DelayedRemoveObject(CValue* gameobj); + void NewRemoveObject(CValue* gameobj); + void ReplaceMesh(CValue* gameobj, + void* meshobj); + /** + * @section Logic stuff + * Initiate an update of the logic system. + */ + void LogicBeginFrame(double curtime, + double deltatime); + void LogicUpdateFrame(double curtime, + double deltatime); + + void + LogicEndFrame( + ); + + CListValue* + GetObjectList( + ); + + CListValue* + GetRootParentList( + ); + + CListValue* + GetLightList( + ); + + SCA_LogicManager* + GetLogicManager( + ); + + SCA_TimeEventManager* + GetTimeEventManager( + ); + + + /** Find a camera in the scene by pointer. */ + KX_Camera* + FindCamera( + KX_Camera* + ); + + /** Find a scene in the scene by name. */ + KX_Camera* + FindCamera( + STR_String& + ); + + /** Add a camera to this scene. */ + void + AddCamera( + KX_Camera* + ); + + /** Find the currently active camera. */ + KX_Camera* + GetActiveCamera( + ); + + /** + * Set this camera to be the active camera in the scene. If the + * camera is not present in the camera list, it will be added + */ + + void + SetActiveCamera( + class KX_Camera* + ); + + /** Return the viewmatrix as used by the last frame. */ + MT_CmMatrix4x4& + GetViewMatrix( + ); + + /** + * Return the projectionmatrix as used by the last frame. This is + * set by hand :) + */ + MT_CmMatrix4x4& + GetProjectionMatrix( + ); + + /** Sets the projection matrix. */ + void + SetProjectionMatrix( + MT_CmMatrix4x4& pmat + ); + + /** + * Activates new desired canvas width set at design time. + * @param width The new desired width. + */ + void + SetCanvasDesignWidth( + unsigned int width + ); + /** + * Activates new desired canvas height set at design time. + * @param width The new desired height. + */ + void + SetCanvasDesignHeight( + unsigned int height + ); + /** + * Returns the current desired canvas width set at design time. + * @return The desired width. + */ + unsigned int + GetCanvasDesignWidth( + void + ) const; + + /** + * Returns the current desired canvas height set at design time. + * @return The desired height. + */ + unsigned int + GetCanvasDesignHeight( + void + ) const; + + /** + * Set the framing options for this scene + */ + + void + SetFramingType( + RAS_FrameSettings & frame_settings + ); + + /** + * Return a const reference to the framing + * type set by the above call. + * The contents are not guarenteed to be sensible + * if you don't call the above function. + */ + + const + RAS_FrameSettings & + GetFramingType( + ) const; + + /** + * Store the current scene's viewport on the + * game engine canvas. + */ + void SetSceneViewport(const RAS_Rect &viewport); + + /** + * Get the current scene's viewport on the + * game engine canvas. This maintained + * externally in KX_GameEngine + */ + const RAS_Rect& GetSceneViewport() const; + + /** + * @section Accessors to different scenes of this scene + */ + void SetNetworkDeviceInterface(NG_NetworkDeviceInterface* newInterface); + void SetNetworkScene(NG_NetworkScene *newScene); + void SetWorldInfo(class KX_WorldInfo* wi); + KX_WorldInfo* GetWorldInfo(); + void CalculateVisibleMeshes(RAS_IRasterizer* rasty); + void UpdateMeshTransformations(); + KX_Camera* GetpCamera(); + SND_Scene* GetSoundScene(); + NG_NetworkDeviceInterface* GetNetworkDeviceInterface(); + NG_NetworkScene* GetNetworkScene(); + + /** + * Replicate the logic bricks associated to this object. + */ + + void ReplicateLogic(class KX_GameObject* newobj); + static SG_Callbacks m_callbacks; + + const STR_String& GetName(); + + // Suspend the entire scene. + void Suspend(); + + // Resume a suspended scene. + void Resume(); + + // Update the activity box settings for objects in this scene, if needed. + void UpdateObjectActivity(void); + + // Enable/disable activity culling. + void SetActivityCulling(bool b); + + // Set the radius of the activity culling box. + void SetActivityCullingRadius(float f); + bool IsSuspended(); + bool IsClearingZBuffer(); + void EnableZBufferClearing(bool isclearingZbuffer); + + class PHY_IPhysicsEnvironment* GetPhysicsEnvironment() + { + return m_physicsEnvironment; + } + + void SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* physEnv) + { + m_physicsEnvironment = physEnv; + } + + void SetGravity(const MT_Vector3& gravity); +}; + +typedef std::vector<KX_Scene*> KX_SceneList; + +#endif //__KX_SCENE_H + diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp new file mode 100644 index 00000000000..7cba1a6ac1e --- /dev/null +++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp @@ -0,0 +1,354 @@ +/** +* Set scene/camera stuff +* +* $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_IActuator.h" +#include "KX_SceneActuator.h" +#include <iostream> +#include "KX_Scene.h" +#include "KX_Camera.h" +#include "KX_KetsjiEngine.h" + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj, + int mode, + KX_Scene *scene, + KX_KetsjiEngine* ketsjiEngine, + const STR_String& nextSceneName, + KX_Camera* camera, + PyTypeObject* T) + : SCA_IActuator(gameobj, T) +{ + m_mode = mode; + m_scene = scene; + m_KetsjiEngine=ketsjiEngine; + m_camera = camera; + m_nextSceneName = nextSceneName; +} /* End of constructor */ + + + +KX_SceneActuator::~KX_SceneActuator() +{ + // there's nothing to be done here, really.... +} /* end of destructor */ + + + +CValue* KX_SceneActuator::GetReplica() +{ + KX_SceneActuator* replica = new KX_SceneActuator(*this); + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + + return replica; +} + + + +bool KX_SceneActuator::Update(double curtime,double deltatime) +{ + bool result = false; + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) + return false; // do nothing on negative events + + switch (m_mode) + { + case KX_SCENE_RESTART: + { + m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_scene->GetName()); + break; + } + case KX_SCENE_SET_SCENE: + { + m_KetsjiEngine->ReplaceScene(m_scene->GetName(),m_nextSceneName); + break; + } + case KX_SCENE_ADD_FRONT_SCENE: + { + bool overlay=true; + m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay); + break; + } + case KX_SCENE_ADD_BACK_SCENE: + { + bool overlay=false; + m_KetsjiEngine->ConvertAndAddScene(m_nextSceneName,overlay); + break; + } + case KX_SCENE_REMOVE_SCENE: + { + m_KetsjiEngine->RemoveScene(m_nextSceneName); + break; + } + case KX_SCENE_SUSPEND: + { + m_KetsjiEngine->SuspendScene(m_nextSceneName); + break; + } + case KX_SCENE_RESUME: + { + m_KetsjiEngine->ResumeScene(m_nextSceneName); + break; + } + case KX_SCENE_SET_CAMERA: + if (m_camera) + { + m_scene->SetActiveCamera(m_camera); + } + break; + default: + ; /* do nothing? this is an internal error !!! */ + } + + return false; +} + + + +/* returns a camera if the name is valid */ +KX_Camera* KX_SceneActuator::FindCamera(char *camName) +{ + KX_SceneList* sl = m_KetsjiEngine->CurrentScenes(); + STR_String name = STR_String(camName); + KX_SceneList::iterator it = sl->begin(); + KX_Camera* cam = NULL; + + while ((it != sl->end()) && (!cam)) + { + cam = (*it)->FindCamera(name); + it++; + } + + return cam; +} + + + +KX_Scene* KX_SceneActuator::FindScene(char * sceneName) +{ + return m_KetsjiEngine->FindScene(sceneName); +} + + + + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_SceneActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_SceneActuator", + sizeof(KX_SceneActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + + + +PyParentObject KX_SceneActuator::Parents[] = +{ + &KX_SceneActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + + +PyMethodDef KX_SceneActuator::Methods[] = +{ + {"setUseRestart", (PyCFunction) KX_SceneActuator::sPySetUseRestart, METH_VARARGS, SetUseRestart_doc}, + {"setScene", (PyCFunction) KX_SceneActuator::sPySetScene, METH_VARARGS, SetScene_doc}, + {"setCamera", (PyCFunction) KX_SceneActuator::sPySetCamera, METH_VARARGS, SetCamera_doc}, + {"getUseRestart", (PyCFunction) KX_SceneActuator::sPyGetUseRestart, METH_VARARGS, GetUseRestart_doc}, + {"getScene", (PyCFunction) KX_SceneActuator::sPyGetScene, METH_VARARGS, GetScene_doc}, + {"getCamera", (PyCFunction) KX_SceneActuator::sPyGetCamera, METH_VARARGS, GetCamera_doc}, + {NULL,NULL} //Sentinel +}; + + + +PyObject* KX_SceneActuator::_getattr(char* attr) +{ + _getattr_up(SCA_IActuator); +} + + + +/* 2. setUseRestart--------------------------------------------------------- */ +char KX_SceneActuator::SetUseRestart_doc[] = +"setUseRestart(flag)\n" +"\t- flag: 0 or 1.\n" +"\tSet flag to 1 to restart the scene.\n" ; +PyObject* KX_SceneActuator::PySetUseRestart(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int boolArg; + + if (!PyArg_ParseTuple(args, "i", &boolArg)) + { + return NULL; + } + + if (boolArg == KX_TRUE) + { + m_restart = true; + } + else if (boolArg == KX_FALSE) + { + m_restart = false; + } + else + { + ; /* internal error */ + } + + Py_Return; +} + + + +/* 3. getUseRestart: */ +char KX_SceneActuator::GetUseRestart_doc[] = +"getUseRestart()\n" +"\tReturn whether the scene will be restarted.\n" ; +PyObject* KX_SceneActuator::PyGetUseRestart(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return PyInt_FromLong(!(m_restart == 0)); +} + + + +/* 4. set scene------------------------------------------------------------- */ +char KX_SceneActuator::SetScene_doc[] = +"setScene(scene)\n" +"\t- scene: string\n" +"\tSet the name of scene the actuator will switch to.\n" ; +PyObject* KX_SceneActuator::PySetScene(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + /* one argument: a scene, ignore the rest */ + char *scene_name; + + if(!PyArg_ParseTuple(args, "s", &scene_name)) + { + return NULL; + } + + if (m_KetsjiEngine->FindScene(scene_name)) + { + /* Scene switch is done by name. */ + m_nextSceneName = scene_name; + } + + Py_Return; +} + + + +/* 5. getScene: */ +char KX_SceneActuator::GetScene_doc[] = +"getScene()\n" +"\tReturn the name of the scene the actuator wants to switch to.\n" ; +PyObject* KX_SceneActuator::PyGetScene(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return PyString_FromString(m_nextSceneName); +} + + + +/* 6. set camera------------------------------------------------------------ */ +char KX_SceneActuator::SetCamera_doc[] = +"setCamera(camera)\n" +"\t- camera: string\n" +"\tSet the camera to switch to.\n" ; +PyObject* KX_SceneActuator::PySetCamera(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + /* one argument: a scene, ignore the rest */ + char *camName; + KX_Camera *camOb; + + if(!PyArg_ParseTuple(args, "s", &camName)) + { + return NULL; + } + + camOb = FindCamera(camName); + if (camOb) m_camera = camOb; + + Py_Return; +} + + + +/* 7. getCamera: */ +char KX_SceneActuator::GetCamera_doc[] = +"getCamera()\n" +"\tReturn the name of the camera to switch to.\n" ; +PyObject* KX_SceneActuator::PyGetCamera(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + return PyString_FromString(m_camera->GetName()); +} +/* eof */ diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h new file mode 100644 index 00000000000..a9f3751322e --- /dev/null +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -0,0 +1,115 @@ + +// +// Add object to the game world on action of this actuator +// +// $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_SCENEACTUATOR +#define __KX_SCENEACTUATOR + +#include "SCA_IActuator.h" + +class KX_SceneActuator : public SCA_IActuator +{ + Py_Header; + + int m_mode; + // (restart) has become a toggle internally... not in the interface though + bool m_restart; + // (set Scene) Scene + /** The current scene. */ + class KX_Scene* m_scene; + class KX_KetsjiEngine* m_KetsjiEngine; + /** The scene to switch to. */ + STR_String m_nextSceneName; + + // (Set Camera) Object + class KX_Camera* m_camera; + + /** Is this a valid scene? */ + class KX_Scene* FindScene(char* sceneName); + /** Is this a valid camera? */ + class KX_Camera* FindCamera(char* cameraName); + + public: + enum SCA_SceneActuatorMode + { + KX_SCENE_NODEF = 0, + KX_SCENE_RESTART, + KX_SCENE_SET_SCENE, + KX_SCENE_SET_CAMERA, + KX_SCENE_ADD_FRONT_SCENE, + KX_SCENE_ADD_BACK_SCENE, + KX_SCENE_REMOVE_SCENE, + KX_SCENE_SUSPEND, + KX_SCENE_RESUME, + KX_SCENE_MAX + }; + + KX_SceneActuator(SCA_IObject* gameobj, + int mode, + KX_Scene* scene, + KX_KetsjiEngine* ketsjiEngine, + const STR_String& nextSceneName, + KX_Camera* camera, + PyTypeObject* T=&Type); + virtual ~KX_SceneActuator(); + + virtual CValue* GetReplica(); + + virtual bool Update(double curtime,double deltatime); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + + /* 1. set */ + /* Removed */ + + /* 2. setUseRestart: */ + KX_PYMETHOD_DOC(KX_SceneActuator,SetUseRestart); + /* 3. getUseRestart: */ + KX_PYMETHOD_DOC(KX_SceneActuator,GetUseRestart); + /* 4. setScene: */ + KX_PYMETHOD_DOC(KX_SceneActuator,SetScene); + /* 5. getScene: */ + KX_PYMETHOD_DOC(KX_SceneActuator,GetScene); + /* 6. setCamera: */ + KX_PYMETHOD_DOC(KX_SceneActuator,SetCamera); + /* 7. getCamera: */ + KX_PYMETHOD_DOC(KX_SceneActuator,GetCamera); + +}; /* end of class KXSceneActuator */ + +#endif diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp new file mode 100644 index 00000000000..b36ff5f2c09 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp @@ -0,0 +1,466 @@ +/** + * KX_SoundActuator.cpp + * + * $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_SoundActuator.h" +#include "SND_SoundObject.h" +#include "KX_GameObject.h" +#include "SND_SoundObject.h" +#include "SND_Scene.h" // needed for replication +#include <iostream> + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ +KX_SoundActuator::KX_SoundActuator(SCA_IObject* gameobj, + SND_SoundObject* sndobj, + SND_Scene* sndscene, + KX_SOUNDACT_TYPE type, + short start, + short end, + PyTypeObject* T) + : SCA_IActuator(gameobj,T) +{ + m_soundObject = sndobj; + m_soundScene = sndscene; + m_type = type; + m_lastEvent = true; + m_isplaying = false; + m_startFrame = start; + m_endFrame = end; + m_pino = false; +} + + + +KX_SoundActuator::~KX_SoundActuator() +{ + //m_soundScene->RemoveObject(this->m_soundObject); + //(this->m_soundObject)->DeleteWhenFinished(); + m_soundScene->RemoveActiveObject(m_soundObject); +// m_soundScene->DeleteObjectWhenFinished(m_soundObject); + m_soundScene->DeleteObject(m_soundObject); +} + + + +CValue* KX_SoundActuator::GetReplica() +{ + KX_SoundActuator* replica = new KX_SoundActuator(*this); + replica->ProcessReplica(); + SND_SoundObject* soundobj = new SND_SoundObject(*m_soundObject); + replica->setSoundObject(soundobj); + m_soundScene->AddObject(soundobj); + + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; +}; + + + +bool KX_SoundActuator::Update(double curtime,double deltatime) +{ + bool result = false; + + // do nothing on negative events, otherwise sounds are played twice! + bool bNegativeEvent = IsNegativeEvent(); + + RemoveAllEvents(); + + if (m_pino) + { + bNegativeEvent = true; + m_pino = false; + } + + if (bNegativeEvent) + { + // here must be a check if it is still playing + m_isplaying = false; + + switch (m_type) + { + case KX_SOUNDACT_PLAYSTOP: + case KX_SOUNDACT_LOOPSTOP: + case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP: + { + m_soundScene->RemoveActiveObject(m_soundObject); + break; + } + case KX_SOUNDACT_PLAYEND: + { + m_soundObject->SetPlaystate(SND_MUST_STOP_WHEN_FINISHED); + break; + } + default: + // implement me !! + break; + } + } + else + { + if (m_soundObject && !m_isplaying) + { + switch (m_type) + { + case KX_SOUNDACT_LOOPBIDIRECTIONAL: + case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP: + { + m_soundObject->SetLoopMode(SND_LOOP_BIDIRECTIONAL); + m_soundScene->AddActiveObject(m_soundObject, curtime); + m_isplaying = true; + result = true; + break; + } + case KX_SOUNDACT_LOOPEND: + case KX_SOUNDACT_LOOPSTOP: + { + m_soundObject->SetLoopMode(SND_LOOP_NORMAL); + m_soundScene->AddActiveObject(m_soundObject, curtime); + m_isplaying = true; + result = true; + break; + } + case KX_SOUNDACT_PLAYSTOP: + case KX_SOUNDACT_PLAYEND: + { + m_soundObject->SetLoopMode(SND_LOOP_OFF); + m_soundScene->AddActiveObject(m_soundObject, curtime); + m_isplaying = true; + result = true; + break; + } + default: + // implement me !! + break; + } + } + } + + if (m_isplaying) + { + m_soundObject->SetPosition(((KX_GameObject*)this->GetParent())->NodeGetWorldPosition()); + m_soundObject->SetVelocity(((KX_GameObject*)this->GetParent())->GetLinearVelocity()); + m_soundObject->SetOrientation(((KX_GameObject*)this->GetParent())->NodeGetWorldOrientation()); + result = true; + } + else + { + result = false; + } + + if (result && (m_soundObject->IsLifeSpanOver(curtime)) && ((m_type == KX_SOUNDACT_PLAYEND) || (m_type == KX_SOUNDACT_PLAYSTOP))) + { + m_pino = true; + } + + return result; +} + + + +void KX_SoundActuator::setSoundObject(class SND_SoundObject* soundobject) +{ + m_soundObject = soundobject; +} + + + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + + + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_SoundActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_SoundActuator", + sizeof(KX_SoundActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + + + +PyParentObject KX_SoundActuator::Parents[] = { + &KX_SoundActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + + +PyMethodDef KX_SoundActuator::Methods[] = { + {"setFilename", (PyCFunction) KX_SoundActuator::sPySetFilename, METH_VARARGS,NULL}, + {"getFilename", (PyCFunction) KX_SoundActuator::sPyGetFilename, METH_VARARGS,NULL}, + {"startSound",(PyCFunction) KX_SoundActuator::sPyStartSound,METH_VARARGS,NULL}, + {"pauseSound",(PyCFunction) KX_SoundActuator::sPyPauseSound,METH_VARARGS,NULL}, + {"stopSound",(PyCFunction) KX_SoundActuator::sPyStopSound,METH_VARARGS,NULL}, + {"setGain",(PyCFunction) KX_SoundActuator::sPySetGain,METH_VARARGS,NULL}, + {"getGain",(PyCFunction) KX_SoundActuator::sPyGetGain,METH_VARARGS,NULL}, + {"setPitch",(PyCFunction) KX_SoundActuator::sPySetPitch,METH_VARARGS,NULL}, + {"getPitch",(PyCFunction) KX_SoundActuator::sPyGetPitch,METH_VARARGS,NULL}, + {"setRollOffFactor",(PyCFunction) KX_SoundActuator::sPySetRollOffFactor,METH_VARARGS,NULL}, + {"getRollOffFactor",(PyCFunction) KX_SoundActuator::sPyGetRollOffFactor,METH_VARARGS,NULL}, + {"setLooping",(PyCFunction) KX_SoundActuator::sPySetLooping,METH_VARARGS,NULL}, + {"getLooping",(PyCFunction) KX_SoundActuator::sPyGetLooping,METH_VARARGS,NULL}, + {"setPosition",(PyCFunction) KX_SoundActuator::sPySetPosition,METH_VARARGS,NULL}, + {"setVelocity",(PyCFunction) KX_SoundActuator::sPySetVelocity,METH_VARARGS,NULL}, + {"setOrientation",(PyCFunction) KX_SoundActuator::sPySetOrientation,METH_VARARGS,NULL}, + {NULL,NULL,NULL,NULL} //Sentinel +}; + + + +PyObject* KX_SoundActuator::_getattr(char* attr) +{ + _getattr_up(SCA_IActuator); +} + + + +PyObject* KX_SoundActuator::PySetFilename(PyObject* self, PyObject* args, PyObject* kwds) +{ + char *soundName = NULL; + void *soundPointer = NULL; + + if (!PyArg_ParseTuple(args, "s", &soundName)) + return NULL; + + Py_Return; +} + + + +PyObject* KX_SoundActuator::PyGetFilename(PyObject* self, PyObject* args, PyObject* kwds) +{ + STR_String objectname = m_soundObject->GetObjectName(); + char* name = objectname.Ptr(); + + if (!name) { + Py_Return; /* internal error */ + } else + return PyString_FromString(name); +} + + + +PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObject* kwds) +{ + m_soundObject->StartSound(); + Py_Return; +} + + + +PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObject* kwds) +{ + m_soundObject->PauseSound(); + Py_Return; +} + + + +PyObject* KX_SoundActuator::PyStopSound(PyObject* self, PyObject* args, PyObject* kwds) +{ + m_soundObject->StopSound(); + Py_Return; +} + + + +PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwds) +{ + float gain = 1.0; + if (!PyArg_ParseTuple(args, "f", &gain)) + return NULL; + + m_soundObject->SetGain(gain); + + Py_Return; +} + + + +PyObject* KX_SoundActuator::PyGetGain(PyObject* self, PyObject* args, PyObject* kwds) +{ + float gain = m_soundObject->GetGain(); + PyObject* result = PyFloat_FromDouble(gain); + + return result; +} + + + +PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject* kwds) +{ + float pitch = 1.0; + if (!PyArg_ParseTuple(args, "f", &pitch)) + return NULL; + + m_soundObject->SetPitch(pitch); + + Py_Return; +} + + + +PyObject* KX_SoundActuator::PyGetPitch(PyObject* self, PyObject* args, PyObject* kwds) +{ + float pitch = m_soundObject->GetPitch(); + PyObject* result = PyFloat_FromDouble(pitch); + + return result; +} + + + +PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds) +{ + float rollofffactor = 1.0; + if (!PyArg_ParseTuple(args, "f", &rollofffactor)) + return NULL; + + m_soundObject->SetRollOffFactor(rollofffactor); + + Py_Return; +} + + + +PyObject* KX_SoundActuator::PyGetRollOffFactor(PyObject* self, PyObject* args, PyObject* kwds) +{ + float rollofffactor = m_soundObject->GetRollOffFactor(); + PyObject* result = PyFloat_FromDouble(rollofffactor); + + return result; +} + + + +PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObject* kwds) +{ + bool looping = 1; + if (!PyArg_ParseTuple(args, "i", &looping)) + return NULL; + + m_soundObject->SetLoopMode(looping); + + Py_Return; +} + + + +PyObject* KX_SoundActuator::PyGetLooping(PyObject* self, PyObject* args, PyObject* kwds) +{ + int looping = m_soundObject->GetLoopMode(); + PyObject* result = PyInt_FromLong(looping); + + return result; +} + + + +PyObject* KX_SoundActuator::PySetPosition(PyObject* self, PyObject* args, PyObject* kwds) +{ + MT_Point3 pos; + pos[0] = 0.0; + pos[1] = 0.0; + pos[2] = 0.0; + + if (!PyArg_ParseTuple(args, "fff", &pos[0], &pos[1], &pos[2])) + return NULL; + + m_soundObject->SetPosition(pos); + + Py_Return; +} + + + +PyObject* KX_SoundActuator::PySetVelocity(PyObject* self, PyObject* args, PyObject* kwds) +{ + MT_Vector3 vel; + vel[0] = 0.0; + vel[1] = 0.0; + vel[2] = 0.0; + + if (!PyArg_ParseTuple(args, "fff", &vel[0], &vel[1], &vel[2])) + return NULL; + + m_soundObject->SetVelocity(vel); + + Py_Return; +} + + + +PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyObject* kwds) +{ + MT_Matrix3x3 ori; + ori[0][0] = 1.0; + ori[0][1] = 0.0; + ori[0][2] = 0.0; + ori[1][0] = 0.0; + ori[1][1] = 1.0; + ori[1][2] = 0.0; + ori[2][0] = 0.0; + ori[2][1] = 0.0; + ori[2][2] = 1.0; + + if (!PyArg_ParseTuple(args, "fffffffff", &ori[0][0], &ori[0][1], &ori[0][2], &ori[1][0], &ori[1][1], &ori[1][2], &ori[2][0], &ori[2][1], &ori[2][2])) + return NULL; + + m_soundObject->SetOrientation(ori); + + Py_Return; +} + + + diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h new file mode 100644 index 00000000000..1ebc3ef5250 --- /dev/null +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -0,0 +1,106 @@ +/** + * KX_SoundActuator.h + * + * $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_SOUNDACTUATOR +#define __KX_SOUNDACTUATOR + +#include "SCA_IActuator.h" + +class KX_SoundActuator : public SCA_IActuator +{ + Py_Header; + bool m_lastEvent; + bool m_isplaying; + /* just some handles to the audio-data... */ + class SND_SoundObject* m_soundObject; + class SND_Scene* m_soundScene; + short m_startFrame; + short m_endFrame; + bool m_pino; +public: + + enum KX_SOUNDACT_TYPE + { + KX_SOUNDACT_NODEF = 0, + KX_SOUNDACT_PLAYSTOP, + KX_SOUNDACT_PLAYEND, + KX_SOUNDACT_LOOPSTOP, + KX_SOUNDACT_LOOPEND, + KX_SOUNDACT_LOOPBIDIRECTIONAL, + KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP, + KX_SOUNDACT_MAX + }; + + KX_SOUNDACT_TYPE m_type; + + KX_SoundActuator(SCA_IObject* gameobj, + class SND_SoundObject* sndobj, + class SND_Scene* sndscene, + KX_SOUNDACT_TYPE type, + short start, + short end, + PyTypeObject* T=&Type); + + ~KX_SoundActuator(); + + void setSoundObject(class SND_SoundObject* soundobject); + bool Update(double curtime,double deltatime); + + CValue* GetReplica(); + + /* -------------------------------------------------------------------- */ + /* Python interface --------------------------------------------------- */ + /* -------------------------------------------------------------------- */ + + PyObject* _getattr(char *attr); + + KX_PYMETHOD(KX_SoundActuator,SetFilename); + KX_PYMETHOD(KX_SoundActuator,GetFilename); + KX_PYMETHOD(KX_SoundActuator,StartSound); + KX_PYMETHOD(KX_SoundActuator,PauseSound); + KX_PYMETHOD(KX_SoundActuator,StopSound); + KX_PYMETHOD(KX_SoundActuator,SetGain); + KX_PYMETHOD(KX_SoundActuator,GetGain); + KX_PYMETHOD(KX_SoundActuator,SetPitch); + KX_PYMETHOD(KX_SoundActuator,GetPitch); + KX_PYMETHOD(KX_SoundActuator,SetRollOffFactor); + KX_PYMETHOD(KX_SoundActuator,GetRollOffFactor); + KX_PYMETHOD(KX_SoundActuator,SetLooping); + KX_PYMETHOD(KX_SoundActuator,GetLooping); + KX_PYMETHOD(KX_SoundActuator,SetPosition); + KX_PYMETHOD(KX_SoundActuator,SetVelocity); + KX_PYMETHOD(KX_SoundActuator,SetOrientation); +}; +#endif //__KX_SOUNDACTUATOR + diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp new file mode 100644 index 00000000000..8b5b9a5d10b --- /dev/null +++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.cpp @@ -0,0 +1,204 @@ +#pragma warning (disable : 4786) + +#include "KX_SumoPhysicsController.h" +#include "SG_Spatial.h" +#include "SM_Scene.h" +#include "KX_GameObject.h" +#include "KX_MotionState.h" + + + +void KX_SumoPhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) +{ + SumoPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]); +} +void KX_SumoPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local) +{ + SumoPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local); + +} +void KX_SumoPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local) +{ + double oldmat[12]; + drot.getValue(oldmat); + float newmat[9]; + float *m = &newmat[0]; + double *orgm = &oldmat[0]; + + *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; + *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; + *m++ = *orgm++;*m++ = *orgm++;*m++ = *orgm++;orgm++; + + SumoPhysicsController::RelativeRotate(newmat,local); +} + +void KX_SumoPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local) +{ + SumoPhysicsController::SetLinearVelocity(lin_vel[0],lin_vel[1],lin_vel[2],local); + +} + +void KX_SumoPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local) +{ + SumoPhysicsController::SetAngularVelocity(ang_vel[0],ang_vel[1],ang_vel[2],local); +} + +MT_Vector3 KX_SumoPhysicsController::GetVelocity(const MT_Point3& pos) +{ + + float linvel[3]; + SumoPhysicsController::GetVelocity(pos[0],pos[1],pos[2],linvel[0],linvel[1],linvel[2]); + + return MT_Vector3 (linvel); +} + +MT_Vector3 KX_SumoPhysicsController::GetLinearVelocity() +{ + return GetVelocity(MT_Point3(0,0,0)); + +} +void KX_SumoPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local) +{ + SumoPhysicsController::ApplyTorque(torque[0],torque[1],torque[2],local); + +} + +void KX_SumoPhysicsController::ApplyForce(const MT_Vector3& force,bool local) +{ + SumoPhysicsController::ApplyForce(force[0],force[1],force[2],local); +} + +bool KX_SumoPhysicsController::Update(double time) +{ + return SynchronizeMotionStates(time); + +} + +void KX_SumoPhysicsController::SetSimulatedTime(double time) +{ + +} + +void KX_SumoPhysicsController::SetSumoTransform(bool nondynaonly) +{ + SumoPhysicsController::setSumoTransform(nondynaonly); + +} + +void KX_SumoPhysicsController::SuspendDynamics() +{ + SumoPhysicsController::SuspendDynamics(); +} + +void KX_SumoPhysicsController::RestoreDynamics() +{ + SumoPhysicsController::RestoreDynamics(); +} + +SG_Controller* KX_SumoPhysicsController::GetReplica(SG_Node* destnode) +{ + + PHY_IMotionState* motionstate = new KX_MotionState(destnode); + + KX_SumoPhysicsController* physicsreplica = new KX_SumoPhysicsController(*this); + + //parentcontroller is here be able to avoid collisions between parent/child + + PHY_IPhysicsController* parentctrl = NULL; + + if (destnode != destnode->GetRootSGParent()) + { + KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject(); + if (clientgameobj) + { + parentctrl = (KX_SumoPhysicsController*)clientgameobj->GetPhysicsController(); + } else + { + // it could be a false node, try the children + NodeList::const_iterator childit; + for ( + childit = destnode->GetSGChildren().begin(); + childit!= destnode->GetSGChildren().end(); + ++childit + ) { + KX_GameObject* clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject()); + if (clientgameobj) + { + parentctrl = (KX_SumoPhysicsController*)clientgameobj->GetPhysicsController(); + } + } + } + } + + physicsreplica->PostProcessReplica(motionstate,parentctrl); + + return physicsreplica; +} + + +void KX_SumoPhysicsController::SetObject (SG_IObject* object) +{ + SG_Controller::SetObject(object); + + // cheating here... + KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject(); + gameobj->SetPhysicsController(this); + + +} + + +void KX_SumoPhysicsController::setOrientation(const MT_Quaternion& orn) +{ + SumoPhysicsController::setOrientation( + orn[0],orn[1],orn[2],orn[3]); + +} +void KX_SumoPhysicsController::getOrientation(MT_Quaternion& orn) +{ + + float quat[4]; + + SumoPhysicsController::getOrientation(quat[0],quat[1],quat[2],quat[3]); + + orn = MT_Quaternion(quat); + +} + +void KX_SumoPhysicsController::setPosition(const MT_Point3& pos) +{ + SumoPhysicsController::setPosition(pos[0],pos[1],pos[2]); + +} + +void KX_SumoPhysicsController::setScaling(const MT_Vector3& scaling) +{ + SumoPhysicsController::setScaling(scaling[0],scaling[1],scaling[2]); + +} + +MT_Scalar KX_SumoPhysicsController::GetMass() +{ + return SumoPhysicsController::getMass(); +} + +MT_Vector3 KX_SumoPhysicsController::getReactionForce() +{ + float force[3]; + SumoPhysicsController::getReactionForce(force[0],force[1],force[2]); + return MT_Vector3(force); + +} + +void KX_SumoPhysicsController::setRigidBody(bool rigid) +{ + SumoPhysicsController::setRigidBody(rigid); + +} + + +KX_SumoPhysicsController::~KX_SumoPhysicsController() +{ + + +}
\ No newline at end of file diff --git a/source/gameengine/Ketsji/KX_SumoPhysicsController.h b/source/gameengine/Ketsji/KX_SumoPhysicsController.h new file mode 100644 index 00000000000..b1019b0c19b --- /dev/null +++ b/source/gameengine/Ketsji/KX_SumoPhysicsController.h @@ -0,0 +1,81 @@ +#ifndef __KX_SUMOPHYSICSCONTROLLER_H +#define __KX_SUMOPHYSICSCONTROLLER_H + +#include "PHY_IPhysicsController.h" +#include "SM_Object.h" // for SM_Callback + +/** + Physics Controller, a special kind of Scene Graph Transformation Controller. + It get's callbacks from Sumo in case a transformation change took place. + Each time the scene graph get's updated, the controller get's a chance + in the 'Update' method to reflect changed. +*/ + +#include "SumoPhysicsController.h" +#include "KX_IPhysicsController.h" + +class KX_SumoPhysicsController : public KX_IPhysicsController, + public SumoPhysicsController + +{ + + +public: + KX_SumoPhysicsController( + class SM_Scene* sumoScene, + DT_SceneHandle solidscene, + class SM_Object* sumoObj, + class PHY_IMotionState* motionstate + ,bool dyna) + : SumoPhysicsController(sumoScene,solidscene,sumoObj,motionstate,dyna), + KX_IPhysicsController(dyna,NULL) + { + }; + virtual ~KX_SumoPhysicsController(); + + void applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse); + virtual void SetObject (SG_IObject* object); + + + void RelativeTranslate(const MT_Vector3& dloc,bool local); + void RelativeRotate(const MT_Matrix3x3& drot,bool local); + void ApplyTorque(const MT_Vector3& torque,bool local); + void ApplyForce(const MT_Vector3& force,bool local); + MT_Vector3 GetLinearVelocity(); + MT_Vector3 GetVelocity(const MT_Point3& pos); + void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); + void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); + + void SuspendDynamics(); + void RestoreDynamics(); + virtual void getOrientation(MT_Quaternion& orn); + virtual void setOrientation(const MT_Quaternion& orn); + + virtual void setPosition(const MT_Point3& pos); + virtual void setScaling(const MT_Vector3& scaling); + virtual MT_Scalar GetMass(); + virtual MT_Vector3 getReactionForce(); + virtual void setRigidBody(bool rigid); + + + virtual SG_Controller* GetReplica(class SG_Node* destnode); + + + void SetSumoTransform(bool nondynaonly); + // todo: remove next line ! + virtual void SetSimulatedTime(double time); + + // call from scene graph to update + virtual bool Update(double time); + + void + SetOption( + int option, + int value + ){ + // intentionally empty + }; + + +}; +#endif //__KX_SUMOPHYSICSCONTROLLER_H diff --git a/source/gameengine/Ketsji/KX_TimeCategoryLogger.cpp b/source/gameengine/Ketsji/KX_TimeCategoryLogger.cpp new file mode 100644 index 00000000000..53a47abd77e --- /dev/null +++ b/source/gameengine/Ketsji/KX_TimeCategoryLogger.cpp @@ -0,0 +1,142 @@ +/** + * $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_TimeCategoryLogger.h" + + +KX_TimeCategoryLogger::KX_TimeCategoryLogger(unsigned int maxNumMeasurements) +: m_maxNumMeasurements(maxNumMeasurements) +{ +} + + +KX_TimeCategoryLogger::~KX_TimeCategoryLogger(void) +{ + DisposeLoggers(); +} + + +void KX_TimeCategoryLogger::SetMaxNumMeasurements(unsigned int maxNumMeasurements) +{ + KX_TimeLoggerMap::iterator it; + for (it = m_loggers.begin(); it != m_loggers.end(); it++) { + it->second->SetMaxNumMeasurements(maxNumMeasurements); + } + m_maxNumMeasurements = maxNumMeasurements; +} + + +unsigned int KX_TimeCategoryLogger::GetMaxNumMeasurements(void) const +{ + return m_maxNumMeasurements; +} + + +void KX_TimeCategoryLogger::AddCategory(TimeCategory tc) +{ + // Only add if not already present + if (m_loggers.find(tc) == m_loggers.end()) { + KX_TimeLogger* logger = new KX_TimeLogger(m_maxNumMeasurements); + //assert(logger); + m_loggers.insert(KX_TimeLoggerMap::value_type(tc, logger)); + } +} + + +void KX_TimeCategoryLogger::StartLog(TimeCategory tc, double now, bool endOtherCategories) +{ + if (endOtherCategories) { + KX_TimeLoggerMap::iterator it; + for (it = m_loggers.begin(); it != m_loggers.end(); it++) { + if (it->first != tc) { + it->second->EndLog(now); + } + } + } + //assert(m_loggers[tc] != m_loggers.end()); + m_loggers[tc]->StartLog(now); +} + + +void KX_TimeCategoryLogger::EndLog(TimeCategory tc, double now) +{ + //assert(m_loggers[tc] != m_loggers.end()); + m_loggers[tc]->EndLog(now); +} + + +void KX_TimeCategoryLogger::EndLog(double now) +{ + KX_TimeLoggerMap::iterator it; + for (it = m_loggers.begin(); it != m_loggers.end(); it++) { + it->second->EndLog(now); + } +} + + +void KX_TimeCategoryLogger::NextMeasurement(double now) +{ + KX_TimeLoggerMap::iterator it; + for (it = m_loggers.begin(); it != m_loggers.end(); it++) { + it->second->NextMeasurement(now); + } +} + + +double KX_TimeCategoryLogger::GetAverage(TimeCategory tc) +{ + //assert(m_loggers[tc] != m_loggers.end()); + return m_loggers[tc]->GetAverage(); +} + + +double KX_TimeCategoryLogger::GetAverage(void) +{ + double time = 0.; + + KX_TimeLoggerMap::iterator it; + for (it = m_loggers.begin(); it != m_loggers.end(); it++) { + time += it->second->GetAverage(); + } + + return time; +} + + +void KX_TimeCategoryLogger::DisposeLoggers(void) +{ + KX_TimeLoggerMap::iterator it; + for (it = m_loggers.begin(); it != m_loggers.end(); it++) { + delete it->second; + } +} + diff --git a/source/gameengine/Ketsji/KX_TimeCategoryLogger.h b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h new file mode 100644 index 00000000000..ce4c7f37c0f --- /dev/null +++ b/source/gameengine/Ketsji/KX_TimeCategoryLogger.h @@ -0,0 +1,133 @@ +/** + * $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_TIME_CATEGORY_LOGGER_H +#define __KX_TIME_CATEGORY_LOGGER_H + +#ifdef WIN32 +#pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#endif + +#include <map> + +#include "KX_TimeLogger.h" + +/** + * Stores and manages time measurements by category. + * Categories can be added dynamically. + * Average measurements can be established for each separate category + * or for all categories together. + */ +class KX_TimeCategoryLogger { +public: + typedef int TimeCategory; + + /** + * Constructor. + * @param maxNumMesasurements Maximum number of measurements stored (> 1). + */ + KX_TimeCategoryLogger(unsigned int maxNumMeasurements = 10); + + /** + * Destructor. + */ + virtual ~KX_TimeCategoryLogger(void); + + /** + * Changes the maximum number of measurements that can be stored. + */ + virtual void SetMaxNumMeasurements(unsigned int maxNumMeasurements); + + /** + * Changes the maximum number of measurements that can be stored. + */ + virtual unsigned int GetMaxNumMeasurements(void) const; + + /** + * Adds a category. + * @param category The new category. + */ + virtual void AddCategory(TimeCategory tc); + + /** + * Starts logging in current measurement for the given category. + * @param tc The category to log to. + * @param now The current time. + * @param endOtherCategories Whether to stop logging to other categories. + */ + virtual void StartLog(TimeCategory tc, double now, bool endOtherCategories = true); + + /** + * End logging in current measurement for the given category. + * @param tc The category to log to. + * @param now The current time. + */ + virtual void EndLog(TimeCategory tc, double now); + + /** + * End logging in current measurement for all categories. + * @param now The current time. + */ + virtual void EndLog(double now); + + /** + * Logs time in next measurement. + * @param now The current time. + */ + virtual void NextMeasurement(double now); + + /** + * Returns average of all but the current measurement time. + * @return The average of all but the current measurement. + */ + virtual double GetAverage(TimeCategory tc); + + /** + * Returns average for grand total. + */ + virtual double GetAverage(void); + +protected: + /** + * Disposes loggers. + */ + virtual void DisposeLoggers(void); + + /** Storage for the loggers. */ + typedef std::map<TimeCategory, KX_TimeLogger*> KX_TimeLoggerMap; + KX_TimeLoggerMap m_loggers; + /** Maximum number of measurements. */ + unsigned int m_maxNumMeasurements; + +}; + +#endif // __KX_TIME_CATEGORY_LOGGER_H diff --git a/source/gameengine/Ketsji/KX_TimeLogger.cpp b/source/gameengine/Ketsji/KX_TimeLogger.cpp new file mode 100644 index 00000000000..e2114e8d8d7 --- /dev/null +++ b/source/gameengine/Ketsji/KX_TimeLogger.cpp @@ -0,0 +1,117 @@ +/** + * $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_TimeLogger.h" + + + +KX_TimeLogger::KX_TimeLogger(unsigned int maxNumMeasurements) +: m_maxNumMeasurements(maxNumMeasurements), m_logging(false), m_logStart(0) +{ +} + + +KX_TimeLogger::~KX_TimeLogger(void) +{ +} + + +void KX_TimeLogger::SetMaxNumMeasurements(unsigned int maxNumMeasurements) +{ + if ((m_maxNumMeasurements != maxNumMeasurements) && maxNumMeasurements) { + // Actual removing is done in NextMeasurement() + m_maxNumMeasurements = maxNumMeasurements; + } +} + + +unsigned int KX_TimeLogger::GetMaxNumMeasurements(void) const +{ + return m_maxNumMeasurements; +} + + +void KX_TimeLogger::StartLog(double now) +{ + if (!m_logging) { + m_logging = true; + m_logStart = now; + } +} + + +void KX_TimeLogger::EndLog(double now) +{ + if (m_logging) { + m_logging = false; + double time = now - m_logStart; + if (m_measurements.size() > 0) { + m_measurements[0] += time; + } + } +} + + +void KX_TimeLogger::NextMeasurement(double now) +{ + // End logging to current measurement + EndLog(now); + + // Add a new measurement at the front + double m = 0.; + m_measurements.push_front(m); + + // Remove measurement if we grow beyond the maximum size + if ((m_measurements.size()) > m_maxNumMeasurements) { + while (m_measurements.size() > m_maxNumMeasurements) { + m_measurements.pop_back(); + } + } +} + + + +double KX_TimeLogger::GetAverage(void) const +{ + double avg = 0.; + + unsigned int numMeasurements = m_measurements.size(); + if (numMeasurements > 1) { + for (int i = 1; i < numMeasurements; i++) { + avg += m_measurements[i]; + } + avg /= (float)numMeasurements - 1; + } + + return avg; +} + diff --git a/source/gameengine/Ketsji/KX_TimeLogger.h b/source/gameengine/Ketsji/KX_TimeLogger.h new file mode 100644 index 00000000000..a802ed1a93a --- /dev/null +++ b/source/gameengine/Ketsji/KX_TimeLogger.h @@ -0,0 +1,107 @@ +/** + * $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_TIME_LOGGER_H +#define __KX_TIME_LOGGER_H + +#ifdef WIN32 +#pragma warning (disable:4786) // suppress stl-MSVC debug info warning +#endif + + +#include <deque> + +/** + * Stores and manages time measurements. + */ +class KX_TimeLogger { +public: + /** + * Constructor. + * @param maxNumMesasurements Maximum number of measurements stored (>1). + */ + KX_TimeLogger(unsigned int maxNumMeasurements = 10); + + /** + * Destructor. + */ + virtual ~KX_TimeLogger(void); + + /** + * Changes the maximum number of measurements that can be stored. + */ + virtual void SetMaxNumMeasurements(unsigned int maxNumMeasurements); + + /** + * Changes the maximum number of measurements that can be stored. + */ + virtual unsigned int GetMaxNumMeasurements(void) const; + + /** + * Starts logging in current measurement. + * @param now The current time. + */ + virtual void StartLog(double now); + + /** + * End logging in current measurement. + * @param now The current time. + */ + virtual void EndLog(double now); + + /** + * Logs time in next measurement. + * @param now The current time. + */ + virtual void NextMeasurement(double now); + + /** + * Returns average of all but the current measurement. + * @return The average of all but the current measurement. + */ + virtual double GetAverage(void) const; + +protected: + /** Storage for the measurements. */ + std::deque<double> m_measurements; + + /** Maximum number of measurements. */ + unsigned int m_maxNumMeasurements; + + /** Time at start of logging. */ + double m_logStart; + + /** State of logging. */ + bool m_logging; +}; + +#endif // __KX_TIME_LOGGER_H diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp new file mode 100644 index 00000000000..d9848398900 --- /dev/null +++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp @@ -0,0 +1,117 @@ +/** + * $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_TouchEventManager.h" + +#include "SCA_ISensor.h" +#include "KX_TouchSensor.h" +#include "KX_GameObject.h" + +#ifdef PHYSICS_NOT_YET + +KX_TouchEventManager::KX_TouchEventManager(class SCA_LogicManager* logicmgr, + DT_RespTableHandle resphandle, + DT_SceneHandle scenehandle) + : SCA_EventManager(TOUCH_EVENTMGR), + m_resphandle(resphandle), + m_scenehandle(scenehandle), + m_logicmgr(logicmgr) {} + +void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor) +{ + + + KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor); + m_sensors.push_back(touchsensor); + + touchsensor->RegisterSumo();//this,m_resphandle); + + //KX_GameObject* gameobj = ((KX_GameObject*)sensor->GetParent()); +// SM_Object* smobj = touchsensor->GetSumoObject();//gameobj->GetSumoObject(); +// if (smobj) +// { +// smobj->calcXform(); +// DT_AddObject(m_scenehandle, +// smobj->getObjectHandle()); +// } +} + + + +void KX_TouchEventManager::EndFrame() +{ + vector<SCA_ISensor*>::iterator it; + for ( it = m_sensors.begin(); + !(it==m_sensors.end());it++) + { + ((KX_TouchSensor*)*it)->EndFrame(); + + } +} + + + +void KX_TouchEventManager::NextFrame(double curtime,double deltatime) +{ + if (m_sensors.size() > 0) + { + vector<SCA_ISensor*>::iterator it; + + for (it = m_sensors.begin();!(it==m_sensors.end());it++) + ((KX_TouchSensor*)*it)->SynchronizeTransform(); + + if (DT_Test(m_scenehandle,m_resphandle)) + int i = 0; + + for (it = m_sensors.begin();!(it==m_sensors.end());it++) + (*it)->Activate(m_logicmgr,NULL); + } +} + + + +void KX_TouchEventManager::RemoveSensor(class SCA_ISensor* sensor) +{ + std::vector<SCA_ISensor*>::iterator i = + std::find(m_sensors.begin(), m_sensors.end(), sensor); + if (!(i == m_sensors.end())) + { + //std::swap(*i, m_sensors.back()); + //m_sensors.pop_back(); + //SM_Object* smobj = ((KX_TouchSensor*)*i)->GetSumoObject(); + //DT_RemoveObject(m_scenehandle, + // smobj->getObjectHandle()); + } + // remove the sensor forever :) + SCA_EventManager::RemoveSensor(sensor); +} + +#endif diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.h b/source/gameengine/Ketsji/KX_TouchEventManager.h new file mode 100644 index 00000000000..4575814986f --- /dev/null +++ b/source/gameengine/Ketsji/KX_TouchEventManager.h @@ -0,0 +1,67 @@ +/** + * $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_TOUCHEVENTMANAGER +#define __KX_TOUCHEVENTMANAGER + +#include "SCA_EventManager.h" +#include "KX_TouchSensor.h" +#include "KX_GameObject.h" + +#include <vector> +using namespace std; + + +class KX_TouchEventManager : public SCA_EventManager +{ + class SCA_LogicManager* m_logicmgr; + +public: + KX_TouchEventManager(class SCA_LogicManager* logicmgr); + virtual void NextFrame(double curtime,double deltatime); + virtual void EndFrame(); + virtual void RemoveSensor(class SCA_ISensor* sensor); + virtual void RegisterSensor(SCA_ISensor* sensor); + SCA_LogicManager* GetLogicManager() { return m_logicmgr;} +}; + +#endif //__KX_TOUCHEVENTMANAGER + + + + + + + + + + + diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp new file mode 100644 index 00000000000..daf344999fc --- /dev/null +++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp @@ -0,0 +1,393 @@ +/** + * Senses touch and collision events + * + * $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_TouchSensor.h" +#include "SCA_EventManager.h" +#include "SCA_LogicManager.h" +#include "KX_GameObject.h" +#include "KX_TouchEventManager.h" +#include <iostream> + +#ifdef PHYSICS_NOT_YET + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + +void KX_TouchSensor::SynchronizeTransform() +{ + + if (m_sumoObj) + { + m_sumoObj->setPosition(((KX_GameObject*)GetParent())->NodeGetWorldPosition()); + m_sumoObj->setOrientation( + ((KX_GameObject*)GetParent())->NodeGetWorldOrientation().getRotation() + ); + m_sumoObj->calcXform(); + } + +} + + +void KX_TouchSensor::EndFrame() { + m_colliders->ReleaseAndRemoveAll(); + m_bTriggered = false; +} + +bool KX_TouchSensor::Evaluate(CValue* event) +{ + bool result = false; + + if (m_bTriggered != m_bLastTriggered) + { + m_bLastTriggered = m_bTriggered; + if (!m_bTriggered) + m_hitObject = NULL; + result = true; + } + + return result; +} + +KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,SM_Object* sumoObj,bool bFindMaterial,const STR_String& touchedpropname,PyTypeObject* T) +:SCA_ISensor(gameobj,eventmgr,T), +m_touchedpropname(touchedpropname), +m_bFindMaterial(bFindMaterial), +m_sumoObj(sumoObj), +m_bCollision(false), +m_bTriggered(false), +m_bLastTriggered(false) +{ + m_eventmgr = eventmgr; + KX_TouchEventManager* touchmgr = (KX_TouchEventManager*) eventmgr; + + m_resptable = touchmgr->GetResponseTable(); + + m_solidHandle = m_sumoObj->getObjectHandle(); + + m_hitObject = NULL; + m_colliders = new CListValue(); +} + + +KX_TouchSensor::~KX_TouchSensor() +{ + DT_ClearObjectResponse(m_resptable,m_solidHandle); + m_colliders->Release(); +} + +void KX_TouchSensor::ReParent(SCA_IObject* parent) +{ + + m_sumoObj = ((KX_GameObject*)parent)->GetSumoObject(); + m_solidHandle = m_sumoObj->getObjectHandle(); + + m_client_info.m_clientobject = NULL;//parent; + m_client_info.m_auxilary_info = NULL; + SCA_ISensor::ReParent(parent); +} + + +void KX_TouchSensor::RegisterSumo() +{ + + if (m_sumoObj) + { + // collision + DT_SetObjectResponse( + m_resptable, + m_solidHandle, + collisionResponse, + DT_SIMPLE_RESPONSE, + this); + + } + +} + +void KX_TouchSensor::HandleCollision(void* obj1,void* obj2,const DT_CollData * coll_data) +{ + KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr; + KX_GameObject* parent = (KX_GameObject*)GetParent(); + + // need the mapping from SM_Objects to gameobjects now + + SM_ClientObjectInfo* client_info =(SM_ClientObjectInfo*) (obj1 == m_sumoObj? + ((SM_Object*)obj2)->getClientObject() : + ((SM_Object*)obj1)->getClientObject()); + + + KX_GameObject* gameobj = ( client_info ? + (KX_GameObject*)client_info->m_clientobject : + NULL); + + if (gameobj && (gameobj != parent)) + { + if (!m_colliders->SearchValue(gameobj)) + m_colliders->Add(gameobj->AddRef()); + + bool found = m_touchedpropname.IsEmpty(); + if (!found) + { + if (m_bFindMaterial) + { + if (client_info->m_auxilary_info) + { + found = (m_touchedpropname == ((char*)client_info->m_auxilary_info)); + } + + if (found) + { + int i=0; + } + + } else + { + found = (gameobj->GetProperty(m_touchedpropname) != NULL); + } + } + if (found) + { + m_bTriggered = true; + m_hitObject = gameobj; + } + + } + +} + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_TouchSensor::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_TouchSensor", + sizeof(KX_TouchSensor), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_TouchSensor::Parents[] = { + &KX_TouchSensor::Type, + &SCA_ISensor::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_TouchSensor::Methods[] = { + {"setProperty", + (PyCFunction) KX_TouchSensor::sPySetProperty, METH_VARARGS, SetProperty_doc}, + {"getProperty", + (PyCFunction) KX_TouchSensor::sPyGetProperty, METH_VARARGS, GetProperty_doc}, + {"getHitObject", + (PyCFunction) KX_TouchSensor::sPyGetHitObject, METH_VARARGS, GetHitObject_doc}, + {"getHitObjectList", + (PyCFunction) KX_TouchSensor::sPyGetHitObjectList, METH_VARARGS, GetHitObjectList_doc}, + {NULL,NULL} //Sentinel +}; + +PyObject* KX_TouchSensor::_getattr(char* attr) { + _getattr_up(SCA_ISensor); +} + +/* Python API */ + +/* 1. setProperty */ +char KX_TouchSensor::SetProperty_doc[] = +"setProperty(name)\n" +"\t- name: string\n" +"\tSet the property or material to collide with. Use\n" +"\tsetTouchMaterial() to switch between properties and\n" +"\tmaterials."; +PyObject* KX_TouchSensor::PySetProperty(PyObject* self, + PyObject* args, + PyObject* kwds) { + char *nameArg; + if (!PyArg_ParseTuple(args, "s", &nameArg)) { + return NULL; + } + + CValue* prop = GetParent()->FindIdentifier(nameArg); + + if (!prop->IsError()) { + m_touchedpropname = nameArg; + prop->Release(); + } else { + ; /* not found ... */ + } + + Py_Return; +} +/* 2. getProperty */ +char KX_TouchSensor::GetProperty_doc[] = +"getProperty(name)\n" +"\tReturns the property or material to collide with. Use\n" +"\tgetTouchMaterial() to find out whether this sensor\n" +"\tlooks for properties or materials."; +PyObject* KX_TouchSensor::PyGetProperty(PyObject* self, + PyObject* args, + PyObject* kwds) { + return PyString_FromString(m_touchedpropname); +} + +char KX_TouchSensor::GetHitObject_doc[] = +"getHitObject()\n" +; +PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + /* to do: do Py_IncRef if the object is already known in Python */ + /* otherwise, this leaks memory */ + if (m_hitObject) + { + return m_hitObject->AddRef(); + } + Py_Return; +} + +char KX_TouchSensor::GetHitObjectList_doc[] = +"getHitObjectList()\n" +"\tReturn a list of the objects this object collided with,\n" +"\tbut only those matching the property/material condition.\n"; +PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + /* to do: do Py_IncRef if the object is already known in Python */ + /* otherwise, this leaks memory */ + + if ( m_touchedpropname.IsEmpty() ) { + return m_colliders->AddRef(); + } else { + CListValue* newList = new CListValue(); + int i = 0; + while (i < m_colliders->GetCount()) { + if (m_bFindMaterial) { + /* need to associate the CValues from the list to material + * names. The collider list _should_ contains only + * KX_GameObjects. I am loathe to cast them, though... The + * material name must be retrieved from Sumo. To a Sumo + * object, a client-info block is attached. This block + * contains the material name. + * - this also doesn't work (obviously) for multi-materials... + */ + KX_GameObject* gameob = (KX_GameObject*) m_colliders->GetValue(i); + SM_Object* smob = (SM_Object*) gameob->GetSumoObject(); + + if (smob) { + SM_ClientObjectInfo* cl_inf = (SM_ClientObjectInfo*) smob->getClientObject(); + + if (m_touchedpropname == ((char*)cl_inf->m_auxilary_info)) { + newList->Add(m_colliders->GetValue(i)->AddRef()); + } + } + + } else { + CValue* val = m_colliders->GetValue(i)->FindIdentifier(m_touchedpropname); + if (!val->IsError()) { + newList->Add(m_colliders->GetValue(i)->AddRef()); + val->Release(); + } + } + + i++; + } + return newList->AddRef(); + } + +} + +/* 5. getTouchMaterial */ +char KX_TouchSensor::GetTouchMaterial_doc[] = +"getTouchMaterial()\n" +"\tReturns KX_TRUE if this sensor looks for a specific material,\n" +"\tKX_FALSE if it looks for a specific property.\n" ; +PyObject* KX_TouchSensor::PyGetTouchMaterial(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int retval = 0; + + if (m_bFindMaterial) { + retval = KX_TRUE; + } else { + retval = KX_FALSE; + } + + return PyInt_FromLong(retval); +} + +/* 6. setTouchMaterial */ +char KX_TouchSensor::SetTouchMaterial_doc[] = +"setTouchMaterial(flag)\n" +"\t- flag: KX_TRUE or KX_FALSE.\n" +"\tSet flag to KX_TRUE to switch on positive pulse mode,\n" +"\tKX_FALSE to switch off positive pulse mode.\n" ; +PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject* args, PyObject* kwds) +{ + int pulseArg = 0; + + if(!PyArg_ParseTuple(args, "i", &pulseArg)) { + return NULL; + } + + if (pulseArg == KX_TRUE) { + m_bFindMaterial = true; + } else if (pulseArg == KX_FALSE){ + m_bFindMaterial = false; + } else { + ; /* internal error */ + } + + Py_Return; +} + +#endif //#ifdef PHYSICS_NOT_YET + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h new file mode 100644 index 00000000000..123f7041968 --- /dev/null +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -0,0 +1,146 @@ +/** + * Senses touch and collision events + * + * $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_TOUCHSENSOR +#define __KX_TOUCHSENSOR + +#include "SCA_ISensor.h" +#include "ListValue.h" + +#include "KX_ClientObjectInfo.h" + +class KX_TouchSensor : public SCA_ISensor +{ +protected: + Py_Header; + + /** + * The sensor should only look for objects with this property. + */ + STR_String m_touchedpropname; + bool m_bFindMaterial; + class SCA_EventManager* m_eventmgr; + + //class SM_Object* m_sumoObj; + //DT_ObjectHandle m_solidHandle; + //SM_ClientObjectInfo m_client_info; + //DT_RespTableHandle m_resptable; + + + bool m_bCollision; + bool m_bTriggered; + bool m_bLastTriggered; + SCA_IObject* m_hitObject; + class CListValue* m_colliders; + +public: + KX_TouchSensor(class SCA_EventManager* eventmgr, + class KX_GameObject* gameobj, + class SM_Object* sumoObj, + bool fFindMaterial, + const STR_String& touchedpropname, + PyTypeObject* T=&Type) ; + virtual ~KX_TouchSensor(); + + virtual CValue* GetReplica() { + KX_TouchSensor* replica = new KX_TouchSensor(*this); + replica->m_colliders = new CListValue(); + replica->m_bCollision = false; + replica->m_bTriggered= false; + replica->m_hitObject = NULL; + replica->m_bLastTriggered = false; + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; + }; + virtual void SynchronizeTransform(); + virtual bool Evaluate(CValue* event); + virtual void ReParent(SCA_IObject* parent); + +/* static void collisionResponse(void *client_data, + void *object1, + void *object2, + const DT_CollData *coll_data) { + class KX_TouchSensor* sensor = (class KX_TouchSensor*) client_data; + sensor->HandleCollision(object1,object2,coll_data); + } + + + + void RegisterSumo(); + + virtual void HandleCollision(void* obj1,void* obj2, + const DT_CollData * coll_data); + + + // SM_Object* GetSumoObject() { return m_sumoObj; }; + + */ + + virtual bool IsPositiveTrigger() { + bool result = m_bTriggered; + if (m_invert) result = !result; + return result; + } + + + void EndFrame(); + + // todo: put some info for collision maybe + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + + /* 1. setProperty */ + KX_PYMETHOD_DOC(KX_TouchSensor,SetProperty); + /* 2. getProperty */ + KX_PYMETHOD_DOC(KX_TouchSensor,GetProperty); + /* 3. getHitObject */ + KX_PYMETHOD_DOC(KX_TouchSensor,GetHitObject); + /* 4. getHitObject */ + KX_PYMETHOD_DOC(KX_TouchSensor,GetHitObjectList); + /* 5. getTouchMaterial */ + KX_PYMETHOD_DOC(KX_TouchSensor,GetTouchMaterial); + /* 6. setTouchMaterial */ + KX_PYMETHOD_DOC(KX_TouchSensor,SetTouchMaterial); + +}; + +#endif //__KX_TOUCHSENSOR + + + diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp new file mode 100644 index 00000000000..647ffb447aa --- /dev/null +++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp @@ -0,0 +1,487 @@ +// +// Replace the mesh for this actuator's parent +// +// $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 ***** + +// todo: not all trackflags / upflags are implemented/tested ! +// m_trackflag is used to determine the forward tracking direction +// m_upflag for the up direction +// normal situation is +y for forward, +z for up + +#include "MT_Scalar.h" +#include "SCA_IActuator.h" +#include "KX_TrackToActuator.h" +#include "SCA_IScene.h" +#include "SCA_LogicManager.h" +#include <math.h> +#include <iostream> +#include "KX_GameObject.h" + + +/* ------------------------------------------------------------------------- */ +/* Native functions */ +/* ------------------------------------------------------------------------- */ + + + +KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj, + SCA_IObject *ob, + int time, + bool allow3D, + int trackflag, + int upflag, + PyTypeObject* T) + : + SCA_IActuator(gameobj, T) +{ + m_time = time; + m_allow3D = allow3D; + m_object = ob; + m_trackflag = trackflag; + m_upflag = upflag; +} /* End of constructor */ + + + +/* old function from Blender */ +MT_Matrix3x3 EulToMat3(float *eul) +{ + MT_Matrix3x3 mat; + float ci, cj, ch, si, sj, sh, cc, cs, sc, ss; + + ci = cos(eul[0]); + cj = cos(eul[1]); + ch = cos(eul[2]); + si = sin(eul[0]); + sj = sin(eul[1]); + sh = sin(eul[2]); + cc = ci*ch; + cs = ci*sh; + sc = si*ch; + ss = si*sh; + + mat[0][0] = cj*ch; + mat[1][0] = sj*sc-cs; + mat[2][0] = sj*cc+ss; + mat[0][1] = cj*sh; + mat[1][1] = sj*ss+cc; + mat[2][1] = sj*cs-sc; + mat[0][2] = -sj; + mat[1][2] = cj*si; + mat[2][2] = cj*ci; + + return mat; +} + + + +/* old function from Blender */ +void Mat3ToEul(MT_Matrix3x3 mat, float *eul) +{ + MT_Scalar cy; + + cy = sqrt(mat[0][0]*mat[0][0] + mat[0][1]*mat[0][1]); + + if (cy > 16.0*FLT_EPSILON) { + eul[0] = atan2(mat[1][2], mat[2][2]); + eul[1] = atan2(-mat[0][2], cy); + eul[2] = atan2(mat[0][1], mat[0][0]); + } else { + eul[0] = atan2(-mat[2][1], mat[1][1]); + eul[1] = atan2(-mat[0][2], cy); + eul[2] = 0.0; + } +} + + + +/* old function from Blender */ +void compatible_eulFast(float *eul, float *oldrot) +{ + float dx, dy, dz; + + /* verschillen van ong 360 graden corrigeren */ + + dx= eul[0] - oldrot[0]; + dy= eul[1] - oldrot[1]; + dz= eul[2] - oldrot[2]; + + if( fabs(dx) > 5.1) { + if(dx > 0.0) eul[0] -= MT_2_PI; else eul[0]+= MT_2_PI; + } + if( fabs(dy) > 5.1) { + if(dy > 0.0) eul[1] -= MT_2_PI; else eul[1]+= MT_2_PI; + } + if( fabs(dz) > 5.1 ) { + if(dz > 0.0) eul[2] -= MT_2_PI; else eul[2]+= MT_2_PI; + } +} + + + +MT_Matrix3x3 matrix3x3_interpol(MT_Matrix3x3 oldmat, MT_Matrix3x3 mat, int m_time) +{ + float eul[3], oldeul[3]; + + Mat3ToEul(oldmat, oldeul); + Mat3ToEul(mat, eul); + compatible_eulFast(eul, oldeul); + + eul[0]= (m_time*oldeul[0] + eul[0])/(1.0+m_time); + eul[1]= (m_time*oldeul[1] + eul[1])/(1.0+m_time); + eul[2]= (m_time*oldeul[2] + eul[2])/(1.0+m_time); + + return EulToMat3(eul); +} + + + +KX_TrackToActuator::~KX_TrackToActuator() +{ + // there's nothing to be done here, really.... +} /* end of destructor */ + + + +bool KX_TrackToActuator::Update(double curtime,double deltatime) +{ + bool result = false; + bool bNegativeEvent = IsNegativeEvent(); + RemoveAllEvents(); + + if (bNegativeEvent) + { + // do nothing on negative events + } + else if (m_object) + { + KX_GameObject* curobj = (KX_GameObject*) GetParent(); + MT_Vector3 dir = ((KX_GameObject*)m_object)->NodeGetWorldPosition() - curobj->NodeGetWorldPosition(); + dir.normalize(); + MT_Vector3 up(0,0,1); + + +#ifdef DSADSA + switch (m_upflag) + { + case 0: + { + up = MT_Vector3(1.0,0,0); + break; + } + case 1: + { + up = MT_Vector3(0,1.0,0); + break; + } + case 2: + default: + { + up = MT_Vector3(0,0,1.0); + } + } +#endif + if (m_allow3D) + { + up = (up - up.dot(dir) * dir).normalized(); + + } + else + { + dir = (dir - up.dot(dir)*up).normalized(); + } + + MT_Vector3 left; + MT_Matrix3x3 mat; + + switch (m_trackflag) + { + case 0: // TRACK X + { + // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up + left = dir.normalized(); + dir = (left.cross(up)).normalized(); + mat.setValue ( + left[0], dir[0],up[0], + left[1], dir[1],up[1], + left[2], dir[2],up[2] + ); + + break; + }; + case 1: // TRACK Y + { + // (0.0 , 1.0 , 0.0 ) y direction is forward, z (0.0 , 0.0 , 1.0 ) up + left = (dir.cross(up)).normalized(); + mat.setValue ( + left[0], dir[0],up[0], + left[1], dir[1],up[1], + left[2], dir[2],up[2] + ); + + break; + } + + case 2: // track Z + { + left = up.normalized(); + up = dir.normalized(); + dir = left; + left = (dir.cross(up)).normalized(); + mat.setValue ( + left[0], dir[0],up[0], + left[1], dir[1],up[1], + left[2], dir[2],up[2] + ); + break; + } + + case 3: // TRACK -X + { + // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up + left = -dir.normalized(); + dir = -(left.cross(up)).normalized(); + mat.setValue ( + left[0], dir[0],up[0], + left[1], dir[1],up[1], + left[2], dir[2],up[2] + ); + + break; + }; + case 4: // TRACK -Y + { + // (0.0 , -1.0 , 0.0 ) -y direction is forward, z (0.0 , 0.0 , 1.0 ) up + left = (-dir.cross(up)).normalized(); + mat.setValue ( + left[0], -dir[0],up[0], + left[1], -dir[1],up[1], + left[2], -dir[2],up[2] + ); + break; + } + case 5: // track -Z + { + left = up.normalized(); + up = -dir.normalized(); + dir = left; + left = (dir.cross(up)).normalized(); + mat.setValue ( + left[0], dir[0],up[0], + left[1], dir[1],up[1], + left[2], dir[2],up[2] + ); + + break; + } + + default: + { + // (1.0 , 0.0 , 0.0 ) -x direction is forward, z (0.0 , 0.0 , 1.0 ) up + left = -dir.normalized(); + dir = -(left.cross(up)).normalized(); + mat.setValue ( + left[0], dir[0],up[0], + left[1], dir[1],up[1], + left[2], dir[2],up[2] + ); + } + } + + MT_Matrix3x3 oldmat; + oldmat= curobj->NodeGetWorldOrientation(); + + /* erwin should rewrite this! */ + mat= matrix3x3_interpol(oldmat, mat, m_time); + + curobj->NodeSetLocalOrientation(mat); + + //cout << "\n TrackTo!"; + result = true; + } + + return result; +} + + + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + + + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject KX_TrackToActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_TrackToActuator", + sizeof(KX_TrackToActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + + + +PyParentObject KX_TrackToActuator::Parents[] = { + &KX_TrackToActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + + + +PyMethodDef KX_TrackToActuator::Methods[] = { + {"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_VARARGS, SetObject_doc}, + {"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, GetObject_doc}, + {"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, SetTime_doc}, + {"getTime", (PyCFunction) KX_TrackToActuator::sPyGetTime, METH_VARARGS, GetTime_doc}, + {"setUse3D", (PyCFunction) KX_TrackToActuator::sPySetUse3D, METH_VARARGS, SetUse3D_doc}, + {"getUse3D", (PyCFunction) KX_TrackToActuator::sPyGetUse3D, METH_VARARGS, GetUse3D_doc}, + {NULL,NULL} //Sentinel +}; + + + +PyObject* KX_TrackToActuator::_getattr(char* attr) +{ + _getattr_up(SCA_IActuator); +} + + + +/* 1. setObject */ +char KX_TrackToActuator::SetObject_doc[] = +"setObject(object)\n" +"\t- object: string\n" +"\tSet the object to track with the parent of this actuator.\n"; +PyObject* KX_TrackToActuator::PySetObject(PyObject* self, PyObject* args, PyObject* kwds) { + char* nameArg; + + if (!PyArg_ParseTuple(args, "s", &nameArg)) { + return NULL; + } + CValue* gameobj = SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(nameArg)); + + m_object= (SCA_IObject*)gameobj; + + Py_Return; +} + + + +/* 2. getObject */ +char KX_TrackToActuator::GetObject_doc[] = +"getObject()\n" +"\tReturns the object to track with the parent of this actuator.\n"; +PyObject* KX_TrackToActuator::PyGetObject(PyObject* self, PyObject* args, PyObject* kwds) +{ + return PyString_FromString(m_object->GetName()); +} + + + +/* 3. setTime */ +char KX_TrackToActuator::SetTime_doc[] = +"setTime(time)\n" +"\t- time: integer\n" +"\tSet the time in frames with which to delay the tracking motion.\n"; +PyObject* KX_TrackToActuator::PySetTime(PyObject* self, PyObject* args, PyObject* kwds) +{ + int timeArg; + + if (!PyArg_ParseTuple(args, "i", &timeArg)) + { + return NULL; + } + + m_time= timeArg; + + Py_Return; +} + + + +/* 4.getTime */ +char KX_TrackToActuator::GetTime_doc[] = +"getTime()\n" +"\t- time: integer\n" +"\tReturn the time in frames with which the tracking motion is delayed.\n"; +PyObject* KX_TrackToActuator::PyGetTime(PyObject* self, PyObject* args, PyObject* kwds) +{ + return PyInt_FromLong(m_time); +} + + + +/* 5. getUse3D */ +char KX_TrackToActuator::GetUse3D_doc[] = +"getUse3D()\n" +"\tReturns 1 if the motion is allowed to extend in the z-direction.\n"; +PyObject* KX_TrackToActuator::PyGetUse3D(PyObject* self, PyObject* args, PyObject* kwds) +{ + return PyInt_FromLong(!(m_allow3D == 0)); +} + + + +/* 6. setUse3D */ +char KX_TrackToActuator::SetUse3D_doc[] = +"setUse3D(value)\n" +"\t- value: 0 or 1\n" +"\tSet to 1 to allow the tracking motion to extend in the z-direction,\n" +"\tset to 0 to lock the tracking motion to the x-y plane.\n"; +PyObject* KX_TrackToActuator::PySetUse3D(PyObject* self, PyObject* args, PyObject* kwds) +{ + int boolArg; + + if (!PyArg_ParseTuple(args, "i", &boolArg)) { + return NULL; + } + + m_allow3D = !(boolArg == 0); + + Py_Return; +} + +/* eof */ diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h new file mode 100644 index 00000000000..cbb9892706e --- /dev/null +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -0,0 +1,85 @@ +// +// Add object to the game world on action of this actuator +// +// $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_TrackToActuator +#define __KX_TrackToActuator + +#include "SCA_IActuator.h" +#include "SCA_IObject.h" + +class KX_TrackToActuator : public SCA_IActuator +{ + Py_Header; + // Object reference. Actually, we use the object's 'life' + SCA_IObject* m_object; + // 3d toggle + bool m_allow3D; + // time field + int m_time; + int m_trackTime; + int m_trackflag; + int m_upflag; + public: + KX_TrackToActuator(SCA_IObject* gameobj, SCA_IObject *ob, int time, + bool threedee,int trackflag,int upflag, PyTypeObject* T=&Type); + virtual ~KX_TrackToActuator(); + virtual CValue* GetReplica() { + KX_TrackToActuator* replica = new KX_TrackToActuator(*this); + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; + }; + + virtual bool Update(double curtime,double deltatime); + + /* Python part */ + virtual PyObject* _getattr(char *attr); + + /* 1. setObject */ + KX_PYMETHOD_DOC(KX_TrackToActuator,SetObject); + /* 2. getObject */ + KX_PYMETHOD_DOC(KX_TrackToActuator,GetObject); + /* 3. setTime */ + KX_PYMETHOD_DOC(KX_TrackToActuator,SetTime); + /* 4. getTime */ + KX_PYMETHOD_DOC(KX_TrackToActuator,GetTime); + /* 5. getUse3D */ + KX_PYMETHOD_DOC(KX_TrackToActuator,GetUse3D); + /* 6. setUse3D */ + KX_PYMETHOD_DOC(KX_TrackToActuator,SetUse3D); + +}; /* end of class KX_TrackToActuator : public KX_EditObjectActuator */ + +#endif diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp new file mode 100644 index 00000000000..2f61ef7a630 --- /dev/null +++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp @@ -0,0 +1,217 @@ +/** + * $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_VertexProxy.h" + +#include "RAS_TexVert.h" + + +PyTypeObject KX_VertexProxy::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_VertexProxy", + sizeof(KX_VertexProxy), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject KX_VertexProxy::Parents[] = { + &KX_VertexProxy::Type, + &SCA_IObject::Type, + &CValue::Type, + NULL +}; + +PyMethodDef KX_VertexProxy::Methods[] = { +{"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_VARARGS}, +{"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_VARARGS}, +{"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_VARARGS}, +{"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_VARARGS}, +{"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_VARARGS}, +{"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_VARARGS}, +{"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_VARARGS}, +{"setNormal", (PyCFunction)KX_VertexProxy::sPySetNormal,METH_VARARGS}, + {NULL,NULL} //Sentinel +}; + +PyObject* +KX_VertexProxy::_getattr(char* attr) +{ + _getattr_up(SCA_IObject); +} + + + +KX_VertexProxy::KX_VertexProxy(RAS_TexVert* vertex) +:m_vertex(vertex) +{ + +} + +KX_VertexProxy::~KX_VertexProxy() +{ + +} + + + +// stuff for cvalue related things +CValue* KX_VertexProxy::Calc(VALUE_OPERATOR op, CValue *val) { return NULL;} +CValue* KX_VertexProxy::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) { return NULL;} +STR_String sVertexName="vertex"; +const STR_String & KX_VertexProxy::GetText() {return sVertexName;}; +float KX_VertexProxy::GetNumber() { return -1;} +STR_String KX_VertexProxy::GetName() { return sVertexName;} +void KX_VertexProxy::SetName(STR_String name) { }; +CValue* KX_VertexProxy::GetReplica() { return NULL;} +void KX_VertexProxy::ReplicaSetName(STR_String name) {}; + + +// stuff for python integration + +PyObject* KX_VertexProxy::PyGetXYZ(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + MT_Point3 pos = m_vertex->getLocalXYZ(); + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index])); + } + + return resultlist; + +} + +PyObject* KX_VertexProxy::PySetXYZ(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + MT_Point3 pos = ConvertPythonVectorArg(args); + m_vertex->SetXYZ(pos); + + + Py_Return; +} + +PyObject* KX_VertexProxy::PyGetNormal(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + + const short* shortnormal = m_vertex->getNormal(); + MT_Vector3 normal(shortnormal[0],shortnormal[1],shortnormal[2]); + normal.normalize(); + + PyObject* resultlist = PyList_New(3); + int index; + for (index=0;index<3;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(normal[index])); + } + + return resultlist; + +} + +PyObject* KX_VertexProxy::PySetNormal(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + MT_Point3 normal = ConvertPythonVectorArg(args); + m_vertex->SetNormal(normal); + Py_Return; +} + + +PyObject* KX_VertexProxy::PyGetRGBA(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int rgba = m_vertex->getRGBA(); + return PyInt_FromLong(rgba); +} + +PyObject* KX_VertexProxy::PySetRGBA(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + int rgba; + if (PyArg_ParseTuple(args,"i",&rgba)) + { + m_vertex->SetRGBA(rgba); + } + Py_Return; +} + + +PyObject* KX_VertexProxy::PyGetUV(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + MT_Vector2 uv = m_vertex->getUV1(); + PyObject* resultlist = PyList_New(2); + int index; + for (index=0;index<2;index++) + { + PyList_SetItem(resultlist,index,PyFloat_FromDouble(uv[index])); + } + + return resultlist; + +} + +PyObject* KX_VertexProxy::PySetUV(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + MT_Point3 uv = ConvertPythonVectorArg(args); + m_vertex->SetUV(MT_Point2(uv[0],uv[1])); + Py_Return; +} + + + diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h new file mode 100644 index 00000000000..f23a2d6941c --- /dev/null +++ b/source/gameengine/Ketsji/KX_VertexProxy.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_VERTEXPROXY +#define __KX_VERTEXPROXY + +#include "SCA_IObject.h" + +class KX_VertexProxy : public SCA_IObject +{ + Py_Header; + + class RAS_TexVert* m_vertex; +public: + KX_VertexProxy(class RAS_TexVert* vertex); + virtual ~KX_VertexProxy(); + + // stuff for cvalue related things + CValue* Calc(VALUE_OPERATOR op, CValue *val) ; + CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val); + const STR_String & GetText(); + float GetNumber(); + STR_String GetName(); + void SetName(STR_String name); // Set the name of the value + void ReplicaSetName(STR_String name); + CValue* GetReplica(); + + +// stuff for python integration + virtual PyObject* _getattr(char *attr); + + KX_PYMETHOD(KX_VertexProxy,GetXYZ); + KX_PYMETHOD(KX_VertexProxy,SetXYZ); + KX_PYMETHOD(KX_VertexProxy,GetUV); + KX_PYMETHOD(KX_VertexProxy,SetUV); + KX_PYMETHOD(KX_VertexProxy,GetRGBA); + KX_PYMETHOD(KX_VertexProxy,SetRGBA); + KX_PYMETHOD(KX_VertexProxy,GetNormal); + KX_PYMETHOD(KX_VertexProxy,SetNormal); + +}; +#endif //__KX_VERTEXPROXY diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp new file mode 100644 index 00000000000..c39775f4391 --- /dev/null +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp @@ -0,0 +1,161 @@ +/* + * $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 ***** + * Actuator to toggle visibility/invisibility of objects + */ + +#include "KX_VisibilityActuator.h" +#include "KX_GameObject.h" + +KX_VisibilityActuator::KX_VisibilityActuator( + SCA_IObject* gameobj, + bool visible, + PyTypeObject* T + ) + : SCA_IActuator(gameobj,T), + m_visible(visible) +{ + // intentionally empty +} + +KX_VisibilityActuator::~KX_VisibilityActuator( + void + ) +{ + // intentionally empty +} + +CValue* +KX_VisibilityActuator::GetReplica( + void + ) +{ + KX_VisibilityActuator* replica = new KX_VisibilityActuator(*this); + replica->ProcessReplica(); + // this will copy properties and so on... + CValue::AddDataToReplica(replica); + return replica; +} + +bool +KX_VisibilityActuator::Update( + double curtime, + double deltatime + ) +{ + bool bNegativeEvent = IsNegativeEvent(); + + RemoveAllEvents(); + if (bNegativeEvent) return false; + + KX_GameObject *obj = (KX_GameObject*) GetParent(); + + obj->SetVisible(m_visible); + obj->MarkVisible(); + + return true; +} + +/* ------------------------------------------------------------------------- */ +/* Python functions */ +/* ------------------------------------------------------------------------- */ + + + +/* Integration hooks ------------------------------------------------------- */ +PyTypeObject +KX_VisibilityActuator::Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "KX_VisibilityActuator", + sizeof(KX_VisibilityActuator), + 0, + PyDestructor, + 0, + __getattr, + __setattr, + 0, //&MyPyCompare, + __repr, + 0, //&cvalue_as_number, + 0, + 0, + 0, + 0 +}; + +PyParentObject +KX_VisibilityActuator::Parents[] = { + &KX_VisibilityActuator::Type, + &SCA_IActuator::Type, + &SCA_ILogicBrick::Type, + &CValue::Type, + NULL +}; + +PyMethodDef +KX_VisibilityActuator::Methods[] = { + {"set", (PyCFunction) KX_VisibilityActuator::sPySetVisible, + METH_VARARGS, SetVisible_doc}, + {NULL,NULL} //Sentinel +}; + +PyObject* +KX_VisibilityActuator::_getattr( + char* attr + ) +{ + _getattr_up(SCA_IActuator); +}; + + + +/* set visibility ---------------------------------------------------------- */ +char +KX_VisibilityActuator::SetVisible_doc[] = +"setVisible(visible?)\n" +"\t - visible? : Make the object visible? (KX_TRUE, KX_FALSE)" +"\tSet the properties of the actuator.\n"; +PyObject* + +KX_VisibilityActuator::PySetVisible(PyObject* self, + PyObject* args, + PyObject* kwds) { + int vis; + + if(!PyArg_ParseTuple(args, "i", &vis)) { + return NULL; + } + + m_visible = PyArgToBool(vis); + + Py_Return; +} + + diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h new file mode 100644 index 00000000000..1c079eee967 --- /dev/null +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h @@ -0,0 +1,80 @@ +/* + * $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 ***** + * Actuator to toggle visibility/invisibility of objects + */ + +#ifndef __KX_VISIBILITYACTUATOR +#define __KX_VISIBILITYACTUATOR + +#include "SCA_IActuator.h" + +class KX_VisibilityActuator : public SCA_IActuator +{ + Py_Header; + + /** Make visible? */ + bool m_visible; + + public: + + KX_VisibilityActuator( + SCA_IObject* gameobj, + bool visible, + PyTypeObject* T=&Type + ); + + virtual + ~KX_VisibilityActuator( + void + ); + + virtual CValue* + GetReplica( + void + ); + + virtual bool + Update( + double curtime, + double deltatime + ); + + /* --------------------------------------------------------------------- */ + /* Python interface ---------------------------------------------------- */ + /* --------------------------------------------------------------------- */ + + virtual PyObject* _getattr(char *attr); + //KX_PYMETHOD_DOC + KX_PYMETHOD_DOC(KX_VisibilityActuator,SetVisible); + +}; + +#endif diff --git a/source/gameengine/Ketsji/KX_WorldInfo.cpp b/source/gameengine/Ketsji/KX_WorldInfo.cpp new file mode 100644 index 00000000000..4c1884572e5 --- /dev/null +++ b/source/gameengine/Ketsji/KX_WorldInfo.cpp @@ -0,0 +1,38 @@ +/** + * $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_WorldInfo.h" + + +KX_WorldInfo::~KX_WorldInfo() +{ +} + diff --git a/source/gameengine/Ketsji/KX_WorldInfo.h b/source/gameengine/Ketsji/KX_WorldInfo.h new file mode 100644 index 00000000000..7bcf4bb1589 --- /dev/null +++ b/source/gameengine/Ketsji/KX_WorldInfo.h @@ -0,0 +1,65 @@ +/** + * $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_WORLDINFO_H +#define __KX_WORLDINFO_H + +#include "MT_Scalar.h" + + +class MT_CmMatrix4x4; + + +class KX_WorldInfo +{ +public: + KX_WorldInfo(){} + virtual ~KX_WorldInfo(); + + virtual bool hasWorld()=0; + virtual bool hasMist()=0; + virtual float getBackColorRed()=0; + virtual float getBackColorGreen()=0; + virtual float getBackColorBlue()=0; + virtual float getMistStart()=0; + virtual float getMistDistance()=0; + virtual float getMistColorRed()=0; + virtual float getMistColorGreen()=0; + virtual float getMistColorBlue()=0; + + virtual void setMistStart(float)=0; + virtual void setMistDistance(float)=0; + virtual void setMistColorRed(float)=0; + virtual void setMistColorGreen(float)=0; + virtual void setMistColorBlue(float)=0; +}; + +#endif //__KX_WORLDINFO_H diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.cpp b/source/gameengine/Ketsji/KX_WorldIpoController.cpp new file mode 100644 index 00000000000..c4907a29a7a --- /dev/null +++ b/source/gameengine/Ketsji/KX_WorldIpoController.cpp @@ -0,0 +1,111 @@ +/** + * $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_WorldIpoController.h" + +#include "KX_ScalarInterpolator.h" +#include "KX_WorldInfo.h" + +bool KX_WorldIpoController::Update(double currentTime) +{ + if (m_modified) + { + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + (*i)->Execute(m_ipotime);//currentTime); + } + + KX_WorldInfo *world; + + if (m_modify_mist_start) { + world->setMistStart(m_mist_start); + } + + if (m_modify_mist_color) { + world->setMistColorRed(m_mist_rgb[0]); + world->setMistColorGreen(m_mist_rgb[1]); + world->setMistColorBlue(m_mist_rgb[2]); + } + + if (m_modify_mist_dist) { + world->setMistDistance(m_mist_dist); + } + + m_modified=false; + } + return false; +} + + +void KX_WorldIpoController::AddInterpolator(KX_IInterpolator* interp) +{ + this->m_interpolators.push_back(interp); +} + + +SG_Controller* KX_WorldIpoController::GetReplica(class SG_Node* destnode) +{ + KX_WorldIpoController* iporeplica = new KX_WorldIpoController(*this); + // clear object that ipo acts on + iporeplica->ClearObject(); + + // dirty hack, ask Gino for a better solution in the ipo implementation + // hacken en zagen, in what we call datahiding, not written for replication :( + + T_InterpolatorList oldlist = m_interpolators; + iporeplica->m_interpolators.clear(); + + T_InterpolatorList::iterator i; + for (i = oldlist.begin(); !(i == oldlist.end()); ++i) { + KX_ScalarInterpolator* copyipo = new KX_ScalarInterpolator(*((KX_ScalarInterpolator*)*i)); + iporeplica->AddInterpolator(copyipo); + + MT_Scalar* scaal = ((KX_ScalarInterpolator*)*i)->GetTarget(); + int orgbase = (int)this; + int orgloc = (int)scaal; + int offset = orgloc-orgbase; + int newaddrbase = (int)iporeplica + offset; + MT_Scalar* blaptr = (MT_Scalar*) newaddrbase; + copyipo->SetNewTarget((MT_Scalar*)blaptr); + } + + return iporeplica; +} + +KX_WorldIpoController::~KX_WorldIpoController() +{ + + T_InterpolatorList::iterator i; + for (i = m_interpolators.begin(); !(i == m_interpolators.end()); ++i) { + delete (*i); + } + +} diff --git a/source/gameengine/Ketsji/KX_WorldIpoController.h b/source/gameengine/Ketsji/KX_WorldIpoController.h new file mode 100644 index 00000000000..36b457adfda --- /dev/null +++ b/source/gameengine/Ketsji/KX_WorldIpoController.h @@ -0,0 +1,99 @@ +/** + * $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_WORLDIPOCONTROLLER_H +#define KX_WORLDIPOCONTROLLER_H + +#include "SG_Controller.h" +#include "SG_Spatial.h" + +#include "KX_IInterpolator.h" + +class KX_WorldIpoController : public SG_Controller +{ +public: + MT_Scalar m_mist_rgb[3]; + MT_Scalar m_mist_start; + MT_Scalar m_mist_dist; + +private: + T_InterpolatorList m_interpolators; + unsigned short m_modify_mist_color : 1; + unsigned short m_modify_mist_start : 1; + unsigned short m_modify_mist_dist : 1; + bool m_modified; + + double m_ipotime; + +public: + KX_WorldIpoController() : m_ipotime(0.0), + m_modify_mist_color(false), + m_modify_mist_start(false), + m_modify_mist_dist(false), + m_modified(true) + {} + + virtual ~KX_WorldIpoController(); + + virtual SG_Controller* GetReplica(class SG_Node* destnode); + + virtual bool Update(double time); + + virtual void SetSimulatedTime(double time) { + m_ipotime = time; + m_modified = true; + } + + void SetModifyMistStart(bool modify) { + m_modify_mist_start = modify; + } + + void SetModifyMistColor(bool modify) { + m_modify_mist_color = modify; + } + + void SetModifyMistDist(bool modify) { + m_modify_mist_dist = modify; + } + + void + SetOption( + int option, + int value + ){ + // intentionally empty + }; + + void AddInterpolator(KX_IInterpolator* interp); +}; + +#endif // KX_LIGHTIPOSGCONTROLLER_H + diff --git a/source/gameengine/Ketsji/Makefile b/source/gameengine/Ketsji/Makefile new file mode 100644 index 00000000000..4e0ee06fe1a --- /dev/null +++ b/source/gameengine/Ketsji/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 = ketsji +DIR = $(OCGDIR)/gameengine/$(LIBNAME) + +include nan_compile.mk + +CCFLAGS += $(LEVEL_1_CPP_WARNINGS) + +CPPFLAGS += $(OGL_CPPFLAGS) +CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION) +CPPFLAGS += -I$(NAN_STRING)/include +CPPFLAGS += -I$(NAN_FUZZICS)/include -I$(NAN_SUMO)/include -I$(NAN_MOTO)/include +CPPFLAGS += -I../Rasterizer -I../GameLogic -I../SceneGraph +CPPFLAGS += -I../BlenderRoutines -I../SoundSystem -I../Expressions +CPPFLAGS += -I../../kernel/gen_system +CPPFLAGS += -I../Network -IKXNetwork +CPPFLAGS += -I../Physics/common +CPPFLAGS += -I../Physics/Dummy +CPPFLAGS += -I../Physics/Sumo +CPPFLAGS += -I. + +########################### + +SOURCEDIR = source/gameengine/Ketsji +DIRS = KXNetwork + +include nan_subdirs.mk + |