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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2008-07-16 11:10:33 +0400
committerCampbell Barton <ideasman42@gmail.com>2008-07-16 11:10:33 +0400
commitaf4262d03f1aef005b36f98d79c3eff55d349a62 (patch)
tree14780e35e604b53ff383c1d58f17c4509cea67e3 /source
parent1c2fd65ddbc2c448dfdd2668ffb66c5807a098e9 (diff)
svn merge -r15566:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'source')
-rw-r--r--source/blender/src/buttons_scene.c72
-rw-r--r--source/blender/src/transform_conversions.c2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp243
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h8
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp9
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp124
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h1
-rw-r--r--source/gameengine/Rasterizer/Makefile3
9 files changed, 409 insertions, 57 deletions
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index af90d01fb59..3b0167d673c 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -137,36 +137,42 @@ static void load_new_sample(char *str) /* called from fileselect */
bSample *sample, *newsample;
sound = G.buts->lockpoin;
+
+ /* No Sound or Selected the same sample as we alredy have, just ignore */
+ if (sound==NULL || str==sound->name)
+ return;
+
+ if (sizeof(sound->sample->name) < strlen(str)) {
+ error("Path too long: %s", str);
+ return;
+ }
+
+ // save values
+ sample = sound->sample;
+ strcpy(name, sound->sample->name);
+ strcpy(sound->name, str);
+ sound_set_sample(sound, NULL);
+ sound_initialize_sample(sound);
- if (sound) {
- // save values
- sample = sound->sample;
- strcpy(name, sound->sample->name);
-
- strcpy(sound->name, str);
- sound_set_sample(sound, NULL);
- sound_initialize_sample(sound);
-
- if (sound->sample->type == SAMPLE_INVALID) {
- error("Not a valid sample: %s", str);
+ if (sound->sample->type == SAMPLE_INVALID) {
+ error("Not a valid sample: %s", str);
- newsample = sound->sample;
+ newsample = sound->sample;
- // restore values
- strcpy(sound->name, name);
- sound_set_sample(sound, sample);
+ // restore values
+ strcpy(sound->name, name);
+ sound_set_sample(sound, sample);
- // remove invalid sample
+ // remove invalid sample
- sound_free_sample(newsample);
- BLI_remlink(samples, newsample);
- MEM_freeN(newsample);
- }
+ sound_free_sample(newsample);
+ BLI_remlink(samples, newsample);
+ MEM_freeN(newsample);
+ return;
}
-
+
BIF_undo_push("Load new audio file");
allqueue(REDRAWBUTSSCENE, 0);
-
}
@@ -403,7 +409,7 @@ static void sound_panel_sound(bSound *sound)
sample = sound->sample;
/* info string */
- if (sound->sample && sound->sample->len) {
+ if (sound->sample && sound->sample->len && sound->sample->channels && sound->sample->bits) {
char *tmp;
if (sound->sample->channels == 1) tmp= "Mono";
else if (sound->sample->channels == 2) tmp= "Stereo";
@@ -1174,18 +1180,18 @@ static void seq_panel_proxy()
130,140,120,19, &last_seq->flag,
0.0, 21.0, 100, 0,
"Use a custom directory to store data");
- }
- if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
- uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_DIR,
- ICON_FILESEL, 10, 120, 20, 20, 0, 0, 0, 0, 0,
- "Select the directory/name for "
- "the proxy storage");
+ if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+ uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_DIR,
+ ICON_FILESEL, 10, 120, 20, 20, 0, 0, 0, 0, 0,
+ "Select the directory/name for "
+ "the proxy storage");
- uiDefBut(block, TEX,
- B_SEQ_BUT_RELOAD, "Dir: ",
- 30,120,220,20, last_seq->strip->proxy->dir,
- 0.0, 160.0, 100, 0, "");
+ uiDefBut(block, TEX,
+ B_SEQ_BUT_RELOAD, "Dir: ",
+ 30,120,220,20, last_seq->strip->proxy->dir,
+ 0.0, 160.0, 100, 0, "");
+ }
}
if (last_seq->flag & SEQ_USE_PROXY) {
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 31a59601448..0cb138712c5 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -3887,7 +3887,7 @@ void special_aftertrans_update(TransInfo *t)
}
}
}
- else if (t->spacetype == SPACE_ACTION) {
+ if (t->spacetype == SPACE_ACTION) {
void *data;
short datatype;
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 78dcb0568d0..d9d2a7f3c23 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1845,7 +1845,10 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
int aspect_width;
int aspect_height;
vector<MT_Vector3> inivel,iniang;
-
+ set<Group*> grouplist; // list of groups to be converted
+ set<Object*> allblobj; // all objects converted
+ set<Object*> groupobj; // objects from groups (never in active layer)
+
if (alwaysUseExpandFraming) {
frame_type = RAS_FrameSettings::e_frame_extend;
aspect_width = canvas->GetWidth();
@@ -1917,6 +1920,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
for (SETLOOPER(blenderscene, base))
{
Object* blenderobject = base->object;
+ allblobj.insert(blenderobject);
+
KX_GameObject* gameobj = gameobject_from_blenderobject(
base->object,
kxscene,
@@ -2044,7 +2049,9 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->NodeUpdateGS(0,true);
gameobj->Bucketize();
-
+
+ if (gameobj->IsDupliGroup())
+ grouplist.insert(blenderobject->dup_group);
}
else
{
@@ -2071,6 +2078,188 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
+ if (!grouplist.empty())
+ {
+ // now convert the group referenced by dupli group object
+ // keep track of all groups already converted
+ set<Group*> allgrouplist = grouplist;
+ set<Group*> tempglist;
+ // recurse
+ while (!grouplist.empty())
+ {
+ set<Group*>::iterator git;
+ tempglist.clear();
+ tempglist.swap(grouplist);
+ for (git=tempglist.begin(); git!=tempglist.end(); git++)
+ {
+ Group* group = *git;
+ GroupObject* go;
+ for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
+ {
+ Object* blenderobject = go->ob;
+ if (converter->FindGameObject(blenderobject) == NULL)
+ {
+ allblobj.insert(blenderobject);
+ groupobj.insert(blenderobject);
+ KX_GameObject* gameobj = gameobject_from_blenderobject(
+ blenderobject,
+ kxscene,
+ rendertools,
+ converter,
+ blenderscene);
+
+ // this code is copied from above except that
+ // object from groups are never is active layer
+ bool isInActiveLayer = false;
+ bool addobj=true;
+
+ if (converter->addInitFromFrame)
+ if (!isInActiveLayer)
+ addobj=false;
+
+ if (gameobj&&addobj)
+ {
+ MT_Point3 posPrev;
+ MT_Matrix3x3 angor;
+ if (converter->addInitFromFrame)
+ blenderscene->r.cfra=blenderscene->r.sfra;
+
+ MT_Point3 pos = MT_Point3(
+ blenderobject->loc[0]+blenderobject->dloc[0],
+ blenderobject->loc[1]+blenderobject->dloc[1],
+ blenderobject->loc[2]+blenderobject->dloc[2]
+ );
+ MT_Vector3 eulxyz = MT_Vector3(
+ blenderobject->rot[0],
+ blenderobject->rot[1],
+ blenderobject->rot[2]
+ );
+ MT_Vector3 scale = MT_Vector3(
+ blenderobject->size[0],
+ blenderobject->size[1],
+ blenderobject->size[2]
+ );
+ if (converter->addInitFromFrame){//rcruiz
+ float eulxyzPrev[3];
+ blenderscene->r.cfra=blenderscene->r.sfra-1;
+ update_for_newframe();
+ MT_Vector3 tmp=pos-MT_Point3(blenderobject->loc[0]+blenderobject->dloc[0],
+ blenderobject->loc[1]+blenderobject->dloc[1],
+ blenderobject->loc[2]+blenderobject->dloc[2]
+ );
+ eulxyzPrev[0]=blenderobject->rot[0];
+ eulxyzPrev[1]=blenderobject->rot[1];
+ eulxyzPrev[2]=blenderobject->rot[2];
+
+ double fps = (double) blenderscene->r.frs_sec/
+ (double) blenderscene->r.frs_sec_base;
+
+ tmp.scale(fps, fps, fps);
+ inivel.push_back(tmp);
+ tmp=eulxyz-eulxyzPrev;
+ tmp.scale(fps, fps, fps);
+ iniang.push_back(tmp);
+ blenderscene->r.cfra=blenderscene->r.sfra;
+ update_for_newframe();
+ }
+
+ gameobj->NodeSetLocalPosition(pos);
+ gameobj->NodeSetLocalOrientation(MT_Matrix3x3(eulxyz));
+ gameobj->NodeSetLocalScale(scale);
+ gameobj->NodeUpdateGS(0,true);
+
+ BL_ConvertIpos(blenderobject,gameobj,converter);
+ // TODO: expand to multiple ipos per mesh
+ Material *mat = give_current_material(blenderobject, 1);
+ if(mat) BL_ConvertMaterialIpos(mat, gameobj, converter);
+
+ sumolist->Add(gameobj->AddRef());
+
+ BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
+
+
+ gameobj->SetName(blenderobject->id.name);
+
+ // templist to find Root Parents (object with no parents)
+ templist->Add(gameobj->AddRef());
+
+ // update children/parent hierarchy
+ if ((blenderobject->parent != 0)&&(!converter->addInitFromFrame))
+ {
+ // blender has an additional 'parentinverse' offset in each object
+ SG_Node* parentinversenode = new SG_Node(NULL,NULL,SG_Callbacks());
+
+ // define a normal parent relationship for this node.
+ KX_NormalParentRelation * parent_relation = KX_NormalParentRelation::New();
+ parentinversenode->SetParentRelation(parent_relation);
+
+ parentChildLink pclink;
+ pclink.m_blenderchild = blenderobject;
+ pclink.m_gamechildnode = parentinversenode;
+ vec_parent_child.push_back(pclink);
+
+ float* fl = (float*) blenderobject->parentinv;
+ MT_Transform parinvtrans(fl);
+ parentinversenode->SetLocalPosition(parinvtrans.getOrigin());
+ parentinversenode->SetLocalOrientation(parinvtrans.getBasis());
+
+ parentinversenode->AddChild(gameobj->GetSGNode());
+ }
+
+ // needed for python scripting
+ logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
+
+ // needed for dynamic object morphing
+ logicmgr->RegisterGameObj(gameobj, blenderobject);
+ for (int i = 0; i < gameobj->GetMeshCount(); i++)
+ logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
+
+ converter->RegisterGameObject(gameobj, blenderobject);
+ // this was put in rapidly, needs to be looked at more closely
+ // only draw/use objects in active 'blender' layers
+
+ logicbrick_conversionlist->Add(gameobj->AddRef());
+
+ if (converter->addInitFromFrame){
+ posPrev=gameobj->NodeGetWorldPosition();
+ angor=gameobj->NodeGetWorldOrientation();
+ }
+ if (isInActiveLayer)
+ {
+ objectlist->Add(gameobj->AddRef());
+ //tf.Add(gameobj->GetSGNode());
+
+ gameobj->NodeUpdateGS(0,true);
+ gameobj->Bucketize();
+
+ }
+ else
+ {
+ //we must store this object otherwise it will be deleted
+ //at the end of this function if it is not a root object
+ inactivelist->Add(gameobj->AddRef());
+
+ }
+ if (gameobj->IsDupliGroup())
+ {
+ // check that the group is not already converted
+ if (allgrouplist.insert(blenderobject->dup_group).second)
+ grouplist.insert(blenderobject->dup_group);
+ }
+ if (converter->addInitFromFrame){
+ gameobj->NodeSetLocalPosition(posPrev);
+ gameobj->NodeSetLocalOrientation(angor);
+ }
+
+ }
+ if (gameobj)
+ gameobj->Release();
+ }
+ }
+ }
+ }
+ }
+
if (blenderscene->camera) {
KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
@@ -2079,15 +2268,18 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
// Set up armatures
- for(SETLOOPER(blenderscene, base)){
- if (base->object->type==OB_MESH){
- Mesh *me = (Mesh*)base->object->data;
+ set<Object*>::iterator oit;
+ for(oit=allblobj.begin(); oit!=allblobj.end(); oit++)
+ {
+ Object* blenderobj = *oit;
+ if (blenderobj->type==OB_MESH){
+ Mesh *me = (Mesh*)blenderobj->data;
if (me->dvert){
- KX_GameObject *obj = converter->FindGameObject(base->object);
+ KX_GameObject *obj = converter->FindGameObject(blenderobj);
- if (base->object->parent && base->object->parent->type==OB_ARMATURE && base->object->partype==PARSKEL){
- KX_GameObject *par = converter->FindGameObject(base->object->parent);
+ if (obj && blenderobj->parent && blenderobj->parent->type==OB_ARMATURE && blenderobj->partype==PARSKEL){
+ KX_GameObject *par = converter->FindGameObject(blenderobj->parent);
if (par)
((BL_SkinDeformer*)(((BL_DeformableGameObject*)obj)->m_pDeformer))->SetArmature((BL_ArmatureObject*) par);
}
@@ -2172,7 +2364,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
{
meshobj = gameobj->GetMesh(0);
}
- BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter,processCompoundChildren);
+ int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
+ BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
}
processCompoundChildren = true;
@@ -2187,7 +2380,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
{
meshobj = gameobj->GetMesh(0);
}
- BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,activeLayerBitInfo,physics_engine,converter,processCompoundChildren);
+ int layerMask = (groupobj.find(blenderobject) == groupobj.end()) ? activeLayerBitInfo : 0;
+ BL_CreatePhysicsObjectNew(gameobj,blenderobject,meshobj,kxscene,layerMask,physics_engine,converter,processCompoundChildren);
}
@@ -2309,22 +2503,25 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
- bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
- BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, activeLayerBitInfo,isInActiveLayer,rendertools,converter);
+ int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
+ bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
+ BL_ConvertActuators(maggie->name, blenderobj,gameobj,logicmgr,kxscene,ketsjiEngine,executePriority, layerMask,isInActiveLayer,rendertools,converter);
}
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
- bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
- BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,activeLayerBitInfo,isInActiveLayer,converter);
+ int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
+ bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
+ BL_ConvertControllers(blenderobj,gameobj,logicmgr,pythondictionary,executePriority,layerMask,isInActiveLayer,converter);
}
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
- bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
- BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter);
+ int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
+ bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
+ BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,layerMask,isInActiveLayer,canvas,converter);
}
// apply the initial state to controllers
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
@@ -2342,5 +2539,19 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// Calculate the scene btree -
// too slow - commented out.
//kxscene->SetNodeTree(tf.MakeTree());
+
+ // instantiate dupli group, we will loop trough the object
+ // that are in active layers. Note that duplicating group
+ // has the effect of adding objects at the end of objectlist.
+ // Only loop through the first part of the list.
+ int objcount = objectlist->GetCount();
+ for (i=0;i<objcount;i++)
+ {
+ KX_GameObject* gameobj = (KX_GameObject*) objectlist->GetValue(i);
+ if (gameobj->IsDupliGroup())
+ {
+ kxscene->DupliGroupRecurse(gameobj, 0);
+ }
+ }
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index ddbf863aa1a..eba154e1094 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -47,6 +47,7 @@
#include "KX_Scene.h"
#include "KX_KetsjiEngine.h" /* for m_anim_framerate */
#include "KX_IPhysicsController.h" /* for suspend/resume */
+#include "DNA_object_types.h"
#define KX_OB_DYNAMIC 1
@@ -392,6 +393,13 @@ public:
m_pBlenderObject = obj;
}
+ bool IsDupliGroup()
+ {
+ return (m_pBlenderObject &&
+ (m_pBlenderObject->transflag & OB_DUPLIGROUP) &&
+ m_pBlenderObject->dup_group != NULL) ? true : false;
+ }
+
/**
* Set the Scene graph node for this game object.
* warning - it is your responsibility to make sure
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index d69871275b9..89699d80031 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -135,9 +135,6 @@ CValue* KX_NearSensor::GetReplica()
void KX_NearSensor::ReParent(SCA_IObject* parent)
{
-
- SCA_ISensor::ReParent(parent);
-
m_client_info->m_gameobject = static_cast<KX_GameObject*>(parent);
m_client_info->m_sensors.push_back(this);
@@ -151,6 +148,7 @@ void KX_NearSensor::ReParent(SCA_IObject* parent)
*/
((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
SynchronizeTransform();
+ SCA_ISensor::ReParent(parent);
}
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index 987e0b946b2..bf2ba18f490 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -80,10 +80,7 @@ CValue* KX_RadarSensor::GetReplica()
{
KX_RadarSensor* replica = new KX_RadarSensor(*this);
replica->m_colliders = new CListValue();
- replica->m_bCollision = false;
- replica->m_bTriggered= false;
- replica->m_hitObject = NULL;
- replica->m_bLastTriggered = false;
+ replica->Init();
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
@@ -92,6 +89,10 @@ CValue* KX_RadarSensor::GetReplica()
if (replica->m_physCtrl)
{
replica->m_physCtrl = replica->m_physCtrl->GetReplica();
+ if (replica->m_physCtrl)
+ {
+ replica->m_physCtrl->setNewClientInfo(replica->m_client_info);
+ }
}
//todo: make sure replication works fine!
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index c14dc0aa257..35461027a8f 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -67,6 +67,8 @@
#include "SG_Controller.h"
#include "SG_IObject.h"
#include "SG_Tree.h"
+#include "DNA_group_types.h"
+#include "BKE_anim.h"
#include "KX_SG_NodeRelationships.h"
@@ -606,6 +608,128 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
newobj->ResetState();
}
+void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
+{
+ KX_GameObject* groupobj = (KX_GameObject*) obj;
+ KX_GameObject* replica;
+ Object* blgroupobj = groupobj->GetBlenderObject();
+ Group* group;
+ GroupObject *go;
+ vector<KX_GameObject*> duplilist;
+
+ if (!groupobj->IsDupliGroup() ||
+ level>MAX_DUPLI_RECUR)
+ return;
+
+ // we will add one group at a time
+ m_logicHierarchicalGameObjects.clear();
+ m_map_gameobject_to_replica.clear();
+ m_ueberExecutionPriority++;
+
+ group = blgroupobj->dup_group;
+ for(go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
+ {
+ Object* blenderobj = go->ob;
+ if (blgroupobj == blenderobj)
+ // this check is also in group_duplilist()
+ continue;
+ KX_GameObject* gameobj = m_sceneConverter->FindGameObject(blenderobj);
+ if (gameobj == NULL)
+ {
+ // this object has not been converted!!!
+ // Should not happen as dupli group are created automatically
+ continue;
+ }
+ if (gameobj->GetParent() != NULL)
+ {
+ // this object is not a top parent. Either it is the child of another
+ // object in the group and it will be added automatically when the parent
+ // is added. Or it is the child of an object outside the group and the group
+ // is inconsistent, skip it anyway
+ continue;
+ }
+ if (blenderobj->lay & group->layer==0)
+ {
+ // object is not visible in the 3D view, will not be instantiated
+ continue;
+ }
+ replica = (KX_GameObject*) AddNodeReplicaObject(NULL,gameobj);
+ // 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 = gameobj->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);
+ }
+ // don't replicate logic now: we assume that the objects in the group can have
+ // logic relationship, even outside parent relationship
+
+ MT_Point3 newpos = groupobj->NodeGetWorldPosition();
+ replica->NodeSetLocalPosition(newpos);
+
+ MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation();
+ replica->NodeSetLocalOrientation(newori);
+
+ // get the rootnode's scale
+ MT_Vector3 newscale = groupobj->GetSGNode()->GetRootSGParent()->GetLocalScale();
+
+ // set the replica's relative scale with the rootnode's scale
+ replica->NodeSetRelativeScale(newscale);
+
+ if (replica->GetPhysicsController())
+ {
+ replica->GetPhysicsController()->setPosition(newpos);
+ replica->GetPhysicsController()->setOrientation(newori.getRotation());
+ replica->GetPhysicsController()->setScaling(newscale);
+ }
+
+ replica->GetSGNode()->UpdateWorldData(0);
+ replica->GetSGNode()->SetBBox(gameobj->GetSGNode()->BBox());
+ replica->GetSGNode()->SetRadius(gameobj->GetSGNode()->Radius());
+ // done with replica
+ replica->Release();
+ }
+
+ // 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);
+ // add the object in the layer of the parent
+ (*git)->SetLayer(groupobj->GetLayer());
+ }
+
+ // 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));
+ }
+
+ // now look if object in the hierarchy have dupli group and recurse
+ for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
+ {
+ if ((*git) != groupobj && (*git)->IsDupliGroup())
+ // can't instantiate group immediately as it destroys m_logicHierarchicalGameObjects
+ duplilist.push_back((*git));
+ }
+
+ for (git = duplilist.begin(); !(git == duplilist.end()); ++git)
+ {
+ DupliGroupRecurse((*git), level+1);
+ }
+}
SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 28dee1b5893..374545f9a90 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -291,6 +291,7 @@ public:
* Update all transforms according to the scenegraph.
*/
void UpdateParents(double curtime);
+ void DupliGroupRecurse(CValue* gameobj, int level);
SCA_IObject* AddReplicaObject(CValue* gameobj,
CValue* locationobj,
int lifespan=0);
diff --git a/source/gameengine/Rasterizer/Makefile b/source/gameengine/Rasterizer/Makefile
index 1ca3e3b0283..e3b1f274ee5 100644
--- a/source/gameengine/Rasterizer/Makefile
+++ b/source/gameengine/Rasterizer/Makefile
@@ -41,6 +41,9 @@ CPPFLAGS += -I$(NAN_STRING)/include
CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I../../kernel/gen_system
CPPFLAGS += -I../BlenderRoutines
+CPPFLAGS += -I../Expressions
+
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
ifeq ($(OS),darwin)
CPPFLAGS += -fpascal-strings