Merging with trunk

15568 - 15963
This commit is contained in:
Martin Poirier
2008-08-05 02:27:09 +00:00
278 changed files with 11359 additions and 3367 deletions

View File

@@ -101,6 +101,13 @@ int KX_BlenderCanvas::GetHeight(
return scrarea_get_win_height(m_area);
}
RAS_Rect &
KX_BlenderCanvas::
GetWindowArea(
){
return m_area_rect;
}
void
KX_BlenderCanvas::
SetViewPort(
@@ -112,6 +119,11 @@ SetViewPort(
int minx = scrarea_get_win_x(m_area);
int miny = scrarea_get_win_y(m_area);
m_area_rect.SetLeft(minx + x1);
m_area_rect.SetBottom(miny + y1);
m_area_rect.SetRight(minx + x2);
m_area_rect.SetTop(miny + y2);
glViewport(minx + x1, miny + y1, vp_width, vp_height);
glScissor(minx + x1, miny + y1, vp_width, vp_height);
}

View File

@@ -117,6 +117,10 @@ public:
return m_displayarea;
};
RAS_Rect &
GetWindowArea(
);
void
SetViewPort(
int x1, int y1,
@@ -159,6 +163,7 @@ public:
private:
/** Blender area the game engine is running within */
struct ScrArea* m_area;
RAS_Rect m_area_rect;
};
#endif // __KX_BLENDERCANVAS

View File

@@ -170,6 +170,7 @@ void BL_RenderText(int mode,const char* textstr,int textlen,struct MTFace* tface
void DisableForText()
{
if(glIsEnabled(GL_BLEND)) glDisable(GL_BLEND);
if(glIsEnabled(GL_ALPHA_TEST)) glDisable(GL_ALPHA_TEST);
if(glIsEnabled(GL_LIGHTING)) {
glDisable(GL_LIGHTING);

View File

@@ -1,114 +0,0 @@
/**
* $Id$
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 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 LICENSE BLOCK *****
*/
#include "KX_BlenderPolyMaterial.h"
#include "BKE_mesh.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if 0
KX_BlenderPolyMaterial::KX_BlenderPolyMaterial(const STR_String &texname,
bool ba,
const STR_String& matname,
int tile,
int tilexrep,
int tileyrep,
int mode,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,
struct MTFace* tface)
: RAS_IPolyMaterial(texname,
false,
matname,
tile,
tilexrep,
tileyrep,
mode,
transparant,
zsort,
lightlayer,
bIsTriangle,
clientobject),
m_tface(tface)
{
}
void KX_BlenderPolyMaterial::Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const
{
if (GetCachingInfo() != cachingInfo)
{
if (!cachingInfo)
{
set_tpage(NULL);
}
cachingInfo = GetCachingInfo();
if ((m_drawingmode & 4)&& (rasty->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED))
{
update_realtime_texture((struct MTFace*) m_tface, rasty->GetTime());
set_tpage(m_tface);
rasty->EnableTextures(true);
}
else
{
set_tpage(NULL);
rasty->EnableTextures(false);
}
if(m_drawingmode & RAS_IRasterizer::KX_TWOSIDE)
{
rasty->SetCullFace(false);
}
else
{
rasty->SetCullFace(true);
}
if (m_drawingmode & RAS_IRasterizer::KX_LINES) {
rasty->SetLines(true);
}
else {
rasty->SetLines(false);
}
}
rasty->SetSpecularity(m_specular[0],m_specular[1],m_specular[2],m_specularity);
rasty->SetShinyness(m_shininess);
rasty->SetDiffuse(m_diffuse[0], m_diffuse[1],m_diffuse[2], 1.0);
}
#endif

View File

@@ -1,99 +0,0 @@
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 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 LICENSE BLOCK *****
*/
#ifndef __KX_BLENDERPOLYMATERIAL
#define __KX_BLENDERPOLYMATERIAL
#include "RAS_MaterialBucket.h"
#include "RAS_IRasterizer.h"
struct MTFace;
extern "C" int set_tpage(MTFace* tface); /* Worst hack ever */
#if 0
class KX_BlenderPolyMaterial : public RAS_IPolyMaterial
{
/** Blender texture face structure. */
MTFace* m_tface;
public:
KX_BlenderPolyMaterial(const STR_String &texname,
bool ba,
const STR_String& matname,
int tile,
int tilexrep,
int tileyrep,
int mode,
bool transparant,
bool zsort,
int lightlayer,
bool bIsTriangle,
void* clientobject,
struct MTFace* tface);
/**
* Returns the caching information for this material,
* This can be used to speed up the rasterizing process.
* @return The caching information.
*/
virtual TCachingInfo GetCachingInfo(void) const;
/**
* Activates the material in the (OpenGL) rasterizer.
* On entry, the cachingInfo contains info about the last activated material.
* On exit, the cachingInfo should contain updated info about this material.
* @param rasty The rasterizer in which the material should be active.
* @param cachingInfo The information about the material used to speed up rasterizing.
*/
virtual void Activate(RAS_IRasterizer* rasty, TCachingInfo& cachingInfo) const;
/**
* Returns the Blender texture face structure that is used for this material.
* @return The material's texture face.
*/
MTFace* GetMTFace(void) const;
protected:
private:
};
inline MTFace* KX_BlenderPolyMaterial::GetMTFace(void) const
{
return m_tface;
}
inline RAS_IPolyMaterial::TCachingInfo KX_BlenderPolyMaterial::GetCachingInfo(void) const
{
return GetMTFace();
}
#endif
#endif // __KX_BLENDERPOLYMATERIAL

View File

@@ -40,7 +40,6 @@
// it needs the gameobject and the sumo physics scene for a raycast
#include "KX_GameObject.h"
#include "KX_BlenderPolyMaterial.h"
#include "KX_PolygonMaterial.h"
#include "KX_BlenderMaterial.h"

View File

@@ -57,24 +57,12 @@
BL_ActionActuator::~BL_ActionActuator()
{
if (m_pose) {
free_pose_channels(m_pose);
MEM_freeN(m_pose);
m_pose = NULL;
};
if (m_userpose){
free_pose_channels(m_userpose);
MEM_freeN(m_userpose);
m_userpose=NULL;
}
if (m_blendpose) {
free_pose_channels(m_blendpose);
MEM_freeN(m_blendpose);
m_blendpose = NULL;
};
if (m_pose)
free_pose(m_pose);
if (m_userpose)
free_pose(m_userpose);
if (m_blendpose)
free_pose(m_blendpose);
}
void BL_ActionActuator::ProcessReplica(){

View File

@@ -82,10 +82,8 @@ void BL_ArmatureObject::ProcessReplica(BL_ArmatureObject *replica)
BL_ArmatureObject::~BL_ArmatureObject()
{
if (m_mrdPose){
free_pose_channels(m_mrdPose);
MEM_freeN(m_mrdPose);
}
if (m_mrdPose)
free_pose(m_mrdPose);
}
/* note, you can only call this for exisiting Armature objects, and not mix it with other Armatures */
@@ -172,12 +170,13 @@ void BL_ArmatureObject::GetMRDPose(bPose **pose)
// copy_pose (&m_mrdPose, m_pose, 0);
//}
if (!*pose)
if (!*pose) {
// must duplicate the constraints too otherwise we have corruption in free_pose_channels()
// because it will free the blender constraints.
// Ideally, blender should rememeber that the constraints were not copied so that
// free_pose_channels() would not free them.
copy_pose(pose, m_objArma->pose, 1);
}
else
extract_pose_from_pose(*pose, m_objArma->pose);

View File

@@ -136,8 +136,12 @@
#include "BKE_mesh.h"
#include "MT_Point3.h"
#include "BLI_arithb.h"
extern "C" {
#include "BKE_customdata.h"
#include "BKE_customdata.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_DerivedMesh.h"
}
#include "BKE_material.h" /* give_current_material */
@@ -309,7 +313,6 @@ typedef struct MTF_localLayer
// ------------------------------------
BL_Material* ConvertMaterial(
Mesh* mesh,
Material *mat,
MTFace* tface,
const char *tfaceName,
@@ -323,15 +326,16 @@ BL_Material* ConvertMaterial(
//this needs some type of manager
BL_Material *material = new BL_Material();
int numchan = -1;
int numchan = -1, texalpha = 0;
bool validmat = (mat!=0);
bool validface = (mesh->mtface && tface);
bool validface = (tface!=0);
short type = 0;
if( validmat )
type = 1; // material color
material->IdMode = DEFAULT_BLENDER;
material->glslmat = (validmat)? glslmat: false;
// --------------------------------
if(validmat) {
@@ -367,12 +371,13 @@ BL_Material* ConvertMaterial(
if(i==0 && facetex ) {
Image*tmp = (Image*)(tface->tpage);
if(tmp) {
material->img[i] = tmp;
material->texname[i] = material->img[i]->id.name;
material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
material->ras_mode|= ( tface->transp &(TF_ADD | TF_ALPHA))?TRANSP:0;
if(material->img[i]->flag & IMA_REFLECT)
material->mapping[i].mapping |= USEREFL;
else
@@ -430,6 +435,8 @@ BL_Material* ConvertMaterial(
material->flag[i] |= ( mttmp->mapto & MAP_ALPHA )?TEXALPHA:0;
material->flag[i] |= ( mttmp->texflag& MTEX_NEGATIVE )?TEXNEG:0;
if(!glslmat && (material->flag[i] & TEXALPHA))
texalpha = 1;
}
}
else if(mttmp->tex->type == TEX_ENVMAP) {
@@ -546,17 +553,7 @@ BL_Material* ConvertMaterial(
material->ref = mat->ref;
material->amb = mat->amb;
// set alpha testing without z-sorting
if( ( validface && (!(tface->transp &~ TF_CLIP))) && mat->mode & MA_ZTRA) {
// sets the RAS_IPolyMaterial::m_flag |RAS_FORCEALPHA
// this is so we don't have the overhead of the z-sorting code
material->ras_mode|=ALPHA_TEST;
}
else{
// use regular z-sorting
material->ras_mode |= ((mat->mode & MA_ZTRA) != 0)?ZSORT:0;
}
material->ras_mode |= ((mat->mode & MA_WIRE) != 0)?WIRE:0;
material->ras_mode |= (mat->mode & MA_WIRE)? WIRE: 0;
}
else {
int valid = 0;
@@ -574,7 +571,6 @@ BL_Material* ConvertMaterial(
material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0;
material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0;
material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0;
material->ras_mode|= ( tface->transp & (TF_ADD|TF_ALPHA))?TRANSP:0;
valid++;
}
}
@@ -607,10 +603,6 @@ BL_Material* ConvertMaterial(
material->ras_mode |= ( (tface->mode & TF_DYNAMIC)!= 0 )?COLLIDER:0;
material->transp = tface->transp;
if(tface->transp&~TF_CLIP)
material->ras_mode |= TRANSP;
material->tile = tface->tile;
material->mode = tface->mode;
@@ -631,7 +623,16 @@ BL_Material* ConvertMaterial(
material->tile = 0;
}
// with ztransp enabled, enforce alpha blending mode
if(validmat && (mat->mode & MA_ZTRA) && (material->transp == TF_SOLID))
material->transp = TF_ALPHA;
// always zsort alpha + add
if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha)
&& (material->transp != TF_CLIP)) {
material->ras_mode |= ALPHA;
material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0;
}
// get uv sets
if(validmat)
@@ -711,132 +712,54 @@ BL_Material* ConvertMaterial(
}
static void BL_ComputeTriTangentSpace(const MT_Vector3 &v1, const MT_Vector3 &v2, const MT_Vector3 &v3,
const MT_Vector2 &uv1, const MT_Vector2 &uv2, const MT_Vector2 &uv3,
MFace* mface, MT_Vector3 *tan1, MT_Vector3 *tan2)
{
MT_Vector3 dx1(v2 - v1), dx2(v3 - v1);
MT_Vector2 duv1(uv2 - uv1), duv2(uv3 - uv1);
MT_Scalar r = 1.0 / (duv1.x() * duv2.y() - duv2.x() * duv1.y());
duv1 *= r;
duv2 *= r;
MT_Vector3 sdir(duv2.y() * dx1 - duv1.y() * dx2);
MT_Vector3 tdir(duv1.x() * dx2 - duv2.x() * dx1);
tan1[mface->v1] += sdir;
tan1[mface->v2] += sdir;
tan1[mface->v3] += sdir;
tan2[mface->v1] += tdir;
tan2[mface->v2] += tdir;
tan2[mface->v3] += tdir;
}
static MT_Vector4* BL_ComputeMeshTangentSpace(Mesh* mesh)
{
MFace* mface = static_cast<MFace*>(mesh->mface);
MTFace* tface = static_cast<MTFace*>(mesh->mtface);
MT_Vector3 *tan1 = new MT_Vector3[mesh->totvert];
MT_Vector3 *tan2 = new MT_Vector3[mesh->totvert];
int v;
for (v = 0; v < mesh->totvert; v++)
{
tan1[v] = MT_Vector3(0.0, 0.0, 0.0);
tan2[v] = MT_Vector3(0.0, 0.0, 0.0);
}
for (int p = 0; p < mesh->totface; p++, mface++, tface++)
{
MT_Vector3 v1(mesh->mvert[mface->v1].co),
v2(mesh->mvert[mface->v2].co),
v3(mesh->mvert[mface->v3].co);
MT_Vector2 uv1(tface->uv[0]),
uv2(tface->uv[1]),
uv3(tface->uv[2]);
BL_ComputeTriTangentSpace(v1, v2, v3, uv1, uv2, uv3, mface, tan1, tan2);
if (mface->v4)
{
MT_Vector3 v4(mesh->mvert[mface->v4].co);
MT_Vector2 uv4(tface->uv[3]);
BL_ComputeTriTangentSpace(v1, v3, v4, uv1, uv3, uv4, mface, tan1, tan2);
}
}
MT_Vector4 *tangent = new MT_Vector4[mesh->totvert];
for (v = 0; v < mesh->totvert; v++)
{
const MT_Vector3 no(mesh->mvert[v].no[0]/32767.0,
mesh->mvert[v].no[1]/32767.0,
mesh->mvert[v].no[2]/32767.0);
// Gram-Schmidt orthogonalize
MT_Vector3 t(tan1[v] - no.cross(no.cross(tan1[v])));
if (!MT_fuzzyZero(t))
t /= t.length();
tangent[v].x() = t.x();
tangent[v].y() = t.y();
tangent[v].z() = t.z();
// Calculate handedness
tangent[v].w() = no.dot(tan1[v].cross(tan2[v])) < 0.0 ? -1.0 : 1.0;
}
delete [] tan1;
delete [] tan2;
return tangent;
}
RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools* rendertools, KX_Scene* scene, KX_BlenderSceneConverter *converter)
{
RAS_MeshObject *meshobj;
bool skinMesh = false;
bool skinMesh = false;
int lightlayer = blenderobj->lay;
MFace* mface = static_cast<MFace*>(mesh->mface);
MTFace* tface = static_cast<MTFace*>(mesh->mtface);
const char *tfaceName = "";
MCol* mmcol = mesh->mcol;
MT_assert(mface || mesh->totface == 0);
// Get DerivedMesh data
DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj);
MVert *mvert = dm->getVertArray(dm);
int totvert = dm->getNumVerts(dm);
MFace *mface = dm->getFaceArray(dm);
MTFace *tface = static_cast<MTFace*>(dm->getFaceDataArray(dm, CD_MTFACE));
MCol *mcol = static_cast<MCol*>(dm->getFaceDataArray(dm, CD_MCOL));
float (*tangent)[3] = NULL;
int totface = dm->getNumFaces(dm);
const char *tfaceName = "";
if(tface) {
DM_add_tangent_layer(dm);
tangent = (float(*)[3])dm->getFaceDataArray(dm, CD_TANGENT);
}
// Determine if we need to make a skinned mesh
if (mesh->dvert || mesh->key){
if (mesh->dvert || mesh->key) {
meshobj = new BL_SkinMeshObject(mesh, lightlayer);
skinMesh = true;
}
else {
else
meshobj = new RAS_MeshObject(mesh, lightlayer);
}
MT_Vector4 *tangent = 0;
if (tface)
tangent = BL_ComputeMeshTangentSpace(mesh);
// Extract avaiable layers
MTF_localLayer *layers = new MTF_localLayer[MAX_MTFACE];
for (int lay=0; lay<MAX_MTFACE; lay++)
{
for (int lay=0; lay<MAX_MTFACE; lay++) {
layers[lay].face = 0;
layers[lay].name = "";
}
int validLayers = 0;
for (int i=0; i<mesh->fdata.totlayer; i++)
for (int i=0; i<dm->faceData.totlayer; i++)
{
if (mesh->fdata.layers[i].type == CD_MTFACE)
if (dm->faceData.layers[i].type == CD_MTFACE)
{
assert(validLayers <= 8);
layers[validLayers].face = (MTFace*)mesh->fdata.layers[i].data;;
layers[validLayers].name = mesh->fdata.layers[i].name;
layers[validLayers].face = (MTFace*)(dm->faceData.layers[i].data);
layers[validLayers].name = dm->faceData.layers[i].name;
if(tface == layers[validLayers].face)
tfaceName = layers[validLayers].name;
validLayers++;
@@ -844,271 +767,269 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
}
meshobj->SetName(mesh->id.name);
meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
for (int f=0;f<mesh->totface;f++,mface++)
meshobj->m_xyz_index_to_vertex_index_mapping.resize(totvert);
for (int f=0;f<totface;f++,mface++)
{
Material* ma = 0;
bool collider = true;
// only add valid polygons
if (mface->v3)
{
MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
// rgb3 is set from the adjoint face in a square
unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
MT_Vector3 no0(mesh->mvert[mface->v1].no[0], mesh->mvert[mface->v1].no[1], mesh->mvert[mface->v1].no[2]),
no1(mesh->mvert[mface->v2].no[0], mesh->mvert[mface->v2].no[1], mesh->mvert[mface->v2].no[2]),
no2(mesh->mvert[mface->v3].no[0], mesh->mvert[mface->v3].no[1], mesh->mvert[mface->v3].no[2]),
no3(0.0, 0.0, 0.0);
MT_Point3 pt0(mesh->mvert[mface->v1].co),
pt1(mesh->mvert[mface->v2].co),
pt2(mesh->mvert[mface->v3].co),
pt3(0.0, 0.0, 0.0);
MT_Vector4 tan0(0.0, 0.0, 0.0, 0.0),
tan1(0.0, 0.0, 0.0, 0.0),
tan2(0.0, 0.0, 0.0, 0.0),
tan3(0.0, 0.0, 0.0, 0.0);
MT_Point2 uv0(0.0,0.0),uv1(0.0,0.0),uv2(0.0,0.0),uv3(0.0,0.0);
MT_Point2 uv20(0.0,0.0),uv21(0.0,0.0),uv22(0.0,0.0),uv23(0.0,0.0);
unsigned int rgb0,rgb1,rgb2,rgb3 = 0;
MT_Vector3 no0, no1, no2, no3;
MT_Point3 pt0, pt1, pt2, pt3;
MT_Vector4 tan0, tan1, tan2, tan3;
/* get coordinates, normals and tangents */
pt0 = MT_Point3(mvert[mface->v1].co);
pt1 = MT_Point3(mvert[mface->v2].co);
pt2 = MT_Point3(mvert[mface->v3].co);
pt3 = (mface->v4)? MT_Point3(mvert[mface->v4].co): MT_Point3(0.0, 0.0, 0.0);
if(mface->flag & ME_SMOOTH) {
float n0[3], n1[3], n2[3], n3[3];
NormalShortToFloat(n0, mvert[mface->v1].no);
NormalShortToFloat(n1, mvert[mface->v2].no);
NormalShortToFloat(n2, mvert[mface->v3].no);
no0 = n0;
no1 = n1;
no2 = n2;
if(mface->v4) {
NormalShortToFloat(n3, mvert[mface->v4].no);
no3 = n3;
}
else
no3 = MT_Vector3(0.0, 0.0, 0.0);
}
else {
float fno[3];
if(mface->v4)
CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
mvert[mface->v3].co, mvert[mface->v4].co, fno);
else
CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
mvert[mface->v3].co, fno);
no0 = no1 = no2 = no3 = MT_Vector3(fno);
}
if(tangent) {
tan0 = tangent[f*4 + 0];
tan1 = tangent[f*4 + 1];
tan2 = tangent[f*4 + 2];
no0 /= 32767.0;
no1 /= 32767.0;
no2 /= 32767.0;
if (mface->v4)
{
pt3 = MT_Point3(mesh->mvert[mface->v4].co);
no3 = MT_Vector3(mesh->mvert[mface->v4].no[0], mesh->mvert[mface->v4].no[1], mesh->mvert[mface->v4].no[2]);
no3 /= 32767.0;
}
tan3 = tangent[f*4 + 3];
}
/* get material */
ma = give_current_material(blenderobj, mface->mat_nr+1);
if(!(mface->flag & ME_SMOOTH))
{
MT_Vector3 norm = ((pt1-pt0).cross(pt2-pt0)).safe_normalized();
norm[0] = ((int) (10*norm[0]))/10.0;
norm[1] = ((int) (10*norm[1]))/10.0;
norm[2] = ((int) (10*norm[2]))/10.0;
no0=no1=no2=no3= norm;
}
{
Material* ma = 0;
bool polyvisible = true;
RAS_IPolyMaterial* polymat = NULL;
BL_Material *bl_mat = NULL;
{
bool polyvisible = true;
RAS_IPolyMaterial* polymat = NULL;
BL_Material *bl_mat = NULL;
if(converter->GetMaterials())
{
if(mesh->totcol > 1)
ma = mesh->mat[mface->mat_nr];
else
ma = give_current_material(blenderobj, 1);
if(converter->GetMaterials()) {
/* do Blender Multitexture and Blender GLSL materials */
unsigned int rgb[4];
MT_Point2 uv[4];
bl_mat = ConvertMaterial(mesh, ma, tface, tfaceName, mface, mmcol, lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
// set the index were dealing with
bl_mat->material_index = (int)mface->mat_nr;
/* first is the BL_Material */
bl_mat = ConvertMaterial(ma, tface, tfaceName, mface, mcol,
lightlayer, blenderobj, layers, converter->GetGLSLMaterials());
polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
unsigned int rgb[4];
bl_mat->GetConversionRGB(rgb);
rgb0 = rgb[0]; rgb1 = rgb[1];
rgb2 = rgb[2]; rgb3 = rgb[3];
MT_Point2 uv[4];
bl_mat->GetConversionUV(uv);
uv0 = uv[0]; uv1 = uv[1];
uv2 = uv[2]; uv3 = uv[3];
bl_mat->material_index = (int)mface->mat_nr;
bl_mat->GetConversionUV2(uv);
uv20 = uv[0]; uv21 = uv[1];
uv22 = uv[2]; uv23 = uv[3];
polyvisible = ((bl_mat->ras_mode & POLY_VIS)!=0);
collider = ((bl_mat->ras_mode & COLLIDER)!=0);
if(tangent){
tan0 = tangent[mface->v1];
tan1 = tangent[mface->v2];
tan2 = tangent[mface->v3];
if (mface->v4)
tan3 = tangent[mface->v4];
}
}
else
{
ma = give_current_material(blenderobj, 1);
/* vertex colors and uv's were stored in bl_mat temporarily */
bl_mat->GetConversionRGB(rgb);
rgb0 = rgb[0]; rgb1 = rgb[1];
rgb2 = rgb[2]; rgb3 = rgb[3];
Image* bima = ((mesh->mtface && tface) ? (Image*) tface->tpage : NULL);
STR_String imastr =
((mesh->mtface && tface) ?
(bima? (bima)->id.name : "" ) : "" );
char transp=0;
short mode=0, tile=0;
int tilexrep=4,tileyrep = 4;
if (bima)
{
tilexrep = bima->xrep;
tileyrep = bima->yrep;
bl_mat->GetConversionUV(uv);
uv0 = uv[0]; uv1 = uv[1];
uv2 = uv[2]; uv3 = uv[3];
bl_mat->GetConversionUV2(uv);
uv20 = uv[0]; uv21 = uv[1];
uv22 = uv[2]; uv23 = uv[3];
}
if (mesh->mtface && tface)
{
// Use texface colors if available
//TF_DYNAMIC means the polygon is a collision face
collider = ((tface->mode & TF_DYNAMIC) != 0);
transp = tface->transp &~ TF_CLIP;
tile = tface->tile;
mode = tface->mode;
polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
uv0 = MT_Point2(tface->uv[0]);
uv1 = MT_Point2(tface->uv[1]);
uv2 = MT_Point2(tface->uv[2]);
/* then the KX_BlenderMaterial */
polymat = new KX_BlenderMaterial(scene, bl_mat, skinMesh, lightlayer, blenderobj );
}
else {
/* do Texture Face materials */
Image* bima = (tface)? (Image*)tface->tpage: NULL;
STR_String imastr = (tface)? (bima? (bima)->id.name : "" ) : "";
if (mface->v4)
uv3 = MT_Point2(tface->uv[3]);
}
else
{
// no texfaces, set COLLSION true and everything else FALSE
mode = default_face_mode;
transp = TF_SOLID;
tile = 0;
}
char transp=0;
short mode=0, tile=0;
int tilexrep=4,tileyrep = 4;
if (bima) {
tilexrep = bima->xrep;
tileyrep = bima->yrep;
}
if (mmcol)
{
// Use vertex colors
rgb0 = KX_Mcol2uint_new(mmcol[0]);
rgb1 = KX_Mcol2uint_new(mmcol[1]);
rgb2 = KX_Mcol2uint_new(mmcol[2]);
if (mface->v4)
rgb3 = KX_Mcol2uint_new(mmcol[3]);
}
else {
// no vertex colors: take from material if we have one,
// otherwise set to white
unsigned int color = 0xFFFFFFFFL;
if (ma)
{
union
{
unsigned char cp[4];
unsigned int integer;
} col_converter;
col_converter.cp[3] = (unsigned char) (ma->r*255.0);
col_converter.cp[2] = (unsigned char) (ma->g*255.0);
col_converter.cp[1] = (unsigned char) (ma->b*255.0);
col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
color = col_converter.integer;
}
/* get tface properties if available */
if(tface) {
/* TF_DYNAMIC means the polygon is a collision face */
collider = ((tface->mode & TF_DYNAMIC) != 0);
transp = tface->transp;
tile = tface->tile;
mode = tface->mode;
polyvisible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
uv0 = MT_Point2(tface->uv[0]);
uv1 = MT_Point2(tface->uv[1]);
uv2 = MT_Point2(tface->uv[2]);
rgb0 = KX_rgbaint2uint_new(color);
rgb1 = KX_rgbaint2uint_new(color);
rgb2 = KX_rgbaint2uint_new(color);
if (mface->v4)
rgb3 = KX_rgbaint2uint_new(color);
}
if (mface->v4)
uv3 = MT_Point2(tface->uv[3]);
}
else {
/* no texfaces, set COLLSION true and everything else FALSE */
mode = default_face_mode;
transp = TF_SOLID;
tile = 0;
}
/* get vertex colors */
if (mcol) {
/* we have vertex colors */
rgb0 = KX_Mcol2uint_new(mcol[0]);
rgb1 = KX_Mcol2uint_new(mcol[1]);
rgb2 = KX_Mcol2uint_new(mcol[2]);
bool istriangle = (mface->v4==0);
bool zsort = ma?(ma->mode & MA_ZTRA) != 0:false;
polymat = new KX_PolygonMaterial(imastr, ma,
tile, tilexrep, tileyrep,
mode, transp, zsort, lightlayer, istriangle, blenderobj, tface, (unsigned int*)mmcol);
if (mface->v4)
rgb3 = KX_Mcol2uint_new(mcol[3]);
}
else {
/* no vertex colors, take from material, otherwise white */
unsigned int color = 0xFFFFFFFFL;
if (ma)
{
polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
} else
{
polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
polymat->m_shininess = 35.0;
union
{
unsigned char cp[4];
unsigned int integer;
} col_converter;
col_converter.cp[3] = (unsigned char) (ma->r*255.0);
col_converter.cp[2] = (unsigned char) (ma->g*255.0);
col_converter.cp[1] = (unsigned char) (ma->b*255.0);
col_converter.cp[0] = (unsigned char) (ma->alpha*255.0);
color = col_converter.integer;
}
}
// see if a bucket was reused or a new one was created
// this way only one KX_BlenderMaterial object has to exist per bucket
bool bucketCreated;
RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
if (bucketCreated) {
// this is needed to free up memory afterwards
converter->RegisterPolyMaterial(polymat);
if(converter->GetMaterials()) {
converter->RegisterBlenderMaterial(bl_mat);
}
} else {
// delete the material objects since they are no longer needed
// from now on, use the polygon material from the material bucket
delete polymat;
if(converter->GetMaterials()) {
delete bl_mat;
}
polymat = bucket->GetPolyMaterial();
}
int nverts = mface->v4?4:3;
int vtxarray = meshobj->FindVertexArray(nverts,polymat);
RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
bool flat;
if (skinMesh) {
/* If the face is set to solid, all fnors are the same */
if (mface->flag & ME_SMOOTH)
flat = false;
else
flat = true;
}
else
flat = false;
poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1));
poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2));
poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3));
if (nverts==4)
poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4));
meshobj->AddPolygon(poly);
if (poly->IsCollider())
{
RAS_TriangleIndex idx;
idx.m_index[0] = mface->v1;
idx.m_index[1] = mface->v2;
idx.m_index[2] = mface->v3;
idx.m_collider = collider;
meshobj->m_triangle_indices.push_back(idx);
if (nverts==4)
{
idx.m_index[0] = mface->v1;
idx.m_index[1] = mface->v3;
idx.m_index[2] = mface->v4;
idx.m_collider = collider;
meshobj->m_triangle_indices.push_back(idx);
}
rgb0 = KX_rgbaint2uint_new(color);
rgb1 = KX_rgbaint2uint_new(color);
rgb2 = KX_rgbaint2uint_new(color);
if (mface->v4)
rgb3 = KX_rgbaint2uint_new(color);
}
// poly->SetVisibleWireframeEdges(mface->edcode);
poly->SetCollider(collider);
bool istriangle = (mface->v4==0);
// only zsort alpha + add
bool alpha = (transp == TF_ALPHA || transp == TF_ADD);
bool zsort = (mode & TF_ALPHASORT)? alpha: 0;
polymat = new KX_PolygonMaterial(imastr, ma,
tile, tilexrep, tileyrep,
mode, transp, alpha, zsort, lightlayer, istriangle, blenderobj, tface, (unsigned int*)mcol);
if (ma) {
polymat->m_specular = MT_Vector3(ma->specr, ma->specg, ma->specb)*ma->spec;
polymat->m_shininess = (float)ma->har/4.0; // 0 < ma->har <= 512
polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
}
else {
polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
polymat->m_shininess = 35.0;
}
}
// see if a bucket was reused or a new one was created
// this way only one KX_BlenderMaterial object has to exist per bucket
bool bucketCreated;
RAS_MaterialBucket* bucket = scene->FindBucket(polymat, bucketCreated);
if (bucketCreated) {
// this is needed to free up memory afterwards
converter->RegisterPolyMaterial(polymat);
if(converter->GetMaterials()) {
converter->RegisterBlenderMaterial(bl_mat);
}
} else {
// delete the material objects since they are no longer needed
// from now on, use the polygon material from the material bucket
delete polymat;
if(converter->GetMaterials()) {
delete bl_mat;
}
polymat = bucket->GetPolyMaterial();
}
int nverts = mface->v4?4:3;
int vtxarray = meshobj->FindVertexArray(nverts,polymat);
RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
bool flat;
if (skinMesh) {
/* If the face is set to solid, all fnors are the same */
if (mface->flag & ME_SMOOTH)
flat = false;
else
flat = true;
}
else
flat = false;
poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,flat,polymat,mface->v1));
poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,flat,polymat,mface->v2));
poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,flat,polymat,mface->v3));
if (nverts==4)
poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,flat,polymat,mface->v4));
meshobj->AddPolygon(poly);
if (poly->IsCollider())
{
RAS_TriangleIndex idx;
idx.m_index[0] = mface->v1;
idx.m_index[1] = mface->v2;
idx.m_index[2] = mface->v3;
idx.m_collider = collider;
meshobj->m_triangle_indices.push_back(idx);
if (nverts==4)
{
idx.m_index[0] = mface->v1;
idx.m_index[1] = mface->v3;
idx.m_index[2] = mface->v4;
idx.m_collider = collider;
meshobj->m_triangle_indices.push_back(idx);
}
}
// poly->SetVisibleWireframeEdges(mface->edcode);
poly->SetCollider(collider);
}
if (tface)
tface++;
if (mmcol)
mmcol+=4;
if (mcol)
mcol+=4;
for (int lay=0; lay<MAX_MTFACE; lay++)
{
@@ -1127,11 +1048,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
(*mit)->GetPolyMaterial()->OnConstruction();
}
if(tangent)
delete [] tangent;
if (layers)
delete []layers;
dm->release(dm);
return meshobj;
}
@@ -1819,7 +1739,7 @@ KX_GameObject* getGameOb(STR_String busc,CListValue* sumolist){
return 0;
}
#include "BLI_arithb.h"
// convert blender objects into ketsji gameobjects
void BL_ConvertBlenderObjects(struct Main* maggie,
const STR_String& scenename,
@@ -1847,7 +1767,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();
@@ -1919,6 +1842,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,
@@ -1932,7 +1857,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (converter->addInitFromFrame)
if (!isInActiveLayer)
addobj=false;
if (gameobj&&addobj)
{
MT_Point3 posPrev;
@@ -1984,10 +1909,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
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);
BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
sumolist->Add(gameobj->AddRef());
BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
@@ -2024,8 +1947,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
// needed for python scripting
logicmgr->RegisterGameObjectName(gameobj->GetName(),gameobj);
// needed for dynamic object morphing
logicmgr->RegisterGameObj(gameobj, blenderobject);
// needed for group duplication
logicmgr->RegisterGameObj(blenderobject, gameobj);
for (int i = 0; i < gameobj->GetMeshCount(); i++)
logicmgr->RegisterGameMeshName(gameobj->GetMesh(i)->GetName(), blenderobject);
@@ -2046,7 +1969,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->NodeUpdateGS(0,true);
gameobj->Bucketize();
}
else
{
@@ -2054,6 +1977,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
//at the end of this function if it is not a root object
inactivelist->Add(gameobj->AddRef());
}
if (gameobj->IsDupliGroup())
grouplist.insert(blenderobject->dup_group);
if (converter->addInitFromFrame){
gameobj->NodeSetLocalPosition(posPrev);
gameobj->NodeSetLocalOrientation(angor);
@@ -2073,7 +1998,188 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
if (blenderscene->camera) {
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 in 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);
BL_ConvertMaterialIpos(blenderobject,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 group duplication
logicmgr->RegisterGameObj(blenderobject, gameobj);
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();
}
}
}
}
}
// non-camera objects not supported as camera currently
if (blenderscene->camera && blenderscene->camera->type == OB_CAMERA) {
KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
if(gamecamera)
@@ -2081,15 +2187,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);
}
@@ -2174,7 +2283,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;
@@ -2189,7 +2299,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);
}
@@ -2311,29 +2422,32 @@ 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);
}
// apply the initial state to controllers
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);
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);
// set the init state to all objects
gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
}
// apply the initial state to controllers, only on the active objects as this registers the sensors
for ( i=0;i<objectlist->GetCount();i++)
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(objectlist->GetValue(i));
gameobj->ResetState();
}
@@ -2344,5 +2458,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);
}
}
}

View File

@@ -60,6 +60,7 @@ public:
{
if (m_pDeformer)
m_pDeformer->Relink (map);
KX_GameObject::Relink(map);
};
void ProcessReplica(KX_GameObject* replica);

View File

@@ -442,15 +442,15 @@ PyMethodDef BL_ShapeActionActuator::Methods[] = {
{"setProperty", (PyCFunction) BL_ShapeActionActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
{"setBlendtime", (PyCFunction) BL_ShapeActionActuator::sPySetBlendtime, METH_VARARGS, SetBlendtime_doc},
{"getAction", (PyCFunction) BL_ShapeActionActuator::sPyGetAction, METH_VARARGS, GetAction_doc},
{"getStart", (PyCFunction) BL_ShapeActionActuator::sPyGetStart, METH_VARARGS, GetStart_doc},
{"getEnd", (PyCFunction) BL_ShapeActionActuator::sPyGetEnd, METH_VARARGS, GetEnd_doc},
{"getBlendin", (PyCFunction) BL_ShapeActionActuator::sPyGetBlendin, METH_VARARGS, GetBlendin_doc},
{"getPriority", (PyCFunction) BL_ShapeActionActuator::sPyGetPriority, METH_VARARGS, GetPriority_doc},
{"getFrame", (PyCFunction) BL_ShapeActionActuator::sPyGetFrame, METH_VARARGS, GetFrame_doc},
{"getProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
{"getType", (PyCFunction) BL_ShapeActionActuator::sPyGetType, METH_VARARGS, GetType_doc},
{"setType", (PyCFunction) BL_ShapeActionActuator::sPySetType, METH_VARARGS, SetType_doc},
{"getAction", (PyCFunction) BL_ShapeActionActuator::sPyGetAction, METH_NOARGS, GetAction_doc},
{"getStart", (PyCFunction) BL_ShapeActionActuator::sPyGetStart, METH_NOARGS, GetStart_doc},
{"getEnd", (PyCFunction) BL_ShapeActionActuator::sPyGetEnd, METH_NOARGS, GetEnd_doc},
{"getBlendin", (PyCFunction) BL_ShapeActionActuator::sPyGetBlendin, METH_NOARGS, GetBlendin_doc},
{"getPriority", (PyCFunction) BL_ShapeActionActuator::sPyGetPriority, METH_NOARGS, GetPriority_doc},
{"getFrame", (PyCFunction) BL_ShapeActionActuator::sPyGetFrame, METH_NOARGS, GetFrame_doc},
{"getProperty", (PyCFunction) BL_ShapeActionActuator::sPyGetProperty, METH_NOARGS, GetProperty_doc},
{"getType", (PyCFunction) BL_ShapeActionActuator::sPyGetType, METH_NOARGS, GetType_doc},
{"setType", (PyCFunction) BL_ShapeActionActuator::sPySetType, METH_NOARGS, SetType_doc},
{NULL,NULL} //Sentinel
};
@@ -463,9 +463,7 @@ char BL_ShapeActionActuator::GetAction_doc[] =
"getAction()\n"
"\tReturns a string containing the name of the current action.\n";
PyObject* BL_ShapeActionActuator::PyGetAction(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* BL_ShapeActionActuator::PyGetAction(PyObject* self) {
PyObject *result;
if (m_action){
@@ -484,9 +482,7 @@ char BL_ShapeActionActuator::GetProperty_doc[] =
"getProperty()\n"
"\tReturns the name of the property to be used in FromProp mode.\n";
PyObject* BL_ShapeActionActuator::PyGetProperty(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* BL_ShapeActionActuator::PyGetProperty(PyObject* self) {
PyObject *result;
result = Py_BuildValue("s", (const char *)m_propname);
@@ -499,9 +495,7 @@ char BL_ShapeActionActuator::GetFrame_doc[] =
"getFrame()\n"
"\tReturns the current frame number.\n";
PyObject* BL_ShapeActionActuator::PyGetFrame(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* BL_ShapeActionActuator::PyGetFrame(PyObject* self) {
PyObject *result;
result = Py_BuildValue("f", m_localtime);
@@ -514,9 +508,7 @@ char BL_ShapeActionActuator::GetEnd_doc[] =
"getEnd()\n"
"\tReturns the last frame of the action.\n";
PyObject* BL_ShapeActionActuator::PyGetEnd(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* BL_ShapeActionActuator::PyGetEnd(PyObject* self) {
PyObject *result;
result = Py_BuildValue("f", m_endframe);
@@ -529,9 +521,7 @@ char BL_ShapeActionActuator::GetStart_doc[] =
"getStart()\n"
"\tReturns the starting frame of the action.\n";
PyObject* BL_ShapeActionActuator::PyGetStart(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* BL_ShapeActionActuator::PyGetStart(PyObject* self) {
PyObject *result;
result = Py_BuildValue("f", m_startframe);
@@ -545,9 +535,7 @@ char BL_ShapeActionActuator::GetBlendin_doc[] =
"\tReturns the number of interpolation animation frames to be\n"
"\tgenerated when this actuator is triggered.\n";
PyObject* BL_ShapeActionActuator::PyGetBlendin(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* BL_ShapeActionActuator::PyGetBlendin(PyObject* self) {
PyObject *result;
result = Py_BuildValue("f", m_blendin);
@@ -561,9 +549,7 @@ char BL_ShapeActionActuator::GetPriority_doc[] =
"\tReturns the priority for this actuator. Actuators with lower\n"
"\tPriority numbers will override actuators with higher numbers.\n";
PyObject* BL_ShapeActionActuator::PyGetPriority(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* BL_ShapeActionActuator::PyGetPriority(PyObject* self) {
PyObject *result;
result = Py_BuildValue("i", m_priority);
@@ -605,6 +591,7 @@ PyObject* BL_ShapeActionActuator::PySetAction(PyObject* self,
}
}
else {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -627,6 +614,7 @@ PyObject* BL_ShapeActionActuator::PySetStart(PyObject* self,
m_startframe = start;
}
else {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -649,6 +637,7 @@ PyObject* BL_ShapeActionActuator::PySetEnd(PyObject* self,
m_endframe = end;
}
else {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -672,6 +661,7 @@ PyObject* BL_ShapeActionActuator::PySetBlendin(PyObject* self,
m_blendin = blendin;
}
else {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -700,6 +690,7 @@ PyObject* BL_ShapeActionActuator::PySetBlendtime(PyObject* self,
m_blendframe = m_blendin;
}
else {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -724,6 +715,7 @@ PyObject* BL_ShapeActionActuator::PySetPriority(PyObject* self,
m_priority = priority;
}
else {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -750,6 +742,7 @@ PyObject* BL_ShapeActionActuator::PySetFrame(PyObject* self,
m_localtime=m_endframe;
}
else {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -773,6 +766,7 @@ PyObject* BL_ShapeActionActuator::PySetProperty(PyObject* self,
m_propname = string;
}
else {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -784,9 +778,7 @@ PyObject* BL_ShapeActionActuator::PySetProperty(PyObject* self,
char BL_ShapeActionActuator::GetType_doc[] =
"getType()\n"
"\tReturns the operation mode of the actuator.\n";
PyObject* BL_ShapeActionActuator::PyGetType(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* BL_ShapeActionActuator::PyGetType(PyObject* self) {
return Py_BuildValue("h", m_playtype);
}
@@ -801,6 +793,7 @@ PyObject* BL_ShapeActionActuator::PySetType(PyObject* self,
short typeArg;
if (!PyArg_ParseTuple(args, "h", &typeArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}

View File

@@ -1,5 +1,5 @@
/**
* $Id$
* $Id:BL_ShapeActionActuator.h 15330 2008-06-23 16:37:51Z theeth $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -87,15 +87,15 @@ public:
KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetBlendtime);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetChannel);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetAction);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetBlendin);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetPriority);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetStart);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetEnd);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetFrame);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetProperty);
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetAction);
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetBlendin);
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetPriority);
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetStart);
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetEnd);
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetFrame);
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetProperty);
// KX_PYMETHOD(BL_ActionActuator,GetChannel);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,GetType);
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetType);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetType);
virtual PyObject* _getattr(const STR_String& attr);

View File

@@ -109,6 +109,13 @@ bool BL_ShapeDeformer::ExecuteShapeDrivers(void)
vector<IpoCurve*>::iterator it;
void *poin;
int type;
// the shape drivers use the bone matrix as input. Must
// update the matrix now
Object* par_arma = m_armobj->GetArmatureObject();
m_armobj->ApplyPose();
where_is_pose( par_arma );
PoseApplied(true);
for (it=m_shapeDrivers.begin(); it!=m_shapeDrivers.end(); it++) {
// no need to set a specific time: this curve has a driver
IpoCurve *icu = *it;

View File

@@ -66,7 +66,8 @@ BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
m_armobj(arma),
m_lastArmaUpdate(-1),
m_defbase(&bmeshobj->defbase),
m_releaseobject(false)
m_releaseobject(false),
m_poseApplied(false)
{
Mat4CpyMat4(m_obmat, bmeshobj->obmat);
};
@@ -98,32 +99,28 @@ BL_SkinDeformer::~BL_SkinDeformer()
m_armobj->Release();
}
bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *)
bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
{
size_t i, j;
if (!Update())
// no need to update the cache
return false;
// update the vertex in m_transverts
Update();
// Update all materials at once, so we can do the above update test
// without ending up with some materials not updated
for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial();
mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial();
// The vertex cache can only be updated for this deformer:
// Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
// share the same mesh (=the same cache). As the rendering is done per polymaterial
// cycling through the objects, the entire mesh cache cannot be updated in one shot.
vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat);
vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat);
// For each array
for (i=0; i<vertexarrays.size(); i++) {
KX_VertexArray& vertexarray = (*vertexarrays[i]);
// For each array
for (i=0; i<vertexarrays.size(); i++) {
KX_VertexArray& vertexarray = (*vertexarrays[i]);
// For each vertex
// copy the untransformed data from the original mvert
for (j=0; j<vertexarray.size(); j++) {
RAS_TexVert& v = vertexarray[j];
v.SetXYZ(m_transverts[v.getOrigIndex()]);
}
// For each vertex
// copy the untransformed data from the original mvert
for (j=0; j<vertexarray.size(); j++) {
RAS_TexVert& v = vertexarray[j];
v.SetXYZ(m_transverts[v.getOrigIndex()]);
}
}
@@ -153,9 +150,11 @@ bool BL_SkinDeformer::Update(void)
/* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
/* but it requires the blender object pointer... */
Object* par_arma = m_armobj->GetArmatureObject();
where_is_pose( par_arma );
if (!PoseApplied()){
m_armobj->ApplyPose();
where_is_pose( par_arma );
}
/* store verts locally */
VerifyStorage();
@@ -180,7 +179,8 @@ bool BL_SkinDeformer::Update(void)
/* Update the current frame */
m_lastArmaUpdate=m_armobj->GetLastFrame();
/* reset for next frame */
PoseApplied(false);
/* indicate that the m_transverts and normals are up to date */
return true;
}

View File

@@ -81,10 +81,13 @@ public:
virtual ~BL_SkinDeformer();
bool Update (void);
bool Apply (class RAS_IPolyMaterial *polymat);
bool PoseApplied()
{ return m_poseApplied; }
void PoseApplied(bool applied)
{ m_poseApplied = applied; }
bool PoseUpdated(void)
{
if (m_armobj && m_lastArmaUpdate!=m_armobj->GetLastFrame()) {
m_armobj->ApplyPose();
return true;
}
return false;
@@ -102,6 +105,7 @@ protected:
ListBase* m_defbase;
float m_obmat[4][4]; // the reference matrix for skeleton deform
bool m_releaseobject;
bool m_poseApplied;
};

View File

@@ -503,7 +503,7 @@ void BL_ConvertActuators(char* maggiename,
case ACT_PROPERTY:
{
bPropertyActuator* propact = (bPropertyActuator*) bact->data;
CValue* destinationObj = NULL;
SCA_IObject* destinationObj = NULL;
/*
here the destinationobject is searched. problem with multiple scenes: other scenes
@@ -628,6 +628,8 @@ void BL_ConvertActuators(char* maggiename,
/* convert settings... degrees in the ui become radians */
/* internally */
if (conact->type == ACT_CONST_TYPE_ORI) {
min = (MT_2_PI * conact->minloc[0])/360.0;
max = (MT_2_PI * conact->maxloc[0])/360.0;
switch (conact->mode) {
case ACT_CONST_DIRPX:
locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX;
@@ -656,18 +658,18 @@ void BL_ConvertActuators(char* maggiename,
min = conact->minloc[2];
max = conact->maxloc[2];
break;
case ACT_CONST_DIRMX:
locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMX;
case ACT_CONST_DIRNX:
locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNX;
min = conact->minloc[0];
max = conact->maxloc[0];
break;
case ACT_CONST_DIRMY:
locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMY;
case ACT_CONST_DIRNY:
locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNY;
min = conact->minloc[1];
max = conact->maxloc[1];
break;
case ACT_CONST_DIRMZ:
locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMZ;
case ACT_CONST_DIRNZ:
locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNZ;
min = conact->minloc[2];
max = conact->maxloc[2];
break;

View File

@@ -733,9 +733,9 @@ void BL_ConvertSensors(struct Object* blenderobject,
gameobj->AddSensor(gamesensor);
// only register to manager if it's in an active layer
if (isInActiveLayer)
gamesensor->RegisterToManager();
// Make registration dynamic: only when sensor is activated
//if (isInActiveLayer)
// gamesensor->RegisterToManager();
for (int i=0;i<sens->totlinks;i++)

View File

@@ -36,6 +36,7 @@
#pragma warning (disable:4786)
#endif
#include "BKE_material.h" /* give_current_material */
#include "KX_GameObject.h"
#include "KX_IpoConvert.h"
@@ -68,6 +69,8 @@
#include "SG_Node.h"
#include "STR_HashedString.h"
static BL_InterpolatorList *GetIpoList(struct Ipo *for_ipo, KX_BlenderSceneConverter *converter) {
BL_InterpolatorList *ipoList= converter->FindInterpolatorList(for_ipo);
@@ -560,16 +563,15 @@ void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *co
}
}
void BL_ConvertMaterialIpos(
Material* blendermaterial,
static void ConvertMaterialIpos(
Material* blendermaterial,
dword matname_hash,
KX_GameObject* gameobj,
KX_BlenderSceneConverter *converter
)
{
if (blendermaterial->ipo) {
KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController();
KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
@@ -596,7 +598,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_COL_R);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -610,7 +612,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_COL_G);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -624,7 +626,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_COL_B);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -638,7 +640,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_ALPHA);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -653,7 +655,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_SPEC_R );
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -667,7 +669,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_SPEC_G);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -681,7 +683,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_SPEC_B);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -696,7 +698,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_HARD);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -710,7 +712,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_SPEC);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -725,7 +727,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_REF);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -739,7 +741,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_EMIT);
if (ipo) {
if (!ipocontr) {
ipocontr = new KX_MaterialIpoController();
ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -752,3 +754,28 @@ void BL_ConvertMaterialIpos(
}
}
void BL_ConvertMaterialIpos(
struct Object* blenderobject,
KX_GameObject* gameobj,
KX_BlenderSceneConverter *converter
)
{
if (blenderobject->totcol==1)
{
Material *mat = give_current_material(blenderobject, 1);
// if there is only one material attached to the mesh then set material_index in BL_ConvertMaterialIpos to NULL
// --> this makes the UpdateMaterialData function in KX_GameObject.cpp use the old hack of using SetObjectColor
// because this yields a better performance as not all the vertex colors need to be edited
if(mat) ConvertMaterialIpos(mat, NULL, gameobj, converter);
}
else
{
for (int material_index=1; material_index <= blenderobject->totcol; material_index++)
{
Material *mat = give_current_material(blenderobject, material_index);
STR_HashedString matname = mat->id.name;
if(mat) ConvertMaterialIpos(mat, matname.hash(), gameobj, converter);
}
}
}

View File

@@ -46,7 +46,7 @@ void BL_ConvertCameraIpos(struct Camera* blendercamera,
class KX_GameObject* cameraobj,
class KX_BlenderSceneConverter *converter);
void BL_ConvertMaterialIpos(struct Material* blendermaterial,
void BL_ConvertMaterialIpos(struct Object* blenderobject,
class KX_GameObject* materialobj,
class KX_BlenderSceneConverter *converter);

View File

@@ -1,5 +1,5 @@
/**
* $Id$
* $Id:SCA_ActuatorEventManager.cpp 15567 2008-07-14 14:09:36Z theeth $
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -48,19 +48,10 @@ SCA_ActuatorEventManager::~SCA_ActuatorEventManager()
}
void SCA_ActuatorEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
}
void SCA_ActuatorEventManager::NextFrame()
{
// check for changed actuator
for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
(*it)->Activate(m_logicmgr,NULL);
}
@@ -69,7 +60,7 @@ void SCA_ActuatorEventManager::NextFrame()
void SCA_ActuatorEventManager::UpdateFrame()
{
// update the state of actuator before executing them
for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
((SCA_ActuatorSensor*)(*it))->Update();
}

View File

@@ -1,5 +1,5 @@
/**
* $Id$
* $Id:SCA_ActuatorEventManager.h 15567 2008-07-14 14:09:36Z theeth $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -44,7 +44,6 @@ public:
virtual ~SCA_ActuatorEventManager();
virtual void NextFrame();
virtual void UpdateFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
//SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
};

View File

@@ -1,7 +1,7 @@
/**
* Actuator sensor
*
* $Id$
* $Id:SCA_ActuatorSensor.cpp 15567 2008-07-14 14:09:36Z theeth $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -149,7 +149,7 @@ PyParentObject SCA_ActuatorSensor::Parents[] = {
};
PyMethodDef SCA_ActuatorSensor::Methods[] = {
{"getActuator", (PyCFunction) SCA_ActuatorSensor::sPyGetActuator, METH_VARARGS, GetActuator_doc},
{"getActuator", (PyCFunction) SCA_ActuatorSensor::sPyGetActuator, METH_NOARGS, GetActuator_doc},
{"setActuator", (PyCFunction) SCA_ActuatorSensor::sPySetActuator, METH_VARARGS, SetActuator_doc},
{NULL,NULL} //Sentinel
};
@@ -162,7 +162,7 @@ PyObject* SCA_ActuatorSensor::_getattr(const STR_String& attr) {
char SCA_ActuatorSensor::GetActuator_doc[] =
"getActuator()\n"
"\tReturn the Actuator with which the sensor operates.\n";
PyObject* SCA_ActuatorSensor::PyGetActuator(PyObject* self, PyObject* args, PyObject* kwds)
PyObject* SCA_ActuatorSensor::PyGetActuator(PyObject* self)
{
return PyString_FromString(m_checkactname);
}
@@ -180,6 +180,7 @@ PyObject* SCA_ActuatorSensor::PySetActuator(PyObject* self, PyObject* args, PyOb
char *actNameArg = NULL;
if (!PyArg_ParseTuple(args, "s", &actNameArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}

View File

@@ -1,7 +1,7 @@
/**
* Actuator sensor
*
* $Id$
* $Id:SCA_ActuatorSensor.h 15567 2008-07-14 14:09:36Z theeth $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -66,7 +66,7 @@ public:
/* 3. setProperty */
KX_PYMETHOD_DOC(SCA_ActuatorSensor,SetActuator);
/* 4. getProperty */
KX_PYMETHOD_DOC(SCA_ActuatorSensor,GetActuator);
KX_PYMETHOD_DOC_NOARGS(SCA_ActuatorSensor,GetActuator);
};

View File

@@ -51,16 +51,9 @@ SCA_AlwaysEventManager::SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr)
void SCA_AlwaysEventManager::NextFrame()
{
for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
SCA_ISensor* sensor = *i;
sensor->Activate(m_logicmgr, NULL);
(*i)->Activate(m_logicmgr, NULL);
}
}
void SCA_AlwaysEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
}

View File

@@ -39,7 +39,6 @@ class SCA_AlwaysEventManager : public SCA_EventManager
public:
SCA_AlwaysEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
};

View File

@@ -45,17 +45,14 @@ SCA_EventManager::~SCA_EventManager()
{
}
void SCA_EventManager::RegisterSensor(class SCA_ISensor* sensor)
{
m_sensors.insert(sensor);
}
void SCA_EventManager::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();
}
m_sensors.erase(sensor);
}
void SCA_EventManager::NextFrame(double curtime, double fixedtime)

View File

@@ -30,12 +30,14 @@
#define __KX_EVENTMANAGER
#include <vector>
#include <set>
#include <algorithm>
class SCA_EventManager
{
protected:
std::vector <class SCA_ISensor*> m_sensors;
// use a set to speed-up insertion/removal
std::set <class SCA_ISensor*> m_sensors;
public:
enum EVENT_MANAGER_TYPE {
@@ -61,7 +63,7 @@ public:
virtual void NextFrame();
virtual void UpdateFrame();
virtual void EndFrame();
virtual void RegisterSensor(class SCA_ISensor* sensor)=0;
virtual void RegisterSensor(class SCA_ISensor* sensor);
int GetType();
protected:

View File

@@ -82,7 +82,10 @@ void SCA_ILogicBrick::ReParent(SCA_IObject* parent)
m_gameobj = parent;
}
void SCA_ILogicBrick::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
{
// nothing to do
}
CValue* SCA_ILogicBrick::Calc(VALUE_OPERATOR op, CValue *val)
{

View File

@@ -32,6 +32,8 @@
#include "Value.h"
#include "SCA_IObject.h"
#include "BoolValue.h"
#include "GEN_Map.h"
#include "GEN_HashedPtr.h"
class SCA_ILogicBrick : public CValue
{
@@ -59,6 +61,7 @@ public:
SCA_IObject* GetParent();
virtual void ReParent(SCA_IObject* parent);
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
// act as a BoolValue (with value IsPositiveTrigger)
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);

View File

@@ -306,7 +306,7 @@ const MT_Point3& SCA_IObject::ConvertPythonPylist(PyObject* pylist)
}
#endif
void SCA_IObject::Suspend(void)
void SCA_IObject::Suspend()
{
if ((!m_ignore_activity_culling)
&& (!m_suspended)) {
@@ -337,12 +337,31 @@ void SCA_IObject::Resume(void)
void SCA_IObject::SetState(unsigned int state)
{
m_state = state;
// update the status of the controllers
unsigned int tmpstate;
SCA_ControllerList::iterator contit;
for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
// we will update the state in two steps:
// 1) set the new state bits that are 1
// 2) clr the new state bits that are 0
// This to ensure continuity if a sensor is attached to two states
// that are switching state: no need to deactive and reactive the sensor
tmpstate = m_state | state;
if (tmpstate != m_state)
{
(*contit)->ApplyState(m_state);
// update the status of the controllers
for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
{
(*contit)->ApplyState(tmpstate);
}
}
m_state = state;
if (m_state != tmpstate)
{
for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
{
(*contit)->ApplyState(m_state);
}
}
}

View File

@@ -41,7 +41,8 @@
void SCA_ISensor::ReParent(SCA_IObject* parent)
{
SCA_ILogicBrick::ReParent(parent);
m_eventmgr->RegisterSensor(this);
// will be done when the sensor is activated
//m_eventmgr->RegisterSensor(this);
this->SetActive(false);
}
@@ -133,6 +134,7 @@ void SCA_ISensor::DecLink() {
{
// sensor is detached from all controllers, initialize it so that it
// is fresh as at startup when it is reattached again.
UnregisterToManager();
Init();
}
}
@@ -168,23 +170,23 @@ PyMethodDef SCA_ISensor::Methods[] = {
{"isPositive", (PyCFunction) SCA_ISensor::sPyIsPositive,
METH_VARARGS, IsPositive_doc},
{"getUsePosPulseMode", (PyCFunction) SCA_ISensor::sPyGetUsePosPulseMode,
METH_VARARGS, GetUsePosPulseMode_doc},
METH_NOARGS, GetUsePosPulseMode_doc},
{"setUsePosPulseMode", (PyCFunction) SCA_ISensor::sPySetUsePosPulseMode,
METH_VARARGS, SetUsePosPulseMode_doc},
{"getFrequency", (PyCFunction) SCA_ISensor::sPyGetFrequency,
METH_VARARGS, GetFrequency_doc},
METH_NOARGS, GetFrequency_doc},
{"setFrequency", (PyCFunction) SCA_ISensor::sPySetFrequency,
METH_VARARGS, SetFrequency_doc},
{"getUseNegPulseMode", (PyCFunction) SCA_ISensor::sPyGetUseNegPulseMode,
METH_VARARGS, GetUseNegPulseMode_doc},
METH_NOARGS, GetUseNegPulseMode_doc},
{"setUseNegPulseMode", (PyCFunction) SCA_ISensor::sPySetUseNegPulseMode,
METH_VARARGS, SetUseNegPulseMode_doc},
{"getInvert", (PyCFunction) SCA_ISensor::sPyGetInvert,
METH_VARARGS, GetInvert_doc},
METH_NOARGS, GetInvert_doc},
{"setInvert", (PyCFunction) SCA_ISensor::sPySetInvert,
METH_VARARGS, SetInvert_doc},
{"getLevel", (PyCFunction) SCA_ISensor::sPyGetLevel,
METH_VARARGS, GetLevel_doc},
METH_NOARGS, GetLevel_doc},
{"setLevel", (PyCFunction) SCA_ISensor::sPySetLevel,
METH_VARARGS, SetLevel_doc},
{NULL,NULL} //Sentinel
@@ -203,6 +205,11 @@ void SCA_ISensor::RegisterToManager()
m_eventmgr->RegisterSensor(this);
}
void SCA_ISensor::UnregisterToManager()
{
m_eventmgr->RemoveSensor(this);
}
void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
{
@@ -259,7 +266,7 @@ PyObject* SCA_ISensor::PyIsPositive(PyObject* self, PyObject* args, PyObject* kw
char SCA_ISensor::GetUsePosPulseMode_doc[] =
"getUsePosPulseMode()\n"
"\tReturns whether positive pulse mode is active.\n";
PyObject* SCA_ISensor::PyGetUsePosPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
PyObject* SCA_ISensor::PyGetUsePosPulseMode(PyObject* self)
{
return BoolToPyArg(m_pos_pulsemode);
}
@@ -286,7 +293,7 @@ PyObject* SCA_ISensor::PySetUsePosPulseMode(PyObject* self, PyObject* args, PyOb
char SCA_ISensor::GetFrequency_doc[] =
"getFrequency()\n"
"\tReturns the frequency of the updates in pulse mode.\n" ;
PyObject* SCA_ISensor::PyGetFrequency(PyObject* self, PyObject* args, PyObject* kwds)
PyObject* SCA_ISensor::PyGetFrequency(PyObject* self)
{
return PyInt_FromLong(m_pulse_frequency);
}
@@ -321,7 +328,7 @@ PyObject* SCA_ISensor::PySetFrequency(PyObject* self, PyObject* args, PyObject*
char SCA_ISensor::GetInvert_doc[] =
"getInvert()\n"
"\tReturns whether or not pulses from this sensor are inverted.\n" ;
PyObject* SCA_ISensor::PyGetInvert(PyObject* self, PyObject* args, PyObject* kwds)
PyObject* SCA_ISensor::PyGetInvert(PyObject* self)
{
return BoolToPyArg(m_invert);
}
@@ -342,11 +349,10 @@ char SCA_ISensor::GetLevel_doc[] =
"getLevel()\n"
"\tReturns whether this sensor is a level detector or a edge detector.\n"
"\tIt makes a difference only in case of logic state transition (state actuator).\n"
"\tA level detector will immediately generate a pulse if the condition for the\n"
"\tdetector is met when entering the state. A edge detector will wait for an off-on\n"
"\ttransition to occur.\n"
"\tOnly some sensors implement this feature: keyboard.\n";
PyObject* SCA_ISensor::PyGetLevel(PyObject* self, PyObject* args, PyObject* kwds)
"\tA level detector will immediately generate a pulse, negative or positive\n"
"\tdepending on the sensor condition, as soon as the state is activated.\n"
"\tA edge detector will wait for a state change before generating a pulse.\n";
PyObject* SCA_ISensor::PyGetLevel(PyObject* self)
{
return BoolToPyArg(m_level);
}
@@ -366,7 +372,7 @@ PyObject* SCA_ISensor::PySetLevel(PyObject* self, PyObject* args, PyObject* kwds
char SCA_ISensor::GetUseNegPulseMode_doc[] =
"getUseNegPulseMode()\n"
"\tReturns whether negative pulse mode is active.\n";
PyObject* SCA_ISensor::PyGetUseNegPulseMode(PyObject* self, PyObject* args, PyObject* kwds)
PyObject* SCA_ISensor::PyGetUseNegPulseMode(PyObject* self)
{
return BoolToPyArg(m_neg_pulsemode);
}

View File

@@ -115,6 +115,8 @@ public:
void SetLevel(bool lvl);
void RegisterToManager();
void UnregisterToManager();
virtual float GetNumber();
/** Stop sensing for a while. */
@@ -129,22 +131,22 @@ public:
void ClrLink()
{ m_links = 0; }
void IncLink()
{ m_links++; }
{ if (!m_links++) RegisterToManager(); }
void DecLink();
bool IsNoLink() const
{ return !m_links; }
/* Python functions: */
KX_PYMETHOD_DOC(SCA_ISensor,IsPositive);
KX_PYMETHOD_DOC(SCA_ISensor,GetUsePosPulseMode);
KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetUsePosPulseMode);
KX_PYMETHOD_DOC(SCA_ISensor,SetUsePosPulseMode);
KX_PYMETHOD_DOC(SCA_ISensor,GetFrequency);
KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetFrequency);
KX_PYMETHOD_DOC(SCA_ISensor,SetFrequency);
KX_PYMETHOD_DOC(SCA_ISensor,GetUseNegPulseMode);
KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetUseNegPulseMode);
KX_PYMETHOD_DOC(SCA_ISensor,SetUseNegPulseMode);
KX_PYMETHOD_DOC(SCA_ISensor,GetInvert);
KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetInvert);
KX_PYMETHOD_DOC(SCA_ISensor,SetInvert);
KX_PYMETHOD_DOC(SCA_ISensor,GetLevel);
KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,GetLevel);
KX_PYMETHOD_DOC(SCA_ISensor,SetLevel);
};

View File

@@ -52,9 +52,10 @@ SCA_JoystickManager::~SCA_JoystickManager()
void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
{
for (unsigned int i = 0; i < m_sensors.size(); i++)
set<SCA_ISensor*>::iterator it;
for (it = m_sensors.begin(); it != m_sensors.end(); it++)
{
SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*) m_sensors[i];
SCA_JoystickSensor* joysensor = (SCA_JoystickSensor*)(*it);
if(!joysensor->IsSuspended())
{
m_joystick->HandleEvents();
@@ -64,12 +65,6 @@ void SCA_JoystickManager::NextFrame(double curtime,double deltatime)
}
void SCA_JoystickManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
}
SCA_Joystick *SCA_JoystickManager::GetJoystickDevice()
{
/*

View File

@@ -45,7 +45,6 @@ public:
SCA_JoystickManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_JoystickManager();
virtual void NextFrame(double curtime,double deltatime);
virtual void RegisterSensor(SCA_ISensor* sensor);
SCA_Joystick* GetJoystickDevice(void);
};

View File

@@ -62,23 +62,14 @@ void SCA_KeyboardManager::NextFrame()
{
//const SCA_InputEvent& event = GetEventValue(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
// cerr << "SCA_KeyboardManager::NextFrame"<< endl;
for (unsigned int i=0;i<m_sensors.size();i++)
set<SCA_ISensor*>::iterator it;
for (it=m_sensors.begin(); it != m_sensors.end(); it++)
{
SCA_KeyboardSensor* keysensor = (SCA_KeyboardSensor*)m_sensors[i];
keysensor->Activate(m_logicmanager,NULL);
(*it)->Activate(m_logicmanager,NULL);
}
}
void SCA_KeyboardManager::RegisterSensor(SCA_ISensor* keysensor)
{
m_sensors.push_back(keysensor);
}
bool SCA_KeyboardManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
return false;

View File

@@ -55,7 +55,6 @@ public:
bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
virtual void NextFrame();
virtual void RegisterSensor(class SCA_ISensor* sensor);
SCA_IInputDevice* GetInputDevice();
};

View File

@@ -127,12 +127,17 @@ void SCA_LogicManager::RegisterGameMeshName(const STR_String& gamemeshname, void
void SCA_LogicManager::RegisterGameObj(CValue* gameobj, void* blendobj)
void SCA_LogicManager::RegisterGameObj(void* blendobj, CValue* gameobj)
{
m_map_gameobj_to_blendobj.insert(CHashedPtr(gameobj), blendobj);
m_map_blendobj_to_gameobj.insert(CHashedPtr(blendobj), gameobj);
}
void SCA_LogicManager::UnregisterGameObj(void* blendobj, CValue* gameobj)
{
void **obp = m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
if (obp && (CValue*)(*obp) == gameobj)
m_map_blendobj_to_gameobj.remove(CHashedPtr(blendobj));
}
CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
{
@@ -146,10 +151,10 @@ CValue* SCA_LogicManager::GetGameObjectByName(const STR_String& gameobjname)
}
void* SCA_LogicManager::FindBlendObjByGameObj(CValue* gameobject)
CValue* SCA_LogicManager::FindGameObjByBlendObj(void* blendobj)
{
void **obp= m_map_gameobj_to_blendobj[CHashedPtr(gameobject)];
return obp?*obp:NULL;
void **obp= m_map_blendobj_to_gameobj[CHashedPtr(blendobj)];
return obp?(CValue*)(*obp):NULL;
}
@@ -171,12 +176,7 @@ void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
(*c)->UnlinkSensor(sensor);
}
m_sensorcontrollermapje.erase(sensor);
for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
!(ie==m_eventmanagers.end());ie++)
{
(*ie)->RemoveSensor(sensor);
}
sensor->UnregisterToManager();
}
void SCA_LogicManager::RemoveController(SCA_IController* controller)

View File

@@ -109,7 +109,7 @@ class SCA_LogicManager
GEN_Map<STR_HashedString,void*> m_mapStringToActions;
GEN_Map<STR_HashedString,void*> m_map_gamemeshname_to_blendobj;
GEN_Map<CHashedPtr,void*> m_map_gameobj_to_blendobj;
GEN_Map<CHashedPtr,void*> m_map_blendobj_to_gameobj;
vector<SmartActuatorPtr> m_removedActuators;
public:
@@ -152,8 +152,9 @@ public:
void RegisterGameMeshName(const STR_String& gamemeshname, void* blendobj);
void* FindBlendObjByGameMeshName(const STR_String& gamemeshname);
void RegisterGameObj(CValue* gameobj, void* blendobj);
void* FindBlendObjByGameObj(CValue* gameobj);
void RegisterGameObj(void* blendobj, CValue* gameobj);
void UnregisterGameObj(void* blendobj, CValue* gameobj);
CValue* FindGameObjByBlendObj(void* blendobj);
};
#endif //__KX_LOGICMANAGER

View File

@@ -75,9 +75,10 @@ void SCA_MouseManager::NextFrame()
{
if (m_mousedevice)
{
for (unsigned int i = 0; i < m_sensors.size(); i++)
set<SCA_ISensor*>::iterator it;
for (it=m_sensors.begin(); it!=m_sensors.end(); it++)
{
SCA_MouseSensor* mousesensor = (SCA_MouseSensor*) m_sensors[i];
SCA_MouseSensor* mousesensor = (SCA_MouseSensor*)(*it);
// (0,0) is the Upper Left corner in our local window
// coordinates
if (!mousesensor->IsSuspended())
@@ -98,15 +99,6 @@ void SCA_MouseManager::NextFrame()
}
}
void SCA_MouseManager::RegisterSensor(SCA_ISensor* keysensor)
{
m_sensors.push_back(keysensor);
}
bool SCA_MouseManager::IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)
{
/* We should guard for non-mouse events maybe? A rather silly side */

View File

@@ -62,7 +62,6 @@ public:
*/
bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode);
virtual void NextFrame();
virtual void RegisterSensor(class SCA_ISensor* sensor);
SCA_IInputDevice* GetInputDevice();
};

View File

@@ -42,7 +42,7 @@
/* Native functions */
/* ------------------------------------------------------------------------- */
SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,CValue* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T )
SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype,PyTypeObject* T )
: SCA_IActuator(gameobj,T),
m_type(acttype),
m_propname(propname),
@@ -51,14 +51,14 @@ SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,CValue* sourceOb
{
// protect ourselves against someone else deleting the source object
// don't protect against ourselves: it would create a dead lock
if (m_sourceObj && m_sourceObj != GetParent())
m_sourceObj->AddRef();
if (m_sourceObj)
m_sourceObj->RegisterActuator(this);
}
SCA_PropertyActuator::~SCA_PropertyActuator()
{
if (m_sourceObj && m_sourceObj != GetParent())
m_sourceObj->Release();
if (m_sourceObj)
m_sourceObj->UnregisterActuator(this);
}
bool SCA_PropertyActuator::Update()
@@ -185,10 +185,31 @@ void SCA_PropertyActuator::ProcessReplica()
// no need to check for self reference like in the constructor:
// the replica will always have a different parent
if (m_sourceObj)
m_sourceObj->AddRef();
m_sourceObj->RegisterActuator(this);
SCA_IActuator::ProcessReplica();
}
bool SCA_PropertyActuator::UnlinkObject(SCA_IObject* clientobj)
{
if (clientobj == m_sourceObj)
{
// this object is being deleted, we cannot continue to track it.
m_sourceObj = NULL;
return true;
}
return false;
}
void SCA_PropertyActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
{
void **h_obj = (*obj_map)[m_sourceObj];
if (h_obj) {
if (m_sourceObj)
m_sourceObj->UnregisterActuator(this);
m_sourceObj = (SCA_IObject*)(*h_obj);
m_sourceObj->RegisterActuator(this);
}
}
/* ------------------------------------------------------------------------- */

View File

@@ -52,7 +52,7 @@ class SCA_PropertyActuator : public SCA_IActuator
int m_type;
STR_String m_propname;
STR_String m_exprtxt;
CValue* m_sourceObj; // for copy property actuator
SCA_IObject* m_sourceObj; // for copy property actuator
public:
@@ -60,7 +60,7 @@ public:
SCA_PropertyActuator(
SCA_IObject* gameobj,
CValue* sourceObj,
SCA_IObject* sourceObj,
const STR_String& propname,
const STR_String& expr,
int acttype,
@@ -74,7 +74,9 @@ public:
GetReplica(
);
void ProcessReplica();
virtual void ProcessReplica();
virtual bool UnlinkObject(SCA_IObject* clientobj);
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool
Update();

View File

@@ -47,19 +47,10 @@ SCA_PropertyEventManager::~SCA_PropertyEventManager()
}
void SCA_PropertyEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
}
void SCA_PropertyEventManager::NextFrame()
{
// check for changed properties
for (vector<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
for (set<SCA_ISensor*>::const_iterator it = m_sensors.begin();!(it==m_sensors.end());it++)
{
(*it)->Activate(m_logicmgr,NULL);
}

View File

@@ -43,7 +43,6 @@ public:
SCA_PropertyEventManager(class SCA_LogicManager* logicmgr);
virtual ~SCA_PropertyEventManager();
virtual void NextFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
//SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
};

View File

@@ -50,16 +50,9 @@ SCA_RandomEventManager::SCA_RandomEventManager(class SCA_LogicManager* logicmgr)
void SCA_RandomEventManager::NextFrame()
{
for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
SCA_ISensor *sensor = *i;
sensor->Activate(m_logicmgr, NULL);
(*i)->Activate(m_logicmgr, NULL);
}
}
void SCA_RandomEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
};

View File

@@ -45,7 +45,6 @@ public:
SCA_RandomEventManager(class SCA_LogicManager* logicmgr);
virtual void NextFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
};
#endif //__KX_RANDOMEVENTMGR

View File

@@ -65,6 +65,11 @@ void SCA_TimeEventManager::RegisterSensor(SCA_ISensor* sensor)
// not yet
}
void SCA_TimeEventManager::RemoveSensor(SCA_ISensor* sensor)
{
// empty
}
void SCA_TimeEventManager::NextFrame(double curtime, double fixedtime)

View File

@@ -45,6 +45,7 @@ public:
virtual void NextFrame(double curtime, double fixedtime);
virtual void RegisterSensor(class SCA_ISensor* sensor);
virtual void RemoveSensor(class SCA_ISensor* sensor);
void AddTimeProperty(CValue* timeval);
void RemoveTimeProperty(CValue* timeval);
};

View File

@@ -130,6 +130,12 @@ public:
) {
return m_displayarea;
};
RAS_Rect &
GetWindowArea(
) {
return m_displayarea;
}
void
BeginFrame(

View File

@@ -36,7 +36,7 @@
#include <iostream>
#include <windows.h>
#include <gl/gl.h>
//#include <gl/gl.h>
#include "GPC_Canvas.h"

View File

@@ -1,6 +1,10 @@
#include "DNA_customdata_types.h"
#include "DNA_material_types.h"
#include "DNA_scene_types.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BL_BlenderShader.h"
#include "BL_Material.h"
@@ -10,30 +14,51 @@
#include "GPU_material.h"
#endif
#include "RAS_BucketManager.h"
#include "RAS_MeshObject.h"
#include "RAS_IRasterizer.h"
/* this is evil, but we need the scene to create materials with
* lights from the correct scene .. */
static struct Scene *GetSceneForName(const STR_String& scenename)
{
Scene *sce;
const bool BL_BlenderShader::Ok()const
for (sce= (Scene*)G.main->scene.first; sce; sce= (Scene*)sce->id.next)
if (scenename == (sce->id.name+2))
return sce;
return (Scene*)G.main->scene.first;
}
bool BL_BlenderShader::Ok()
{
#ifdef BLENDER_GLSL
return (mGPUMat != 0);
VerifyShader();
return (mMat && mMat->gpumaterial);
#else
return 0;
#endif
}
BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer)
BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer)
:
#ifdef BLENDER_GLSL
mGPUMat(0),
mScene(scene),
mMat(ma),
mGPUMat(NULL),
#endif
mBound(false),
mLightLayer(lightlayer)
{
#ifdef BLENDER_GLSL
if(ma) {
GPU_material_from_blender(ma);
mGPUMat = ma->gpumaterial;
mBlenderScene = GetSceneForName(scene->GetName());
mBlendMode = GPU_BLEND_SOLID;
if(mMat) {
GPU_material_from_blender(mBlenderScene, mMat);
mGPUMat = mMat->gpumaterial;
}
#endif
}
@@ -41,17 +66,29 @@ BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer)
BL_BlenderShader::~BL_BlenderShader()
{
#ifdef BLENDER_GLSL
if(mGPUMat) {
GPU_material_unbind(mGPUMat);
mGPUMat = 0;
}
if(mMat && mMat->gpumaterial)
GPU_material_unbind(mMat->gpumaterial);
#endif
}
bool BL_BlenderShader::VerifyShader()
{
#ifdef BLENDER_GLSL
if(mMat && !mMat->gpumaterial)
GPU_material_from_blender(mBlenderScene, mMat);
mGPUMat = mMat->gpumaterial;
return (mMat && mGPUMat);
#else
return false;
#endif
}
void BL_BlenderShader::SetProg(bool enable)
{
#ifdef BLENDER_GLSL
if(mGPUMat) {
if(VerifyShader()) {
if(enable) {
GPU_material_bind(mGPUMat, mLightLayer);
mBound = true;
@@ -70,7 +107,7 @@ int BL_BlenderShader::GetAttribNum()
GPUVertexAttribs attribs;
int i, enabled = 0;
if(!mGPUMat)
if(!VerifyShader())
return enabled;
GPU_material_vertex_attributes(mGPUMat, &attribs);
@@ -96,7 +133,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
ras->SetAttribNum(0);
if(!mGPUMat)
if(!VerifyShader())
return;
if(ras->GetDrawingMode() == RAS_IRasterizer::KX_TEXTURED) {
@@ -142,9 +179,11 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
{
#ifdef BLENDER_GLSL
float obmat[4][4], viewmat[4][4], viewinvmat[4][4];
float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
if(!mGPUMat || !mBound)
VerifyShader();
if(!mGPUMat) // || !mBound)
return;
MT_Matrix4x4 model;
@@ -158,10 +197,22 @@ void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
view.invert();
view.getValue((float*)viewinvmat);
GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat);
if(ms.m_bObjectColor)
ms.m_RGBAcolor.getValue((float*)obcol);
else
obcol[0]= obcol[1]= obcol[2]= obcol[3]= 1.0f;
GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat, obcol);
mBlendMode = GPU_material_blend_mode(mGPUMat, obcol);
#endif
}
int BL_BlenderShader::GetBlendMode()
{
return mBlendMode;
}
bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
{
#ifdef BLENDER_GLSL

View File

@@ -14,7 +14,10 @@
#include "RAS_IPolygonMaterial.h"
#include "KX_Scene.h"
struct Material;
struct Scene;
class BL_Material;
#define BL_MAX_ATTRIB 16
@@ -27,21 +30,28 @@ class BL_BlenderShader
{
private:
#ifdef BLENDER_GLSL
KX_Scene *mScene;
struct Scene *mBlenderScene;
struct Material *mMat;
GPUMaterial *mGPUMat;
#endif
bool mBound;
int mLightLayer;
int mBlendMode;
bool VerifyShader();
public:
BL_BlenderShader(struct Material *ma, int lightlayer);
BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lightlayer);
virtual ~BL_BlenderShader();
const bool Ok()const;
bool Ok();
void SetProg(bool enable);
int GetAttribNum();
void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);
void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty);
int GetBlendMode();
bool Equals(BL_BlenderShader *blshader);
};

View File

@@ -129,8 +129,7 @@ enum BL_flag
TEXALPHA=8, // use alpha combiner functions
TEXNEG=16, // negate blending
HASIPO=32,
USENEGALPHA=64,
ALPHA_TEST=128
USENEGALPHA=64
};
// BL_Material::ras_mode
@@ -139,7 +138,7 @@ enum BL_ras_mode
POLY_VIS=1,
COLLIDER=2,
ZSORT=4,
TRANSP=8,
ALPHA=8,
TRIANGLE=16,
USE_LIGHT=32,
WIRE=64

View File

@@ -384,8 +384,6 @@ void BL_Texture::DisableUnit()
void BL_Texture::DisableAllTextures()
{
glDisable(GL_BLEND);
for(int i=0; i<MAXTEX; i++) {
if(GLEW_ARB_multitexture)
glActiveTextureARB(GL_TEXTURE0_ARB+i);

View File

@@ -55,28 +55,13 @@ 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()
{
// 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;
set<class SCA_ISensor*>::iterator it;
for (it = m_sensors.begin(); !(it==m_sensors.end()); it++) {
// printf("KX_NetworkEventManager::proceed sensor %.2f\n", curtime);

View File

@@ -42,9 +42,6 @@ public:
class NG_NetworkDeviceInterface *ndi);
virtual ~KX_NetworkEventManager ();
virtual void RegisterSensor(class SCA_ISensor* sensor);
virtual void RemoveSensor(class SCA_ISensor* sensor);
virtual void NextFrame();
virtual void EndFrame();

View File

@@ -38,6 +38,7 @@ extern "C" {
// ------------------------------------
#define spit(x) std::cout << x << std::endl;
BL_Shader *KX_BlenderMaterial::mLastShader = NULL;
BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL;
//static PyObject *gTextureDict = 0;
@@ -58,7 +59,8 @@ KX_BlenderMaterial::KX_BlenderMaterial(
data->tilexrep[0],
data->tileyrep[0],
data->mode,
((data->ras_mode &TRANSP)!=0),
data->transp,
((data->ras_mode &ALPHA)!=0),
((data->ras_mode &ZSORT)!=0),
lightlayer,
((data->ras_mode &TRIANGLE)!=0),
@@ -79,7 +81,6 @@ KX_BlenderMaterial::KX_BlenderMaterial(
m_flag |=RAS_BLENDERMAT;
m_flag |=(mMaterial->IdMode>=ONETEX)?RAS_MULTITEX:0;
m_flag |=(mMaterial->ras_mode & USE_LIGHT)!=0?RAS_MULTILIGHT:0;
m_flag |=(mMaterial->ras_mode &ALPHA_TEST)!=0?RAS_FORCEALPHA:0;
// figure max
int enabled = mMaterial->num_enabled;
@@ -158,12 +159,29 @@ void KX_BlenderMaterial::OnConstruction()
mConstructed = true;
}
void KX_BlenderMaterial::EndFrame()
{
if(mLastBlenderShader) {
mLastBlenderShader->SetProg(false);
mLastBlenderShader = NULL;
}
if(mLastShader) {
mLastShader->SetProg(false);
mLastShader = NULL;
}
}
void KX_BlenderMaterial::OnExit()
{
if( mShader ) {
//note, the shader here is allocated, per unique material
//and this function is called per face
mShader->SetProg(false);
//note, the shader here is allocated, per unique material
//and this function is called per face
if(mShader == mLastShader) {
mShader->SetProg(false);
mLastShader = NULL;
}
delete mShader;
mShader = 0;
}
@@ -197,13 +215,19 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
int i;
if( !enable || !mShader->Ok() ) {
// frame cleanup.
mShader->SetProg(false);
if(mShader == mLastShader) {
mShader->SetProg(false);
mLastShader = NULL;
}
ras->SetBlendingMode(TF_SOLID);
BL_Texture::DisableAllTextures();
return;
}
BL_Texture::DisableAllTextures();
mShader->SetProg(true);
mLastShader = mShader;
BL_Texture::ActivateFirst();
@@ -217,9 +241,12 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras)
}
if(!mUserDefBlend) {
setDefaultBlending();
ras->SetBlendingMode(mMaterial->transp);
}
else {
ras->SetBlendingMode(TF_SOLID);
ras->SetBlendingMode(-1); // indicates custom mode
// tested to be valid enums
glEnable(GL_BLEND);
glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
@@ -234,11 +261,14 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras
mLastBlenderShader->SetProg(false);
mLastBlenderShader= NULL;
}
ras->SetBlendingMode(TF_SOLID);
BL_Texture::DisableAllTextures();
return;
}
if(!mBlenderShader->Equals(mLastBlenderShader)) {
ras->SetBlendingMode(mMaterial->transp);
BL_Texture::DisableAllTextures();
if(mLastBlenderShader)
@@ -251,17 +281,17 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras
void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
{
if(GLEW_ARB_shader_objects && mShader)
mShader->SetProg(false);
BL_Texture::DisableAllTextures();
if( !enable )
if( !enable ) {
ras->SetBlendingMode(TF_SOLID);
return;
}
BL_Texture::ActivateFirst();
if( mMaterial->IdMode == DEFAULT_BLENDER ) {
setDefaultBlending();
ras->SetBlendingMode(mMaterial->transp);
return;
}
@@ -271,7 +301,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
mTextures[0].ActivateTexture();
mTextures[0].setTexEnv(0, true);
mTextures[0].SetMapping(mMaterial->mapping[0].mapping);
setDefaultBlending();
ras->SetBlendingMode(mMaterial->transp);
}
return;
}
@@ -294,9 +324,12 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
}
if(!mUserDefBlend) {
setDefaultBlending();
ras->SetBlendingMode(mMaterial->transp);
}
else {
ras->SetBlendingMode(TF_SOLID);
ras->SetBlendingMode(-1); // indicates custom mode
glEnable(GL_BLEND);
glBlendFunc(mBlendFunc[0], mBlendFunc[1]);
}
@@ -356,6 +389,11 @@ KX_BlenderMaterial::ActivateBlenderShaders(
{
KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
if(mLastShader) {
mLastShader->SetProg(false);
mLastShader= NULL;
}
// reset...
if(tmp->mMaterial->IsShared())
cachingInfo =0;
@@ -402,6 +440,11 @@ KX_BlenderMaterial::ActivateMat(
{
KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
if(mLastShader) {
mLastShader->SetProg(false);
mLastShader= NULL;
}
if(mLastBlenderShader) {
mLastBlenderShader->SetProg(false);
mLastBlenderShader= NULL;
@@ -451,7 +494,10 @@ KX_BlenderMaterial::Activate(
return dopass;
}
else {
mShader->SetProg(false);
if(mShader == mLastShader) {
mShader->SetProg(false);
mLastShader = NULL;
}
mPass = 0;
dopass = false;
return dopass;
@@ -499,10 +545,22 @@ bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const
void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const
{
if(mShader && GLEW_ARB_shader_objects)
if(mShader && GLEW_ARB_shader_objects) {
mShader->Update(ms, rasty);
else if(mBlenderShader && GLEW_ARB_shader_objects)
}
else if(mBlenderShader && GLEW_ARB_shader_objects) {
int blendmode;
mBlenderShader->Update(ms, rasty);
/* we do blend modes here, because they can change per object
* with the same material due to obcolor */
blendmode = mBlenderShader->GetBlendMode();
if((blendmode == TF_SOLID || blendmode == TF_ALPHA) && mMaterial->transp != TF_SOLID)
blendmode = mMaterial->transp;
rasty->SetBlendingMode(blendmode);
}
}
void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const
@@ -582,31 +640,6 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
ras->EnableTextures(false);
}
bool KX_BlenderMaterial::setDefaultBlending()
{
if( mMaterial->transp &TF_ADD) {
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glDisable ( GL_ALPHA_TEST );
return true;
}
if( mMaterial->transp & TF_ALPHA ) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable ( GL_ALPHA_TEST );
return true;
}
if( mMaterial->transp & TF_CLIP ) {
glDisable(GL_BLEND);
glEnable ( GL_ALPHA_TEST );
glAlphaFunc(GL_GREATER, 0.5f);
return false;
}
return false;
}
void KX_BlenderMaterial::setTexMatrixData(int i)
{
glMatrixMode(GL_TEXTURE);
@@ -831,12 +864,14 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
void KX_BlenderMaterial::SetBlenderGLSLShader(void)
{
if(!mBlenderShader)
mBlenderShader = new BL_BlenderShader(mMaterial->material, m_lightlayer);
mBlenderShader = new BL_BlenderShader(mScene, mMaterial->material, m_lightlayer);
if(!mBlenderShader->Ok()) {
delete mBlenderShader;
mBlenderShader = 0;
}
else
m_flag |= RAS_BLENDERGLSL;
}
KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getMaterialIndex, "getMaterialIndex()")

View File

@@ -90,11 +90,13 @@ public:
// --------------------------------
// pre calculate to avoid pops/lag at startup
virtual void OnConstruction( );
static void EndFrame();
private:
BL_Material* mMaterial;
BL_Shader* mShader;
BL_BlenderShader* mBlenderShader;
static BL_BlenderShader *mLastBlenderShader;
KX_Scene* mScene;
BL_Texture mTextures[MAXTEX]; // texture array
bool mUserDefBlend;
@@ -114,7 +116,6 @@ private:
void setBlenderShaderData( bool enable, RAS_IRasterizer *ras);
void setShaderData( bool enable, RAS_IRasterizer *ras);
bool setDefaultBlending();
void setObjectMatrixData(int i, RAS_IRasterizer *ras);
void setTexMatrixData(int i);
@@ -123,6 +124,10 @@ private:
// cleanup stuff
void OnExit();
// shader chacing
static BL_BlenderShader *mLastBlenderShader;
static BL_Shader *mLastShader;
mutable int mPass;
};

View File

@@ -13,11 +13,13 @@
#include "KX_ClientObjectInfo.h"
#include "PHY_IPhysicsEnvironment.h"
#include "CcdPhysicsEnvironment.h"
KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna)
: KX_IPhysicsController(dyna,(PHY_IPhysicsController*)this),
CcdPhysicsController(ci)
CcdPhysicsController(ci),
m_savedCollisionFlags(0)
{
}
@@ -131,9 +133,10 @@ void KX_BulletPhysicsController::getOrientation(MT_Quaternion& orn)
CcdPhysicsController::getOrientation(myorn[0],myorn[1],myorn[2],myorn[3]);
orn = MT_Quaternion(myorn[0],myorn[1],myorn[2],myorn[3]);
}
void KX_BulletPhysicsController::setOrientation(const MT_Quaternion& orn)
void KX_BulletPhysicsController::setOrientation(const MT_Matrix3x3& orn)
{
CcdPhysicsController::setOrientation(orn.x(),orn.y(),orn.z(),orn.w());
btMatrix3x3 btmat(orn[0][0], orn[0][1], orn[0][2], orn[1][0], orn[1][1], orn[1][2], orn[2][0], orn[2][1], orn[2][2]);
CcdPhysicsController::setWorldOrientation(btmat);
}
void KX_BulletPhysicsController::setPosition(const MT_Point3& pos)
{
@@ -161,14 +164,37 @@ void KX_BulletPhysicsController::setRigidBody(bool rigid)
{
}
void KX_BulletPhysicsController::SuspendDynamics()
void KX_BulletPhysicsController::SuspendDynamics(bool ghost)
{
GetRigidBody()->setActivationState(DISABLE_SIMULATION);
btRigidBody *body = GetRigidBody();
if (body->getActivationState() != DISABLE_SIMULATION)
{
btBroadphaseProxy* handle = body->getBroadphaseHandle();
m_savedCollisionFlags = body->getCollisionFlags();
m_savedMass = GetMass();
m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
m_savedCollisionFilterMask = handle->m_collisionFilterMask;
body->setActivationState(DISABLE_SIMULATION);
GetPhysicsEnvironment()->updateCcdPhysicsController(this,
0.0,
btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
btBroadphaseProxy::StaticFilter,
btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
}
}
void KX_BulletPhysicsController::RestoreDynamics()
{
GetRigidBody()->forceActivationState(ACTIVE_TAG);
btRigidBody *body = GetRigidBody();
if (body->getActivationState() == DISABLE_SIMULATION)
{
GetPhysicsEnvironment()->updateCcdPhysicsController(this,
m_savedMass,
m_savedCollisionFlags,
m_savedCollisionFilterGroup,
m_savedCollisionFilterMask);
GetRigidBody()->forceActivationState(ACTIVE_TAG);
}
}
SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)

View File

@@ -7,6 +7,11 @@
class KX_BulletPhysicsController : public KX_IPhysicsController ,public CcdPhysicsController
{
private:
int m_savedCollisionFlags;
short int m_savedCollisionFilterGroup;
short int m_savedCollisionFilterMask;
MT_Scalar m_savedMass;
public:
@@ -30,7 +35,7 @@ public:
virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local);
virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local);
virtual void getOrientation(MT_Quaternion& orn);
virtual void setOrientation(const MT_Quaternion& orn);
virtual void setOrientation(const MT_Matrix3x3& orn);
virtual void setPosition(const MT_Point3& pos);
virtual void setScaling(const MT_Vector3& scaling);
virtual MT_Scalar GetMass();
@@ -39,7 +44,7 @@ public:
virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
virtual void SuspendDynamics();
virtual void SuspendDynamics(bool ghost);
virtual void RestoreDynamics();
virtual SG_Controller* GetReplica(class SG_Node* destnode);

View File

@@ -49,7 +49,7 @@ STR_String KX_CameraActuator::Y_AXIS_STRING = "y";
KX_CameraActuator::KX_CameraActuator(
SCA_IObject* gameobj,
CValue *obj,
SCA_IObject *obj,
MT_Scalar hght,
MT_Scalar minhght,
MT_Scalar maxhght,
@@ -63,11 +63,14 @@ KX_CameraActuator::KX_CameraActuator(
m_maxHeight (maxhght),
m_x (xytog)
{
if (m_ob)
m_ob->RegisterActuator(this);
}
KX_CameraActuator::~KX_CameraActuator()
{
//nothing to do
if (m_ob)
m_ob->UnregisterActuator(this);
}
CValue*
@@ -81,8 +84,35 @@ GetReplica(
return replica;
};
void KX_CameraActuator::ProcessReplica()
{
if (m_ob)
m_ob->RegisterActuator(this);
SCA_IActuator::ProcessReplica();
}
bool KX_CameraActuator::UnlinkObject(SCA_IObject* clientobj)
{
if (clientobj == m_ob)
{
// this object is being deleted, we cannot continue to track it.
m_ob = NULL;
return true;
}
return false;
}
void KX_CameraActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
{
void **h_obj = (*obj_map)[m_ob];
if (h_obj) {
if (m_ob)
m_ob->UnregisterActuator(this);
m_ob = (SCA_IObject*)(*h_obj);
m_ob->RegisterActuator(this);
}
}
/* three functions copied from blender arith... don't know if there's an equivalent */
@@ -181,8 +211,14 @@ static void Kx_VecUpMat3(float *vec, float mat[][3], short axis)
bool KX_CameraActuator::Update(double curtime, bool frame)
{
bool result = true;
/* wondering... is it really neccesary/desirable to suppress negative */
/* events here? */
bool bNegativeEvent = IsNegativeEvent();
RemoveAllEvents();
if (bNegativeEvent || !m_ob)
return false;
KX_GameObject *obj = (KX_GameObject*) GetParent();
MT_Point3 from = obj->NodeGetWorldPosition();
MT_Matrix3x3 frommat = obj->NodeGetWorldOrientation();
@@ -195,13 +231,6 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
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? */
@@ -315,7 +344,7 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
actormat[2][0]= mat[0][2]; actormat[2][1]= mat[1][2]; actormat[2][2]= mat[2][2];
obj->NodeSetLocalOrientation(actormat);
return result;
return true;
}
CValue *KX_CameraActuator::findObject(char *obName)
@@ -404,7 +433,11 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* self,
PyObject* gameobj;
if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj))
{
m_ob = (CValue*)gameobj;
if (m_ob)
m_ob->UnregisterActuator(this);
m_ob = (SCA_IObject*)gameobj;
if (m_ob)
m_ob->RegisterActuator(this);
Py_Return;
}
PyErr_Clear();
@@ -412,10 +445,13 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* self,
char* objectname;
if (PyArg_ParseTuple(args, "s", &objectname))
{
CValue *object = (CValue*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
SCA_IObject *object = (SCA_IObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
if(object)
{
if (m_ob != NULL)
m_ob->UnregisterActuator(this);
m_ob = object;
m_ob->RegisterActuator(this);
Py_Return;
}
}

View File

@@ -49,7 +49,7 @@ class KX_CameraActuator : public SCA_IActuator
Py_Header;
private :
/** Object that will be tracked. */
CValue *m_ob;
SCA_IObject *m_ob;
/** height (float), */
//const MT_Scalar m_height;
@@ -87,7 +87,7 @@ private :
SCA_IObject *gameobj,
//const CValue *ob,
CValue *ob,
SCA_IObject *ob,
MT_Scalar hght,
MT_Scalar minhght,
MT_Scalar maxhght,
@@ -103,6 +103,7 @@ private :
/** Methods Inherited from CValue */
CValue* GetReplica();
virtual void ProcessReplica();
/** Methods inherited from SCA_IActuator */
@@ -110,7 +111,10 @@ private :
double curtime,
bool frame
);
virtual bool UnlinkObject(SCA_IObject* clientobj);
/** Methods inherited from SCA_ILogicBrick */
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */

View File

@@ -88,11 +88,17 @@ KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj,
} else {
m_refDirection /= len;
}
m_minimumBound = cos(minBound);
m_maximumBound = cos(maxBound);
m_minimumSine = sin(minBound);
m_maximumSine = sin(maxBound);
}
break;
default:
m_minimumBound = minBound;
m_maximumBound = maxBound;
m_minimumSine = 0.f;
m_maximumSine = 0.f;
break;
}
@@ -153,9 +159,9 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
KX_GameObject *obj = (KX_GameObject*) GetParent();
MT_Point3 position = obj->NodeGetWorldPosition();
MT_Point3 newposition;
MT_Vector3 direction;
MT_Vector3 direction, refDirection;
MT_Matrix3x3 rotation = obj->NodeGetWorldOrientation();
MT_Scalar filter, newdistance;
MT_Scalar filter, newdistance, cosangle;
int axis, sign;
if (m_posDampTime) {
@@ -178,16 +184,52 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
direction[2] = rotation[2][1];
axis = 1;
break;
case KX_ACT_CONSTRAINT_ORIZ:
default:
direction[0] = rotation[0][2];
direction[1] = rotation[1][2];
direction[2] = rotation[2][2];
axis = 2;
break;
}
// apply damping on the direction
if ((m_maximumBound < (1.0f-FLT_EPSILON)) || (m_minimumBound < (1.0f-FLT_EPSILON))) {
// reference direction needs to be evaluated
// 1. get the cosine between current direction and target
cosangle = direction.dot(m_refDirection);
if (cosangle >= (m_maximumBound-FLT_EPSILON) && cosangle <= (m_minimumBound+FLT_EPSILON)) {
// no change to do
result = true;
goto CHECK_TIME;
}
// 2. define a new reference direction
// compute local axis with reference direction as X and
// Y in direction X refDirection plane
MT_Vector3 zaxis = m_refDirection.cross(direction);
if (MT_fuzzyZero2(zaxis.length2())) {
// direction and refDirection are identical,
// choose any other direction to define plane
if (direction[0] < 0.9999)
zaxis = m_refDirection.cross(MT_Vector3(1.0,0.0,0.0));
else
zaxis = m_refDirection.cross(MT_Vector3(0.0,1.0,0.0));
}
MT_Vector3 yaxis = zaxis.cross(m_refDirection);
yaxis.normalize();
if (cosangle > m_minimumBound) {
// angle is too close to reference direction,
// choose a new reference that is exactly at minimum angle
refDirection = m_minimumBound * m_refDirection + m_minimumSine * yaxis;
} else {
// angle is too large, choose new reference direction at maximum angle
refDirection = m_maximumBound * m_refDirection + m_maximumSine * yaxis;
}
} else {
refDirection = m_refDirection;
}
if (m_posDampTime) {
direction = filter*direction + (1.0-filter)*m_refDirection;
// apply damping on the direction
direction = filter*direction + (1.0-filter)*refDirection;
} else {
direction = refDirection;
}
obj->AlignAxisToVect(direction, axis);
result = true;
@@ -195,9 +237,9 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
case KX_ACT_CONSTRAINT_DIRPX:
case KX_ACT_CONSTRAINT_DIRPY:
case KX_ACT_CONSTRAINT_DIRPZ:
case KX_ACT_CONSTRAINT_DIRMX:
case KX_ACT_CONSTRAINT_DIRMY:
case KX_ACT_CONSTRAINT_DIRMZ:
case KX_ACT_CONSTRAINT_DIRNX:
case KX_ACT_CONSTRAINT_DIRNY:
case KX_ACT_CONSTRAINT_DIRNZ:
switch (m_locrot) {
case KX_ACT_CONSTRAINT_DIRPX:
direction[0] = rotation[0][0];
@@ -220,21 +262,21 @@ bool KX_ConstraintActuator::Update(double curtime, bool frame)
axis = 2;
sign = 1;
break;
case KX_ACT_CONSTRAINT_DIRMX:
case KX_ACT_CONSTRAINT_DIRNX:
direction[0] = -rotation[0][0];
direction[1] = -rotation[1][0];
direction[2] = -rotation[2][0];
axis = 0;
sign = 0;
break;
case KX_ACT_CONSTRAINT_DIRMY:
case KX_ACT_CONSTRAINT_DIRNY:
direction[0] = -rotation[0][1];
direction[1] = -rotation[1][1];
direction[2] = -rotation[2][1];
axis = 1;
sign = 0;
break;
case KX_ACT_CONSTRAINT_DIRMZ:
case KX_ACT_CONSTRAINT_DIRNZ:
direction[0] = -rotation[0][2];
direction[1] = -rotation[1][2];
direction[2] = -rotation[2][2];
@@ -395,27 +437,27 @@ PyParentObject KX_ConstraintActuator::Parents[] = {
PyMethodDef KX_ConstraintActuator::Methods[] = {
{"setDamp", (PyCFunction) KX_ConstraintActuator::sPySetDamp, METH_VARARGS, SetDamp_doc},
{"getDamp", (PyCFunction) KX_ConstraintActuator::sPyGetDamp, METH_VARARGS, GetDamp_doc},
{"getDamp", (PyCFunction) KX_ConstraintActuator::sPyGetDamp, METH_NOARGS, GetDamp_doc},
{"setRotDamp", (PyCFunction) KX_ConstraintActuator::sPySetRotDamp, METH_VARARGS, SetRotDamp_doc},
{"getRotDamp", (PyCFunction) KX_ConstraintActuator::sPyGetRotDamp, METH_VARARGS, GetRotDamp_doc},
{"getRotDamp", (PyCFunction) KX_ConstraintActuator::sPyGetRotDamp, METH_NOARGS, GetRotDamp_doc},
{"setDirection", (PyCFunction) KX_ConstraintActuator::sPySetDirection, METH_VARARGS, SetDirection_doc},
{"getDirection", (PyCFunction) KX_ConstraintActuator::sPyGetDirection, METH_VARARGS, GetDirection_doc},
{"getDirection", (PyCFunction) KX_ConstraintActuator::sPyGetDirection, METH_NOARGS, GetDirection_doc},
{"setOption", (PyCFunction) KX_ConstraintActuator::sPySetOption, METH_VARARGS, SetOption_doc},
{"getOption", (PyCFunction) KX_ConstraintActuator::sPyGetOption, METH_VARARGS, GetOption_doc},
{"getOption", (PyCFunction) KX_ConstraintActuator::sPyGetOption, METH_NOARGS, GetOption_doc},
{"setTime", (PyCFunction) KX_ConstraintActuator::sPySetTime, METH_VARARGS, SetTime_doc},
{"getTime", (PyCFunction) KX_ConstraintActuator::sPyGetTime, METH_VARARGS, GetTime_doc},
{"getTime", (PyCFunction) KX_ConstraintActuator::sPyGetTime, METH_NOARGS, GetTime_doc},
{"setProperty", (PyCFunction) KX_ConstraintActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
{"getProperty", (PyCFunction) KX_ConstraintActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
{"getProperty", (PyCFunction) KX_ConstraintActuator::sPyGetProperty, METH_NOARGS, GetProperty_doc},
{"setMin", (PyCFunction) KX_ConstraintActuator::sPySetMin, METH_VARARGS, SetMin_doc},
{"getMin", (PyCFunction) KX_ConstraintActuator::sPyGetMin, METH_VARARGS, GetMin_doc},
{"getMin", (PyCFunction) KX_ConstraintActuator::sPyGetMin, METH_NOARGS, GetMin_doc},
{"setDistance", (PyCFunction) KX_ConstraintActuator::sPySetMin, METH_VARARGS, SetDistance_doc},
{"getDistance", (PyCFunction) KX_ConstraintActuator::sPyGetMin, METH_VARARGS, GetDistance_doc},
{"getDistance", (PyCFunction) KX_ConstraintActuator::sPyGetMin, METH_NOARGS, GetDistance_doc},
{"setMax", (PyCFunction) KX_ConstraintActuator::sPySetMax, METH_VARARGS, SetMax_doc},
{"getMax", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_VARARGS, GetMax_doc},
{"getMax", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_NOARGS, GetMax_doc},
{"setRayLength", (PyCFunction) KX_ConstraintActuator::sPySetMax, METH_VARARGS, SetRayLength_doc},
{"getRayLength", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_VARARGS, GetRayLength_doc},
{"getRayLength", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_NOARGS, GetRayLength_doc},
{"setLimit", (PyCFunction) KX_ConstraintActuator::sPySetLimit, METH_VARARGS, SetLimit_doc},
{"getLimit", (PyCFunction) KX_ConstraintActuator::sPyGetLimit, METH_VARARGS, GetLimit_doc},
{"getLimit", (PyCFunction) KX_ConstraintActuator::sPyGetLimit, METH_NOARGS, GetLimit_doc},
{NULL,NULL} //Sentinel
};
@@ -434,6 +476,7 @@ PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self,
PyObject* kwds) {
int dampArg;
if(!PyArg_ParseTuple(args, "i", &dampArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -446,9 +489,7 @@ PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self,
char KX_ConstraintActuator::GetDamp_doc[] =
"getDamp()\n"
"\tReturns the damping parameter.\n";
PyObject* KX_ConstraintActuator::PyGetDamp(PyObject* self,
PyObject* args,
PyObject* kwds){
PyObject* KX_ConstraintActuator::PyGetDamp(PyObject* self){
return PyInt_FromLong(m_posDampTime);
}
@@ -463,6 +504,7 @@ PyObject* KX_ConstraintActuator::PySetRotDamp(PyObject* self,
PyObject* kwds) {
int dampArg;
if(!PyArg_ParseTuple(args, "i", &dampArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -475,9 +517,7 @@ PyObject* KX_ConstraintActuator::PySetRotDamp(PyObject* self,
char KX_ConstraintActuator::GetRotDamp_doc[] =
"getRotDamp()\n"
"\tReturns the damping time for application of the constraint.\n";
PyObject* KX_ConstraintActuator::PyGetRotDamp(PyObject* self,
PyObject* args,
PyObject* kwds){
PyObject* KX_ConstraintActuator::PyGetRotDamp(PyObject* self){
return PyInt_FromLong(m_rotDampTime);
}
@@ -494,6 +534,7 @@ PyObject* KX_ConstraintActuator::PySetDirection(PyObject* self,
MT_Vector3 dir;
if(!PyArg_ParseTuple(args, "(fff)", &x, &y, &z)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
dir[0] = x;
@@ -512,9 +553,7 @@ PyObject* KX_ConstraintActuator::PySetDirection(PyObject* self,
char KX_ConstraintActuator::GetDirection_doc[] =
"getDirection()\n"
"\tReturns the reference direction of the orientation constraint as a 3-tuple.\n";
PyObject* KX_ConstraintActuator::PyGetDirection(PyObject* self,
PyObject* args,
PyObject* kwds){
PyObject* KX_ConstraintActuator::PyGetDirection(PyObject* self){
PyObject *retVal = PyList_New(3);
PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_refDirection[0]));
@@ -538,6 +577,7 @@ PyObject* KX_ConstraintActuator::PySetOption(PyObject* self,
PyObject* kwds) {
int option;
if(!PyArg_ParseTuple(args, "i", &option)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -549,9 +589,7 @@ PyObject* KX_ConstraintActuator::PySetOption(PyObject* self,
char KX_ConstraintActuator::GetOption_doc[] =
"getOption()\n"
"\tReturns the option parameter.\n";
PyObject* KX_ConstraintActuator::PyGetOption(PyObject* self,
PyObject* args,
PyObject* kwds){
PyObject* KX_ConstraintActuator::PyGetOption(PyObject* self){
return PyInt_FromLong(m_option);
}
@@ -567,6 +605,7 @@ PyObject* KX_ConstraintActuator::PySetTime(PyObject* self,
PyObject* kwds) {
int t;
if(!PyArg_ParseTuple(args, "i", &t)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -580,9 +619,7 @@ PyObject* KX_ConstraintActuator::PySetTime(PyObject* self,
char KX_ConstraintActuator::GetTime_doc[] =
"getTime()\n"
"\tReturns the time parameter.\n";
PyObject* KX_ConstraintActuator::PyGetTime(PyObject* self,
PyObject* args,
PyObject* kwds){
PyObject* KX_ConstraintActuator::PyGetTime(PyObject* self){
return PyInt_FromLong(m_activeTime);
}
@@ -597,6 +634,7 @@ PyObject* KX_ConstraintActuator::PySetProperty(PyObject* self,
PyObject* kwds) {
char *property;
if (!PyArg_ParseTuple(args, "s", &property)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
if (property == NULL) {
@@ -612,9 +650,7 @@ PyObject* KX_ConstraintActuator::PySetProperty(PyObject* self,
char KX_ConstraintActuator::GetProperty_doc[] =
"getProperty()\n"
"\tReturns the property parameter.\n";
PyObject* KX_ConstraintActuator::PyGetProperty(PyObject* self,
PyObject* args,
PyObject* kwds){
PyObject* KX_ConstraintActuator::PyGetProperty(PyObject* self){
return PyString_FromString(m_property);
}
@@ -634,6 +670,7 @@ PyObject* KX_ConstraintActuator::PySetMin(PyObject* self,
PyObject* kwds) {
float minArg;
if(!PyArg_ParseTuple(args, "f", &minArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -659,9 +696,7 @@ 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) {
PyObject* KX_ConstraintActuator::PyGetMin(PyObject* self) {
return PyFloat_FromDouble(m_minimumBound);
}
@@ -681,6 +716,7 @@ PyObject* KX_ConstraintActuator::PySetMax(PyObject* self,
PyObject* kwds){
float maxArg;
if(!PyArg_ParseTuple(args, "f", &maxArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -706,9 +742,7 @@ 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) {
PyObject* KX_ConstraintActuator::PyGetMax(PyObject* self) {
return PyFloat_FromDouble(m_maximumBound);
}
@@ -736,6 +770,7 @@ PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self,
PyObject* kwds) {
int locrotArg;
if(!PyArg_ParseTuple(args, "i", &locrotArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -747,9 +782,7 @@ PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self,
char KX_ConstraintActuator::GetLimit_doc[] =
"getLimit()\n"
"\tReturns the type of constraint.\n";
PyObject* KX_ConstraintActuator::PyGetLimit(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* KX_ConstraintActuator::PyGetLimit(PyObject* self) {
return PyInt_FromLong(m_locrot);
}

View File

@@ -48,6 +48,10 @@ protected:
float m_minimumBound;
// max (float)
float m_maximumBound;
// sinus of minimum angle
float m_minimumSine;
// sinus of maximum angle
float m_maximumSine;
// reference direction
MT_Vector3 m_refDirection;
// locrotxyz choice (pick one): only one choice allowed at a time!
@@ -80,9 +84,9 @@ protected:
KX_ACT_CONSTRAINT_DIRPX,
KX_ACT_CONSTRAINT_DIRPY,
KX_ACT_CONSTRAINT_DIRPZ,
KX_ACT_CONSTRAINT_DIRMX,
KX_ACT_CONSTRAINT_DIRMY,
KX_ACT_CONSTRAINT_DIRMZ,
KX_ACT_CONSTRAINT_DIRNX,
KX_ACT_CONSTRAINT_DIRNY,
KX_ACT_CONSTRAINT_DIRNZ,
KX_ACT_CONSTRAINT_ORIX,
KX_ACT_CONSTRAINT_ORIY,
KX_ACT_CONSTRAINT_ORIZ,
@@ -127,27 +131,27 @@ protected:
virtual PyObject* _getattr(const STR_String& attr);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDamp);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetDamp);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetDamp);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetRotDamp);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetRotDamp);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetRotDamp);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDirection);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetDirection);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetDirection);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetOption);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetOption);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetOption);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetTime);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetTime);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetTime);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetProperty);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetProperty);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetProperty);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMin);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetMin);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetMin);
static char SetDistance_doc[];
static char GetDistance_doc[];
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMax);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetMax);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetMax);
static char SetRayLength_doc[];
static char GetRayLength_doc[];
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetLimit);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetLimit);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetLimit);
};
#endif //__KX_CONSTRAINTACTUATOR

View File

@@ -61,6 +61,8 @@ typedef unsigned long uint_ptr;
#include "KX_RayCast.h"
#include "KX_PythonInit.h"
#include "KX_PyMath.h"
#include "SCA_IActuator.h"
#include "SCA_ISensor.h"
// This file defines relationships between parents and children
// in the game engine.
@@ -75,10 +77,10 @@ KX_GameObject::KX_GameObject(
SCA_IObject(T),
m_bDyna(false),
m_layer(0),
m_pBlenderObject(NULL),
m_bSuspendDynamics(false),
m_bUseObjectColor(false),
m_bIsNegativeScaling(false),
m_pBlenderObject(NULL),
m_bVisible(true),
m_pPhysicsController1(NULL),
m_pPhysicsEnvironment(NULL),
@@ -94,12 +96,9 @@ KX_GameObject::KX_GameObject(
KX_NormalParentRelation * parent_relation =
KX_NormalParentRelation::New();
m_pSGNode->SetParentRelation(parent_relation);
};
KX_GameObject::~KX_GameObject()
{
// is this delete somewhere ?
@@ -163,6 +162,7 @@ STR_String KX_GameObject::GetName()
void KX_GameObject::SetName(STR_String name)
{
m_name = name;
}; // Set the name of the value
@@ -222,6 +222,10 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
RemoveParent(scene);
obj->GetSGNode()->AddChild(GetSGNode());
if (m_pPhysicsController1)
{
m_pPhysicsController1->SuspendDynamics(true);
}
// Set us to our new scale, position, and orientation
scale1[0] = scale1[0]/scale2[0];
scale1[1] = scale1[1]/scale2[1];
@@ -258,6 +262,10 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
if (!rootlist->SearchValue(this))
// object was not in root list, add it now and increment ref count
rootlist->Add(AddRef());
if (m_pPhysicsController1)
{
m_pPhysicsController1->RestoreDynamics();
}
}
}
@@ -267,6 +275,7 @@ void KX_GameObject::ProcessReplica(KX_GameObject* replica)
replica->m_pSGNode = NULL;
replica->m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
replica->m_pClient_info->m_gameobject = replica;
replica->m_state = 0;
}
@@ -432,6 +441,7 @@ void KX_GameObject::UpdateIPO(float curframetime,
// IPO update
void
KX_GameObject::UpdateMaterialData(
dword matname_hash,
MT_Vector4 rgba,
MT_Vector3 specrgb,
MT_Scalar hard,
@@ -443,16 +453,35 @@ KX_GameObject::UpdateMaterialData(
)
{
int mesh = 0;
if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0) {
RAS_MaterialBucket::Set::iterator mit = m_meshes[mesh]->GetFirstMaterial();
for(; mit != m_meshes[mesh]->GetLastMaterial(); ++mit)
{
RAS_IPolyMaterial* poly = (*mit)->GetPolyMaterial();
if(poly->GetFlag() & RAS_BLENDERMAT )
if(poly->GetFlag() & RAS_BLENDERMAT)
{
SetObjectColor(rgba);
KX_BlenderMaterial *m = static_cast<KX_BlenderMaterial*>(poly);
m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
if (matname_hash == NULL)
{
m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
// if mesh has only one material attached to it then use original hack with no need to edit vertices (better performance)
if(!(poly->GetFlag() & RAS_BLENDERGLSL))
SetObjectColor(rgba);
}
else
{
if (matname_hash == poly->GetMaterialNameHash())
{
m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
m_meshes[mesh]->SetVertexColor(poly,rgba);
// no break here, because one blender material can be split into several game engine materials
// (e.g. one uvsphere material is split into one material at poles with ras_mode TRIANGLE and one material for the body
// if here was a break then would miss some vertices if material was split
}
}
}
}
}
@@ -714,8 +743,12 @@ MT_Vector3 KX_GameObject::GetAngularVelocity(bool local)
void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
{
if (m_pPhysicsController1)
if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{
// don't update physic controller if the object is a child:
// 1) the transformation will not be right
// 2) in this case, the physic controller is necessarily a static object
// that is updated from the normal kinematic synchronization
m_pPhysicsController1->setPosition(trans);
}
@@ -727,25 +760,22 @@ void KX_GameObject::NodeSetLocalPosition(const MT_Point3& trans)
void KX_GameObject::NodeSetLocalOrientation(const MT_Matrix3x3& rot)
{
if (m_pPhysicsController1)
if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{
m_pPhysicsController1->setOrientation(rot.getRotation());
// see note above
m_pPhysicsController1->setOrientation(rot);
}
if (GetSGNode())
GetSGNode()->SetLocalOrientation(rot);
else
{
int i;
i=0;
}
}
void KX_GameObject::NodeSetLocalScale(const MT_Vector3& scale)
{
if (m_pPhysicsController1)
if (m_pPhysicsController1 && (!GetSGNode() || !GetSGNode()->GetSGParent()))
{
// see note above
m_pPhysicsController1->setScaling(scale);
}
@@ -832,7 +862,7 @@ void KX_GameObject::Resume(void)
}
}
void KX_GameObject::Suspend(void)
void KX_GameObject::Suspend()
{
if ((!m_ignore_activity_culling)
&& (!m_suspended)) {
@@ -875,6 +905,8 @@ PyMethodDef KX_GameObject::Methods[] = {
{"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_NOARGS},
{"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
{"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
{"getChildren", (PyCFunction)KX_GameObject::sPyGetChildren,METH_NOARGS},
{"getChildrenRecursive", (PyCFunction)KX_GameObject::sPyGetChildrenRecursive,METH_NOARGS},
{"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
{"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_NOARGS},
{"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_NOARGS},
@@ -882,6 +914,7 @@ PyMethodDef KX_GameObject::Methods[] = {
KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
KX_PYMETHODTABLE(KX_GameObject, rayCast),
KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
KX_PYMETHODTABLE(KX_GameObject, getVectTo),
{NULL,NULL} //Sentinel
};
@@ -1292,20 +1325,58 @@ PyObject* KX_GameObject::PyRemoveParent(PyObject* self)
Py_RETURN_NONE;
}
static void walk_children(SG_Node* node, CListValue* list, bool recursive)
{
NodeList& children = node->GetSGChildren();
for (NodeList::iterator childit = children.begin();!(childit==children.end());++childit)
{
SG_Node* childnode = (*childit);
CValue* childobj = (CValue*)childnode->GetSGClientObject();
if (childobj != NULL) // This is a GameObject
{
// add to the list
list->Add(childobj->AddRef());
}
// if the childobj is NULL then this may be an inverse parent link
// so a non recursive search should still look down this node.
if (recursive || childobj==NULL) {
walk_children(childnode, list, recursive);
}
}
}
PyObject* KX_GameObject::PyGetChildren(PyObject* self)
{
CListValue* list = new CListValue();
walk_children(m_pSGNode, list, 0);
return list;
}
PyObject* KX_GameObject::PyGetChildrenRecursive(PyObject* self)
{
CListValue* list = new CListValue();
walk_children(m_pSGNode, list, 1);
return list;
}
PyObject* KX_GameObject::PyGetMesh(PyObject* self,
PyObject* args,
PyObject* kwds)
{
int mesh = 0;
if (PyArg_ParseTuple(args, "|i", &mesh))
if (!PyArg_ParseTuple(args, "|i", &mesh))
return NULL; // python sets a simple error
if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0)
{
if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0)
{
KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[mesh]);
return meshproxy;
}
KX_MeshProxy* meshproxy = new KX_MeshProxy(m_meshes[mesh]);
return meshproxy;
}
Py_RETURN_NONE;
}
@@ -1420,6 +1491,7 @@ PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self,
if (PyVecTo(pyvect, vect))
{
AlignAxisToVect(vect,axis,fac);
NodeUpdateGS(0.f,true);
Py_RETURN_NONE;
}
}
@@ -1485,6 +1557,54 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo,
return NULL;
}
KX_PYMETHODDEF_DOC(KX_GameObject, getVectTo,
"getVectTo(other): get vector and the distance to another point/KX_GameObject\n"
"Returns a 3-tuple with (distance,worldVector,localVector)\n")
{
MT_Point3 toPoint, fromPoint;
MT_Vector3 toDir, locToDir;
MT_Scalar distance;
PyObject *returnValue;
PyObject *pyother;
if (!PyVecArgTo(args, toPoint))
{
PyErr_Clear();
if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &pyother))
{
KX_GameObject *other = static_cast<KX_GameObject*>(pyother);
toPoint = other->NodeGetWorldPosition();
}else
{
PyErr_SetString(PyExc_TypeError, "Expected a 3D Vector or GameObject type");
return NULL;
}
}
fromPoint = NodeGetWorldPosition();
toDir = toPoint-fromPoint;
distance = toDir.length();
if (MT_fuzzyZero(distance))
{
//cout << "getVectTo() Error: Null vector!\n";
locToDir = toDir = MT_Vector3(0.0,0.0,0.0);
distance = 0.0;
} else {
toDir.normalize();
locToDir = toDir * NodeGetWorldOrientation();
}
returnValue = PyTuple_New(3);
if (returnValue) { // very unlikely to fail, python sets a memory error here.
PyTuple_SET_ITEM(returnValue, 0, PyFloat_FromDouble(distance));
PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(toDir));
PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(locToDir));
}
return returnValue;
}
bool KX_GameObject::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
{
@@ -1517,8 +1637,9 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
float dist = 0.0f;
char *propName = NULL;
if (!PyArg_ParseTuple(args,"O|fs", &pyarg, &dist, &propName))
return NULL;
if (!PyArg_ParseTuple(args,"O|fs", &pyarg, &dist, &propName)) {
return NULL; // python sets simple error
}
if (!PyVecTo(pyarg, toPoint))
{
@@ -1565,11 +1686,11 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
}
KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
"rayCast(to,from,dist,prop): cast a ray and return tuple (object,hit,normal) of contact point with object within dist that matches prop or None if no hit\n"
"rayCast(to,from,dist,prop): cast a ray and return tuple (object,hit,normal) of contact point with object within dist that matches prop or (None,None,None) tuple if no hit\n"
" prop = property name that object must have; can be omitted => detect any object\n"
" dist = max distance to look (can be negative => look behind); 0 or omitted => detect up to to\n"
" from = 3-tuple or object reference for origin of ray (if object, use center of object)\n"
" Can None or omitted => start from self object center\n"
" Can be None or omitted => start from self object center\n"
" to = 3-tuple or object reference for destination of ray (if object, use center of object)\n"
"Note: the object on which you call this method matters: the ray will ignore it if it goes through it\n")
{
@@ -1581,8 +1702,9 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
char *propName = NULL;
KX_GameObject *other;
if (!PyArg_ParseTuple(args,"O|Ofs", &pyto, &pyfrom, &dist, &propName))
return NULL;
if (!PyArg_ParseTuple(args,"O|Ofs", &pyto, &pyfrom, &dist, &propName)) {
return NULL; // Python sets a simple error
}
if (!PyVecTo(pyto, toPoint))
{
@@ -1640,16 +1762,12 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
if (m_pHitObject)
{
PyObject* returnValue = PyTuple_New(3);
if (!returnValue)
return NULL;
PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->AddRef());
PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(resultPoint));
PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(resultNormal));
if (returnValue) { // unlikely this would ever fail, if it does python sets an error
PyTuple_SET_ITEM(returnValue, 0, m_pHitObject->AddRef());
PyTuple_SET_ITEM(returnValue, 1, PyObjectFrom(resultPoint));
PyTuple_SET_ITEM(returnValue, 2, PyObjectFrom(resultNormal));
}
return returnValue;
//return Py_BuildValue("(O,(fff),(fff))",
// m_pHitObject->AddRef(), // trick: KX_GameObject are not true Python object, they use a difference reference count system
// resultPoint[0], resultPoint[1], resultPoint[2],
// resultNormal[0], resultNormal[1], resultNormal[2]);
}
return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
//Py_RETURN_NONE;
@@ -1660,6 +1778,20 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
* --------------------------------------------------------------------- */
void KX_GameObject::Relink(GEN_Map<GEN_HashedPtr, void*> *map_parameter)
{
/* intentionally empty ? */
// we will relink the sensors and actuators that use object references
// if the object is part of the replicated hierarchy, use the new
// object reference instead
SCA_SensorList& sensorlist = GetSensors();
SCA_SensorList::iterator sit;
for (sit=sensorlist.begin(); sit != sensorlist.end(); sit++)
{
(*sit)->Relink(map_parameter);
}
SCA_ActuatorList& actuatorlist = GetActuators();
SCA_ActuatorList::iterator ait;
for (ait=actuatorlist.begin(); ait != actuatorlist.end(); ait++)
{
(*ait)->Relink(map_parameter);
}
}

View File

@@ -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
@@ -513,6 +521,7 @@ public:
*/
void
UpdateMaterialData(
dword matname_hash,
MT_Vector4 rgba,
MT_Vector3 specrgb,
MT_Scalar hard,
@@ -738,6 +747,8 @@ public:
KX_PYMETHOD_NOARGS(KX_GameObject,GetParent);
KX_PYMETHOD_O(KX_GameObject,SetParent);
KX_PYMETHOD_NOARGS(KX_GameObject,RemoveParent);
KX_PYMETHOD_NOARGS(KX_GameObject,GetChildren);
KX_PYMETHOD_NOARGS(KX_GameObject,GetChildrenRecursive);
KX_PYMETHOD(KX_GameObject,GetMesh);
KX_PYMETHOD_NOARGS(KX_GameObject,GetPhysicsId);
KX_PYMETHOD_NOARGS(KX_GameObject,GetPropertyNames);
@@ -745,6 +756,7 @@ public:
KX_PYMETHOD_DOC(KX_GameObject,rayCastTo);
KX_PYMETHOD_DOC(KX_GameObject,rayCast);
KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo);
KX_PYMETHOD_DOC(KX_GameObject,getVectTo);
private :

View File

@@ -71,14 +71,15 @@ public:
virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) = 0;
virtual void getOrientation(MT_Quaternion& orn)=0;
virtual void setOrientation(const MT_Quaternion& orn)=0;
virtual void setOrientation(const MT_Matrix3x3& 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 SuspendDynamics(bool ghost=false)=0;
virtual void RestoreDynamics()=0;
virtual SG_Controller* GetReplica(class SG_Node* destnode)=0;

View File

@@ -430,27 +430,27 @@ PyMethodDef KX_IpoActuator::Methods[] = {
{"setStart", (PyCFunction) KX_IpoActuator::sPySetStart,
METH_VARARGS, SetStart_doc},
{"getStart", (PyCFunction) KX_IpoActuator::sPyGetStart,
METH_VARARGS, GetStart_doc},
METH_NOARGS, GetStart_doc},
{"setEnd", (PyCFunction) KX_IpoActuator::sPySetEnd,
METH_VARARGS, SetEnd_doc},
{"getEnd", (PyCFunction) KX_IpoActuator::sPyGetEnd,
METH_VARARGS, GetEnd_doc},
METH_NOARGS, GetEnd_doc},
{"setIpoAsForce", (PyCFunction) KX_IpoActuator::sPySetIpoAsForce,
METH_VARARGS, SetIpoAsForce_doc},
{"getIpoAsForce", (PyCFunction) KX_IpoActuator::sPyGetIpoAsForce,
METH_VARARGS, GetIpoAsForce_doc},
METH_NOARGS, GetIpoAsForce_doc},
{"setIpoAdd", (PyCFunction) KX_IpoActuator::sPySetIpoAdd,
METH_VARARGS, SetIpoAdd_doc},
{"getIpoAdd", (PyCFunction) KX_IpoActuator::sPyGetIpoAdd,
METH_VARARGS, GetIpoAdd_doc},
METH_NOARGS, GetIpoAdd_doc},
{"setType", (PyCFunction) KX_IpoActuator::sPySetType,
METH_VARARGS, SetType_doc},
{"getType", (PyCFunction) KX_IpoActuator::sPyGetType,
METH_VARARGS, GetType_doc},
METH_NOARGS, GetType_doc},
{"setForceIpoActsLocal", (PyCFunction) KX_IpoActuator::sPySetForceIpoActsLocal,
METH_VARARGS, SetForceIpoActsLocal_doc},
{"getForceIpoActsLocal", (PyCFunction) KX_IpoActuator::sPyGetForceIpoActsLocal,
METH_VARARGS, GetForceIpoActsLocal_doc},
METH_NOARGS, GetForceIpoActsLocal_doc},
{NULL,NULL} //Sentinel
};
@@ -480,6 +480,7 @@ PyObject* KX_IpoActuator::PySet(PyObject* self,
int startFrame, stopFrame;
if(!PyArg_ParseTuple(args, "siii", &mode, &startFrame,
&stopFrame, &forceToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
modenum = string2mode(mode);
@@ -515,6 +516,7 @@ PyObject* KX_IpoActuator::PySetProperty(PyObject* self,
/* args: property */
char *propertyName;
if(!PyArg_ParseTuple(args, "s", &propertyName)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -533,6 +535,7 @@ PyObject* KX_IpoActuator::PySetStart(PyObject* self,
PyObject* kwds) {
float startArg;
if(!PyArg_ParseTuple(args, "f", &startArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -544,9 +547,7 @@ PyObject* KX_IpoActuator::PySetStart(PyObject* self,
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) {
PyObject* KX_IpoActuator::PyGetStart(PyObject* self) {
return PyFloat_FromDouble(m_startframe);
}
@@ -560,6 +561,7 @@ PyObject* KX_IpoActuator::PySetEnd(PyObject* self,
PyObject* kwds) {
float endArg;
if(!PyArg_ParseTuple(args, "f", &endArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -571,9 +573,7 @@ PyObject* KX_IpoActuator::PySetEnd(PyObject* self,
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) {
PyObject* KX_IpoActuator::PyGetEnd(PyObject* self) {
return PyFloat_FromDouble(m_endframe);
}
@@ -588,6 +588,7 @@ PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self,
int boolArg;
if (!PyArg_ParseTuple(args, "i", &boolArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -601,9 +602,7 @@ PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self,
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) {
PyObject* KX_IpoActuator::PyGetIpoAsForce(PyObject* self) {
return BoolToPyArg(m_ipo_as_force);
}
@@ -618,6 +617,7 @@ PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self,
int boolArg;
if (!PyArg_ParseTuple(args, "i", &boolArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -631,9 +631,7 @@ PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self,
char KX_IpoActuator::GetIpoAdd_doc[] =
"getIpoAsAdd()\n"
"\tReturns whether to interpret the ipo as additive rather than absolute.\n";
PyObject* KX_IpoActuator::PyGetIpoAdd(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* KX_IpoActuator::PyGetIpoAdd(PyObject* self) {
return BoolToPyArg(m_ipo_add);
}
@@ -648,6 +646,7 @@ PyObject* KX_IpoActuator::PySetType(PyObject* self,
int typeArg;
if (!PyArg_ParseTuple(args, "i", &typeArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -662,9 +661,7 @@ PyObject* KX_IpoActuator::PySetType(PyObject* self,
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) {
PyObject* KX_IpoActuator::PyGetType(PyObject* self) {
return PyInt_FromLong(m_type);
}
@@ -681,6 +678,7 @@ PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self,
int boolArg;
if (!PyArg_ParseTuple(args, "i", &boolArg)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
@@ -693,9 +691,7 @@ 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) {
PyObject* KX_IpoActuator::PyGetForceIpoActsLocal(PyObject* self) {
return BoolToPyArg(m_ipo_local);
}

View File

@@ -143,17 +143,17 @@ public:
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_NOARGS(KX_IpoActuator,GetStart);
KX_PYMETHOD_DOC(KX_IpoActuator,SetEnd);
KX_PYMETHOD_DOC(KX_IpoActuator,GetEnd);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetEnd);
KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAsForce);
KX_PYMETHOD_DOC(KX_IpoActuator,GetIpoAsForce);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetIpoAsForce);
KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAdd);
KX_PYMETHOD_DOC(KX_IpoActuator,GetIpoAdd);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetIpoAdd);
KX_PYMETHOD_DOC(KX_IpoActuator,SetType);
KX_PYMETHOD_DOC(KX_IpoActuator,GetType);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetType);
KX_PYMETHOD_DOC(KX_IpoActuator,SetForceIpoActsLocal);
KX_PYMETHOD_DOC(KX_IpoActuator,GetForceIpoActsLocal);
KX_PYMETHOD_DOC_NOARGS(KX_IpoActuator,GetForceIpoActsLocal);
};

View File

@@ -118,7 +118,6 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
m_bInitialized(false),
m_activecam(0),
m_bFixedTime(false),
m_game2ipo(false),
m_firstframe(true),
@@ -148,6 +147,8 @@ KX_KetsjiEngine::KX_KetsjiEngine(KX_ISystem* system)
m_showBackground(false),
m_show_debug_properties(false),
m_game2ipo(false),
// Default behavior is to hide the cursor every frame.
m_hideCursor(false),

View File

@@ -37,6 +37,7 @@ bool KX_MaterialIpoController::Update(double currentTime)
//kxgameobj->SetObjectColor(m_rgba);
kxgameobj->UpdateMaterialData(
m_matname_hash,
m_rgba,
m_specrgb,
m_hard,

View File

@@ -7,6 +7,8 @@
#include "SG_Spatial.h"
#include "KX_IInterpolator.h"
#include "STR_String.h" //typedef dword
class KX_MaterialIpoController : public SG_Controller
{
public:
@@ -23,10 +25,12 @@ private:
bool m_modified;
double m_ipotime;
dword m_matname_hash;
public:
KX_MaterialIpoController() :
KX_MaterialIpoController(dword matname_hash) :
m_modified(true),
m_ipotime(0.0)
m_ipotime(0.0),
m_matname_hash(matname_hash)
{}
virtual ~KX_MaterialIpoController();
virtual SG_Controller* GetReplica(class SG_Node* destnode);

View File

@@ -98,6 +98,14 @@ void KX_NearSensor::RegisterSumo(KX_TouchEventManager *touchman)
}
}
void KX_NearSensor::UnregisterSumo(KX_TouchEventManager* touchman)
{
if (m_physCtrl)
{
touchman->GetPhysicsEnvironment()->removeSensor(m_physCtrl);
}
}
CValue* KX_NearSensor::GetReplica()
{
KX_NearSensor* replica = new KX_NearSensor(*this);
@@ -135,9 +143,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 +156,7 @@ void KX_NearSensor::ReParent(SCA_IObject* parent)
*/
((KX_GameObject*)GetParent())->GetSGNode()->ComputeWorldTransforms(NULL);
SynchronizeTransform();
SCA_ISensor::ReParent(parent);
}

View File

@@ -77,6 +77,7 @@ public:
const PHY_CollData * coll_data);
virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2);
virtual void RegisterSumo(KX_TouchEventManager *touchman);
virtual void UnregisterSumo(KX_TouchEventManager* touchman);
virtual PyObject* _getattr(const STR_String& attr);

View File

@@ -304,27 +304,27 @@ PyParentObject KX_ObjectActuator::Parents[] = {
};
PyMethodDef KX_ObjectActuator::Methods[] = {
{"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_VARARGS},
{"getForce", (PyCFunction) KX_ObjectActuator::sPyGetForce, METH_NOARGS},
{"setForce", (PyCFunction) KX_ObjectActuator::sPySetForce, METH_VARARGS},
{"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_VARARGS},
{"getTorque", (PyCFunction) KX_ObjectActuator::sPyGetTorque, METH_NOARGS},
{"setTorque", (PyCFunction) KX_ObjectActuator::sPySetTorque, METH_VARARGS},
{"getDLoc", (PyCFunction) KX_ObjectActuator::sPyGetDLoc, METH_VARARGS},
{"getDLoc", (PyCFunction) KX_ObjectActuator::sPyGetDLoc, METH_NOARGS},
{"setDLoc", (PyCFunction) KX_ObjectActuator::sPySetDLoc, METH_VARARGS},
{"getDRot", (PyCFunction) KX_ObjectActuator::sPyGetDRot, METH_VARARGS},
{"getDRot", (PyCFunction) KX_ObjectActuator::sPyGetDRot, METH_NOARGS},
{"setDRot", (PyCFunction) KX_ObjectActuator::sPySetDRot, METH_VARARGS},
{"getLinearVelocity", (PyCFunction) KX_ObjectActuator::sPyGetLinearVelocity, METH_VARARGS},
{"getLinearVelocity", (PyCFunction) KX_ObjectActuator::sPyGetLinearVelocity, METH_NOARGS},
{"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS},
{"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_VARARGS},
{"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_NOARGS},
{"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS},
{"setDamping", (PyCFunction) KX_ObjectActuator::sPySetDamping, METH_VARARGS},
{"getDamping", (PyCFunction) KX_ObjectActuator::sPyGetDamping, METH_VARARGS},
{"getDamping", (PyCFunction) KX_ObjectActuator::sPyGetDamping, METH_NOARGS},
{"setForceLimitX", (PyCFunction) KX_ObjectActuator::sPySetForceLimitX, METH_VARARGS},
{"getForceLimitX", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitX, METH_VARARGS},
{"getForceLimitX", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitX, METH_NOARGS},
{"setForceLimitY", (PyCFunction) KX_ObjectActuator::sPySetForceLimitY, METH_VARARGS},
{"getForceLimitY", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitY, METH_VARARGS},
{"getForceLimitY", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitY, METH_NOARGS},
{"setForceLimitZ", (PyCFunction) KX_ObjectActuator::sPySetForceLimitZ, METH_VARARGS},
{"getForceLimitZ", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitZ, METH_VARARGS},
{"setPID", (PyCFunction) KX_ObjectActuator::sPyGetPID, METH_VARARGS},
{"getForceLimitZ", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitZ, METH_NOARGS},
{"setPID", (PyCFunction) KX_ObjectActuator::sPyGetPID, METH_NOARGS},
{"getPID", (PyCFunction) KX_ObjectActuator::sPySetPID, METH_VARARGS},
@@ -340,9 +340,7 @@ PyObject* KX_ObjectActuator::_getattr(const STR_String& attr) {
/* Removed! */
/* 2. getForce */
PyObject* KX_ObjectActuator::PyGetForce(PyObject* self,
PyObject* args,
PyObject* kwds)
PyObject* KX_ObjectActuator::PyGetForce(PyObject* self)
{
PyObject *retVal = PyList_New(4);
@@ -362,6 +360,7 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* self,
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_force.setValue(vecArg);
@@ -371,9 +370,7 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* self,
}
/* 4. getTorque */
PyObject* KX_ObjectActuator::PyGetTorque(PyObject* self,
PyObject* args,
PyObject* kwds)
PyObject* KX_ObjectActuator::PyGetTorque(PyObject* self)
{
PyObject *retVal = PyList_New(4);
@@ -393,6 +390,7 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* self,
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_torque.setValue(vecArg);
@@ -402,9 +400,7 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* self,
}
/* 6. getDLoc */
PyObject* KX_ObjectActuator::PyGetDLoc(PyObject* self,
PyObject* args,
PyObject* kwds)
PyObject* KX_ObjectActuator::PyGetDLoc(PyObject* self)
{
PyObject *retVal = PyList_New(4);
@@ -424,6 +420,7 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self,
int bToggle = 0;
if(!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_dloc.setValue(vecArg);
@@ -433,9 +430,7 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self,
}
/* 8. getDRot */
PyObject* KX_ObjectActuator::PyGetDRot(PyObject* self,
PyObject* args,
PyObject* kwds)
PyObject* KX_ObjectActuator::PyGetDRot(PyObject* self)
{
PyObject *retVal = PyList_New(4);
@@ -455,6 +450,7 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* self,
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_drot.setValue(vecArg);
@@ -464,9 +460,7 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* self,
}
/* 10. getLinearVelocity */
PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self) {
PyObject *retVal = PyList_New(4);
PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_linear_velocity[0]));
@@ -485,6 +479,7 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self,
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_linear_velocity.setValue(vecArg);
@@ -495,9 +490,7 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self,
/* 12. getAngularVelocity */
PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self) {
PyObject *retVal = PyList_New(4);
PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_angular_velocity[0]));
@@ -515,6 +508,7 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self,
int bToggle = 0;
if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
&vecArg[2], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_angular_velocity.setValue(vecArg);
@@ -529,6 +523,7 @@ PyObject* KX_ObjectActuator::PySetDamping(PyObject* self,
PyObject* kwds) {
int damping = 0;
if (!PyArg_ParseTuple(args, "i", &damping) || damping < 0 || damping > 1000) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_damping = damping;
@@ -536,15 +531,11 @@ PyObject* KX_ObjectActuator::PySetDamping(PyObject* self,
}
/* 13. getVelocityDamping */
PyObject* KX_ObjectActuator::PyGetDamping(PyObject* self,
PyObject* args,
PyObject* kwds) {
PyObject* KX_ObjectActuator::PyGetDamping(PyObject* self) {
return Py_BuildValue("i",m_damping);
}
/* 6. getForceLimitX */
PyObject* KX_ObjectActuator::PyGetForceLimitX(PyObject* self,
PyObject* args,
PyObject* kwds)
PyObject* KX_ObjectActuator::PyGetForceLimitX(PyObject* self)
{
PyObject *retVal = PyList_New(3);
@@ -562,6 +553,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* self,
float vecArg[2];
int bToggle = 0;
if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_drot[0] = vecArg[0];
@@ -571,9 +563,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* self,
}
/* 6. getForceLimitY */
PyObject* KX_ObjectActuator::PyGetForceLimitY(PyObject* self,
PyObject* args,
PyObject* kwds)
PyObject* KX_ObjectActuator::PyGetForceLimitY(PyObject* self)
{
PyObject *retVal = PyList_New(3);
@@ -591,6 +581,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* self,
float vecArg[2];
int bToggle = 0;
if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_drot[1] = vecArg[0];
@@ -600,9 +591,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* self,
}
/* 6. getForceLimitZ */
PyObject* KX_ObjectActuator::PyGetForceLimitZ(PyObject* self,
PyObject* args,
PyObject* kwds)
PyObject* KX_ObjectActuator::PyGetForceLimitZ(PyObject* self)
{
PyObject *retVal = PyList_New(3);
@@ -620,6 +609,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* self,
float vecArg[2];
int bToggle = 0;
if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_drot[2] = vecArg[0];
@@ -629,9 +619,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* self,
}
/* 4. getPID */
PyObject* KX_ObjectActuator::PyGetPID(PyObject* self,
PyObject* args,
PyObject* kwds)
PyObject* KX_ObjectActuator::PyGetPID(PyObject* self)
{
PyObject *retVal = PyList_New(3);
@@ -648,6 +636,7 @@ PyObject* KX_ObjectActuator::PySetPID(PyObject* self,
{
float vecArg[3];
if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2])) {
PyErr_SetString(PyExc_TypeError, "Invalid arguments");
return NULL;
}
m_torque.setValue(vecArg);

View File

@@ -155,27 +155,27 @@ public:
virtual PyObject* _getattr(const STR_String& attr);
KX_PYMETHOD(KX_ObjectActuator,GetForce);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForce);
KX_PYMETHOD(KX_ObjectActuator,SetForce);
KX_PYMETHOD(KX_ObjectActuator,GetTorque);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetTorque);
KX_PYMETHOD(KX_ObjectActuator,SetTorque);
KX_PYMETHOD(KX_ObjectActuator,GetDLoc);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetDLoc);
KX_PYMETHOD(KX_ObjectActuator,SetDLoc);
KX_PYMETHOD(KX_ObjectActuator,GetDRot);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetDRot);
KX_PYMETHOD(KX_ObjectActuator,SetDRot);
KX_PYMETHOD(KX_ObjectActuator,GetLinearVelocity);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetLinearVelocity);
KX_PYMETHOD(KX_ObjectActuator,SetLinearVelocity);
KX_PYMETHOD(KX_ObjectActuator,GetAngularVelocity);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetAngularVelocity);
KX_PYMETHOD(KX_ObjectActuator,SetAngularVelocity);
KX_PYMETHOD(KX_ObjectActuator,SetDamping);
KX_PYMETHOD(KX_ObjectActuator,GetDamping);
KX_PYMETHOD(KX_ObjectActuator,GetForceLimitX);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetDamping);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForceLimitX);
KX_PYMETHOD(KX_ObjectActuator,SetForceLimitX);
KX_PYMETHOD(KX_ObjectActuator,GetForceLimitY);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForceLimitY);
KX_PYMETHOD(KX_ObjectActuator,SetForceLimitY);
KX_PYMETHOD(KX_ObjectActuator,GetForceLimitZ);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForceLimitZ);
KX_PYMETHOD(KX_ObjectActuator,SetForceLimitZ);
KX_PYMETHOD(KX_ObjectActuator,GetPID);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetPID);
KX_PYMETHOD(KX_ObjectActuator,SetPID);
};

View File

@@ -133,8 +133,9 @@ void KX_OdePhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool l
ODEPhysicsController::SetLinearVelocity(lin_vel[0],lin_vel[1],lin_vel[2],local);
}
void KX_OdePhysicsController::setOrientation(const MT_Quaternion& orn)
void KX_OdePhysicsController::setOrientation(const MT_Matrix3x3& rot)
{
MT_Quaternion orn = rot.getRotation();
ODEPhysicsController::setOrientation(orn[0],orn[1],orn[2],orn[3]);
}
@@ -177,7 +178,7 @@ void KX_OdePhysicsController::setRigidBody(bool rigid)
}
void KX_OdePhysicsController::SuspendDynamics()
void KX_OdePhysicsController::SuspendDynamics(bool)
{
ODEPhysicsController::SuspendDynamics();
}

View File

@@ -67,14 +67,14 @@ public:
virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local);
virtual void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
virtual void getOrientation(MT_Quaternion& orn);
virtual void setOrientation(const MT_Quaternion& orn);
virtual void setOrientation(const MT_Matrix3x3& 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 void SuspendDynamics();
virtual void SuspendDynamics(bool);
virtual void RestoreDynamics();

View File

@@ -46,19 +46,22 @@
KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj,
int mode,
CValue *ob,
SCA_IObject *ob,
PyTypeObject* T)
: SCA_IActuator(gameobj, T),
m_mode(mode),
m_ob(ob)
{
if (m_ob)
m_ob->RegisterActuator(this);
}
KX_ParentActuator::~KX_ParentActuator()
{
/* intentionally empty */
if (m_ob)
m_ob->UnregisterActuator(this);
}
@@ -73,6 +76,36 @@ CValue* KX_ParentActuator::GetReplica()
return replica;
}
void KX_ParentActuator::ProcessReplica()
{
if (m_ob)
m_ob->RegisterActuator(this);
SCA_IActuator::ProcessReplica();
}
bool KX_ParentActuator::UnlinkObject(SCA_IObject* clientobj)
{
if (clientobj == m_ob)
{
// this object is being deleted, we cannot continue to track it.
m_ob = NULL;
return true;
}
return false;
}
void KX_ParentActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
{
void **h_obj = (*obj_map)[m_ob];
if (h_obj) {
if (m_ob)
m_ob->UnregisterActuator(this);
m_ob = (SCA_IObject*)(*h_obj);
m_ob->RegisterActuator(this);
}
}
bool KX_ParentActuator::Update()
@@ -87,7 +120,8 @@ bool KX_ParentActuator::Update()
KX_Scene *scene = PHY_GetActiveScene();
switch (m_mode) {
case KX_PARENT_SET:
obj->SetParent(scene, (KX_GameObject*)m_ob);
if (m_ob)
obj->SetParent(scene, (KX_GameObject*)m_ob);
break;
case KX_PARENT_REMOVE:
obj->RemoveParent(scene);
@@ -148,7 +182,11 @@ PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* args, PyObjec
PyObject* gameobj;
if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj))
{
m_ob = (CValue*)gameobj;
if (m_ob != NULL)
m_ob->UnregisterActuator(this);
m_ob = (SCA_IObject*)gameobj;
if (m_ob)
m_ob->RegisterActuator(this);
Py_Return;
}
PyErr_Clear();
@@ -156,10 +194,13 @@ PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* args, PyObjec
char* objectname;
if (PyArg_ParseTuple(args, "s", &objectname))
{
CValue *object = (CValue*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
SCA_IObject *object = (SCA_IObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));
if(object)
{
if (m_ob != NULL)
m_ob->UnregisterActuator(this);
m_ob = object;
m_ob->RegisterActuator(this);
Py_Return;
}
}

View File

@@ -47,7 +47,7 @@ class KX_ParentActuator : public SCA_IActuator
int m_mode;
/** Object to set as parent */
CValue *m_ob;
SCA_IObject *m_ob;
@@ -62,12 +62,15 @@ class KX_ParentActuator : public SCA_IActuator
KX_ParentActuator(class SCA_IObject* gameobj,
int mode,
CValue *ob,
SCA_IObject *ob,
PyTypeObject* T=&Type);
virtual ~KX_ParentActuator();
virtual bool Update();
virtual CValue* GetReplica();
virtual void ProcessReplica();
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool UnlinkObject(SCA_IObject* clientobj);
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */

View File

@@ -59,7 +59,8 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname,
int tilexrep,
int tileyrep,
int mode,
bool transparant,
int transp,
bool alpha,
bool zsort,
int lightlayer,
bool bIsTriangle,
@@ -74,7 +75,8 @@ KX_PolygonMaterial::KX_PolygonMaterial(const STR_String &texname,
tilexrep,
tileyrep,
mode,
transparant,
transp,
alpha,
zsort,
lightlayer,
bIsTriangle,
@@ -245,7 +247,7 @@ PyObject* KX_PolygonMaterial::_getattr(const STR_String& attr)
if (attr == "drawingmode")
return PyInt_FromLong(m_drawingmode);
if (attr == "transparent")
return PyInt_FromLong(m_transparant);
return PyInt_FromLong(m_alpha);
if (attr == "zsort")
return PyInt_FromLong(m_zsort);
if (attr == "lightlayer")
@@ -312,7 +314,7 @@ int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue)
if (attr == "transparent")
{
m_transparant = value;
m_alpha = value;
return 0;
}

View File

@@ -64,7 +64,8 @@ public:
int tilexrep,
int tileyrep,
int mode,
bool transparant,
int transp,
bool alpha,
bool zsort,
int lightlayer,
bool bIsTriangle,

View File

@@ -84,7 +84,10 @@ bool PyMatTo(PyObject* pymat, T& mat)
}
} else
noerror = false;
if (noerror==false)
PyErr_SetString(PyExc_TypeError, "could not be converted to a matrix (sequence of sequences)");
return noerror;
}
@@ -97,9 +100,13 @@ bool PyVecTo(PyObject* pyval, T& vec)
if (PySequence_Check(pyval))
{
unsigned int numitems = PySequence_Size(pyval);
if (numitems != Size(vec))
if (numitems != Size(vec)) {
char err[128];
sprintf(err, "error setting vector, %d args, should be %d", numitems, Size(vec));
PyErr_SetString(PyExc_AttributeError, err);
return false;
}
for (unsigned int x = 0; x < numitems; x++)
{
PyObject *item = PySequence_GetItem(pyval, x); /* new ref */
@@ -107,7 +114,17 @@ bool PyVecTo(PyObject* pyval, T& vec)
Py_DECREF(item);
}
if (PyErr_Occurred()) {
PyErr_SetString(PyExc_AttributeError, "one or more of the items in the sequence was not a float");
return false;
}
return true;
} else
{
char err[128];
sprintf(err, "not a sequence type, expected a sequence of numbers size %d", Size(vec));
PyErr_SetString(PyExc_AttributeError, err);
}
return false;

View File

@@ -756,6 +756,15 @@ PyObject* initGameLogic(KX_Scene* scene) // quick hack to get gravity hook
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);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRPX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPX);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRPY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPY);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRPY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPY);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRNX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNX);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRNY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNY);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_DIRNY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRNY);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIX, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIY, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIY);
KX_MACRO_addTypesToDict(d, KX_CONSTRAINTACT_ORIZ, KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIZ);
/* 4. Ipo actuator, simple part */
KX_MACRO_addTypesToDict(d, KX_IPOACT_PLAY, KX_IpoActuator::KX_ACT_IPO_PLAY);

View File

@@ -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!
@@ -175,8 +176,10 @@ void KX_RadarSensor::SynchronizeTransform()
if (m_physCtrl)
{
m_physCtrl->setPosition(trans.getOrigin().x(),trans.getOrigin().y(),trans.getOrigin().z());
m_physCtrl->setOrientation(trans.getRotation().x(),trans.getRotation().y(),trans.getRotation().z(),trans.getRotation().w());
MT_Quaternion orn = trans.getRotation();
MT_Point3 pos = trans.getOrigin();
m_physCtrl->setPosition(pos[0],pos[1],pos[2]);
m_physCtrl->setOrientation(orn[0],orn[1],orn[2],orn[3]);
m_physCtrl->calcXform();
}

View File

@@ -44,14 +44,9 @@ using namespace std;
void KX_RayEventManager::NextFrame()
{
for (vector<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
for (set<class SCA_ISensor*>::const_iterator i= m_sensors.begin();!(i==m_sensors.end());i++)
{
SCA_ISensor *sensor = *i;
sensor->Activate(m_logicmgr, NULL);
(*i)->Activate(m_logicmgr, NULL);
}
}
void KX_RayEventManager::RegisterSensor(SCA_ISensor* sensor)
{
m_sensors.push_back(sensor);
};

View File

@@ -45,7 +45,6 @@ public:
m_logicmgr(logicmgr)
{}
virtual void NextFrame();
virtual void RegisterSensor(SCA_ISensor* sensor);
};
#endif //__KX_RAYEVENTMGR

View File

@@ -137,6 +137,17 @@ bool KX_SCA_AddObjectActuator::UnlinkObject(SCA_IObject* clientobj)
return false;
}
void KX_SCA_AddObjectActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
{
void **h_obj = (*obj_map)[m_OriginalObject];
if (h_obj) {
if (m_OriginalObject)
m_OriginalObject->UnregisterActuator(this);
m_OriginalObject = (SCA_IObject*)(*h_obj);
m_OriginalObject->RegisterActuator(this);
}
}
/* ------------------------------------------------------------------------- */
/* Python functions */

View File

@@ -95,6 +95,9 @@ public:
virtual bool
UnlinkObject(SCA_IObject* clientobj);
virtual void
Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool
Update();

View File

@@ -37,6 +37,7 @@
#include "MT_assert.h"
#include "KX_KetsjiEngine.h"
#include "KX_BlenderMaterial.h"
#include "RAS_IPolygonMaterial.h"
#include "ListValue.h"
#include "SCA_LogicManager.h"
@@ -66,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"
@@ -90,6 +93,9 @@ void* KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
{
KX_GameObject* replica = ((KX_Scene*)scene)->AddNodeReplicaObject(node,(KX_GameObject*)gameobj);
if(replica)
replica->Release();
return (void*)replica;
}
@@ -114,13 +120,13 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
PyObjectPlus(&KX_Scene::Type),
m_keyboardmgr(NULL),
m_mousemgr(NULL),
m_sceneConverter(NULL),
m_physicsEnvironment(0),
m_sceneName(sceneName),
m_adi(adi),
m_networkDeviceInterface(ndi),
m_active_camera(NULL),
m_ueberExecutionPriority(0),
m_sceneConverter(NULL)
m_ueberExecutionPriority(0)
{
m_suspendedtime = 0.0;
m_suspendeddelta = 0.0;
@@ -429,6 +435,11 @@ void KX_Scene::RemoveNodeDestructObject(class SG_IObject* node,class CValue* gam
KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CValue* gameobj)
{
// for group duplication, limit the duplication of the hierarchy to the
// objects that are part of the group.
if (!IsObjectInGroup(gameobj))
return NULL;
KX_GameObject* orgobj = (KX_GameObject*)gameobj;
KX_GameObject* newobj = (KX_GameObject*)orgobj->GetReplica();
m_map_gameobject_to_replica.insert(orgobj, newobj);
@@ -506,6 +517,11 @@ KX_GameObject* KX_Scene::AddNodeReplicaObject(class SG_IObject* node, class CVal
// hierarchy that's because first ALL bricks must exist in the new
// replica of the hierarchy in order to make cross-links work properly
// !
// It is VERY important that the order of sensors and actuators in
// the replicated object is preserved: it is is used to reconnect the logic.
// This method is more robust then using the bricks name in case of complex
// group replication. The replication of logic bricks is done in
// SCA_IObject::ReParentLogic(), make sure it preserves the order of the bricks.
void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
{
// also relink the controller to sensors/actuators
@@ -528,37 +544,38 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
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);
SCA_IObject* oldsensorobj = oldsensor->GetParent();
SCA_IObject* newsensorobj = NULL;
if (newsensor)
// the original owner of the sensor has been replicated?
void **h_obj = m_map_gameobject_to_replica[oldsensorobj];
if (h_obj)
newsensorobj = (SCA_IObject*)(*h_obj);
if (!newsensorobj)
{
// relink this newsensor to the controller
m_logicmgr->RegisterToSensor(cont,newsensor);
// no, then the sensor points outside the hierachy, keep it the same
if (m_objectlist->SearchValue(oldsensorobj))
// only replicate links that points to active objects
m_logicmgr->RegisterToSensor(cont,oldsensor);
}
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;
}
// yes, then the new sensor has the same position
SCA_SensorList& sensorlist = oldsensorobj->GetSensors();
SCA_SensorList::iterator sit;
SCA_ISensor* newsensor = NULL;
int sensorpos;
if (newsensor)
for (sensorpos=0, sit=sensorlist.begin(); sit!=sensorlist.end(); sit++, sensorpos++)
{
// 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);
if ((*sit) == oldsensor)
{
newsensor = newsensorobj->GetSensors().at(sensorpos);
break;
}
}
assert(newsensor != NULL);
m_logicmgr->RegisterToSensor(cont,newsensor);
}
}
@@ -566,38 +583,40 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
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)
SCA_IObject* oldactuatorobj = oldactuator->GetParent();
SCA_IObject* newactuatorobj = NULL;
// the original owner of the sensor has been replicated?
void **h_obj = m_map_gameobject_to_replica[oldactuatorobj];
if (h_obj)
newactuatorobj = (SCA_IObject*)(*h_obj);
if (!newactuatorobj)
{
// relink this newsensor to the controller
m_logicmgr->RegisterToActuator(cont,newactuator);
newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
// no, then the sensor points outside the hierachy, keep it the same
if (m_objectlist->SearchValue(oldactuatorobj))
// only replicate links that points to active objects
m_logicmgr->RegisterToActuator(cont,oldactuator);
}
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;
}
// yes, then the new sensor has the same position
SCA_ActuatorList& actuatorlist = oldactuatorobj->GetActuators();
SCA_ActuatorList::iterator ait;
SCA_IActuator* newactuator = NULL;
int actuatorpos;
if (newactuator)
for (actuatorpos=0, ait=actuatorlist.begin(); ait!=actuatorlist.end(); ait++, actuatorpos++)
{
// 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);
if ((*ait) == oldactuator)
{
newactuator = newactuatorobj->GetActuators().at(actuatorpos);
break;
}
}
assert(newactuator != NULL);
m_logicmgr->RegisterToActuator(cont,newactuator);
newactuator->SetUeberExecutePriority(m_ueberExecutionPriority);
}
}
}
@@ -605,6 +624,154 @@ 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;
KX_GameObject* gameobj;
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++;
// for groups will do something special:
// we will force the creation of objects to those in the group only
// Again, this is match what Blender is doing (it doesn't care of parent relationship)
m_groupGameObjects.clear();
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;
gameobj = (KX_GameObject*)m_logicmgr->FindGameObjByBlendObj(blenderobj);
if (gameobj == NULL)
{
// this object has not been converted!!!
// Should not happen as dupli group are created automatically
continue;
}
if ((blenderobj->lay & group->layer)==0)
{
// object is not visible in the 3D view, will not be instantiated
continue;
}
m_groupGameObjects.insert(gameobj);
}
set<CValue*>::iterator oit;
for (oit=m_groupGameObjects.begin(); oit != m_groupGameObjects.end(); oit++)
{
gameobj = (KX_GameObject*)(*oit);
KX_GameObject *parent = gameobj->GetParent();
if (parent != NULL)
{
parent->Release(); // GetParent() increased the refcount
// 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;
}
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();
if (childreplicanode)
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
// In order to match 3D view, the position of groupobj is used as a
// transformation matrix instead of the new position. This means that
// the group reference point is 0,0,0
// get the rootnode's scale
MT_Vector3 newscale = groupobj->NodeGetWorldScaling();
// set the replica's relative scale with the rootnode's scale
replica->NodeSetRelativeScale(newscale);
MT_Matrix3x3 newori = groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldOrientation();
replica->NodeSetLocalOrientation(newori);
MT_Point3 newpos = groupobj->NodeGetWorldPosition() +
newscale*(groupobj->NodeGetWorldOrientation() * gameobj->NodeGetWorldPosition());
replica->NodeSetLocalPosition(newpos);
if (replica->GetPhysicsController())
{
// not required, already done in NodeSetLocalOrientation..
//replica->GetPhysicsController()->setPosition(newpos);
//replica->GetPhysicsController()->setOrientation(newori.getRotation());
// Scaling has been set relatively hereabove, this does not
// set the scaling of the controller. I don't know why it's just the
// relative scale and not the full scale that has to be put here...
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();
}
// the logic must be replicated first because we need
// the new logic bricks before relinking
vector<KX_GameObject*>::iterator git;
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
{
(*git)->ReParentLogic();
}
// relink any pointers as necessary, sort of a temporary solution
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
{
// this will also relink the actuator to objects within the hierarchy
(*git)->Relink(&m_map_gameobject_to_replica);
// add the object in the layer of the parent
(*git)->SetLayer(groupobj->GetLayer());
}
// 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,
@@ -614,6 +781,7 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
m_logicHierarchicalGameObjects.clear();
m_map_gameobject_to_replica.clear();
m_groupGameObjects.clear();
// todo: place a timebomb in the object, for temporarily objects :)
// lifespan of zero means 'this object lives forever'
@@ -647,24 +815,26 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
{
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);
// add the object in the layer of the parent
(*git)->SetLayer(parentobj->GetLayer());
if (childreplicanode)
replica->GetSGNode()->AddChild(childreplicanode);
}
// now replicate logic
vector<KX_GameObject*>::iterator git;
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
{
(*git)->ReParentLogic();
}
// relink any pointers as necessary, sort of a temporary solution
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
{
// this will also relink the actuators in the hierarchy
(*git)->Relink(&m_map_gameobject_to_replica);
// add the object in the layer of the parent
(*git)->SetLayer(parentobj->GetLayer());
}
// replicate crosslinks etc. between logic bricks
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
{
@@ -685,8 +855,9 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
if (replica->GetPhysicsController())
{
replica->GetPhysicsController()->setPosition(newpos);
replica->GetPhysicsController()->setOrientation(newori.getRotation());
// not needed, already done in NodeSetLocalPosition()
//replica->GetPhysicsController()->setPosition(newpos);
//replica->GetPhysicsController()->setOrientation(newori.getRotation());
replica->GetPhysicsController()->setScaling(newscale);
}
@@ -697,6 +868,20 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
replica->GetSGNode()->UpdateWorldData(0);
replica->GetSGNode()->SetBBox(originalobj->GetSGNode()->BBox());
replica->GetSGNode()->SetRadius(originalobj->GetSGNode()->Radius());
// check if there are objects with dupligroup in the hierarchy
vector<KX_GameObject*> duplilist;
for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
{
if ((*git)->IsDupliGroup())
{
// separate list as m_logicHierarchicalGameObjects is also used by DupliGroupRecurse()
duplilist.push_back(*git);
}
}
for (git = duplilist.begin();!(git==duplilist.end());++git)
{
DupliGroupRecurse(*git, 0);
}
// don't release replica here because we are returning it, not done with it...
return replica;
}
@@ -743,6 +928,12 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
int ret;
KX_GameObject* newobj = (KX_GameObject*) gameobj;
// keep the blender->game object association up to date
// note that all the replicas of an object will have the same
// blender object, that's why we need to check the game object
// as only the deletion of the original object must be recorded
m_logicmgr->UnregisterGameObj(newobj->GetBlenderObject(), gameobj);
//todo: look at this
//GetPhysicsEnvironment()->RemovePhysicsController(gameobj->getPhysicsController());
@@ -801,6 +992,7 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
//m_active_camera->Release();
m_active_camera = NULL;
}
// in case this is a camera
m_cameras.remove((KX_Camera*)newobj);
@@ -1057,14 +1249,10 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
if (visible)
{
int nummeshes = gameobj->GetMeshCount();
MT_Transform t( cam->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
// this adds the vertices to the display list
for (int m=0;m<nummeshes;m++)
{
// this adds the vertices to the display list
(gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode());
}
(gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode());
}
gameobj->MarkVisible(visible);
}
@@ -1121,12 +1309,11 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
if (vis)
{
int nummeshes = gameobj->GetMeshCount();
MT_Transform t(cam->GetWorldToCamera() * gameobj->GetSGNode()->GetWorldTransform());
for (int m=0;m<nummeshes;m++)
{
// this adds the vertices to the display list
(gameobj->GetMesh(m))->SchedulePolygons(t, rasty->GetDrawingMode());
(gameobj->GetMesh(m))->SchedulePolygons(rasty->GetDrawingMode());
}
// Visibility/ non-visibility are marked
// elsewhere now.
@@ -1239,7 +1426,7 @@ void KX_Scene::UpdateParents(double curtime)
RAS_MaterialBucket* KX_Scene::FindBucket(class RAS_IPolyMaterial* polymat, bool &bucketCreated)
{
return m_bucketmanager->RAS_BucketManagerFindBucket(polymat, bucketCreated);
return m_bucketmanager->FindBucket(polymat, bucketCreated);
}
@@ -1249,10 +1436,9 @@ void KX_Scene::RenderBuckets(const MT_Transform & cameratransform,
class RAS_IRenderTools* rendertools)
{
m_bucketmanager->Renderbuckets(cameratransform,rasty,rendertools);
KX_BlenderMaterial::EndFrame();
}
void KX_Scene::UpdateObjectActivity(void)
{
if (m_activity_culling) {

View File

@@ -216,6 +216,16 @@ protected:
*/
std::vector<KX_GameObject*> m_logicHierarchicalGameObjects;
/**
* This temporary variable will contain the list of
* object that can be added during group instantiation.
* objects outside this list will not be added (can
* happen with children that are outside the group).
* Used in AddReplicaObject. If the list is empty, it
* means don't care.
*/
std::set<CValue*> m_groupGameObjects;
/**
* Pointer to system variable passed in in constructor
* only used in constructor so we do not need to keep it
@@ -291,6 +301,12 @@ public:
* Update all transforms according to the scenegraph.
*/
void UpdateParents(double curtime);
void DupliGroupRecurse(CValue* gameobj, int level);
bool IsObjectInGroup(CValue* gameobj)
{
return (m_groupGameObjects.empty() ||
m_groupGameObjects.find(gameobj) != m_groupGameObjects.end());
}
SCA_IObject* AddReplicaObject(CValue* gameobj,
CValue* locationobj,
int lifespan=0);

View File

@@ -58,13 +58,16 @@ KX_SceneActuator::KX_SceneActuator(SCA_IObject *gameobj,
m_KetsjiEngine=ketsjiEngine;
m_camera = camera;
m_nextSceneName = nextSceneName;
if (m_camera)
m_camera->RegisterActuator(this);
} /* End of constructor */
KX_SceneActuator::~KX_SceneActuator()
{
// there's nothing to be done here, really....
if (m_camera)
m_camera->UnregisterActuator(this);
} /* end of destructor */
@@ -79,6 +82,34 @@ CValue* KX_SceneActuator::GetReplica()
return replica;
}
void KX_SceneActuator::ProcessReplica()
{
if (m_camera)
m_camera->RegisterActuator(this);
SCA_IActuator::ProcessReplica();
}
bool KX_SceneActuator::UnlinkObject(SCA_IObject* clientobj)
{
if (clientobj == (SCA_IObject*)m_camera)
{
// this object is being deleted, we cannot continue to track it.
m_camera = NULL;
return true;
}
return false;
}
void KX_SceneActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
{
void **h_obj = (*obj_map)[m_camera];
if (h_obj) {
if (m_camera)
m_camera->UnregisterActuator(this);
m_camera = (KX_Camera*)(*h_obj);
m_camera->RegisterActuator(this);
}
}
bool KX_SceneActuator::Update()
@@ -332,7 +363,11 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self,
PyObject *cam;
if (PyArg_ParseTuple(args, "O!", &KX_Camera::Type, &cam))
{
if (m_camera)
m_camera->UnregisterActuator(this);
m_camera = (KX_Camera*) cam;
if (m_camera)
m_camera->RegisterActuator(this);
Py_Return;
}
PyErr_Clear();
@@ -345,7 +380,13 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self,
}
KX_Camera *camOb = FindCamera(camName);
if (camOb) m_camera = camOb;
if (camOb)
{
if (m_camera)
m_camera->UnregisterActuator(this);
m_camera = camOb;
m_camera->RegisterActuator(this);
}
Py_Return;
}

View File

@@ -82,6 +82,9 @@ class KX_SceneActuator : public SCA_IActuator
virtual ~KX_SceneActuator();
virtual CValue* GetReplica();
virtual void ProcessReplica();
virtual bool UnlinkObject(SCA_IObject* clientobj);
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool Update();

View File

@@ -101,7 +101,7 @@ void KX_SumoPhysicsController::SetSumoTransform(bool nondynaonly)
}
void KX_SumoPhysicsController::SuspendDynamics()
void KX_SumoPhysicsController::SuspendDynamics(bool)
{
SumoPhysicsController::SuspendDynamics();
}
@@ -170,8 +170,9 @@ void KX_SumoPhysicsController::setMargin(float collisionMargin)
}
void KX_SumoPhysicsController::setOrientation(const MT_Quaternion& orn)
void KX_SumoPhysicsController::setOrientation(const MT_Matrix3x3& rot)
{
MT_Quaternion orn = rot.getRotation();
SumoPhysicsController::setOrientation(
orn[0],orn[1],orn[2],orn[3]);

View File

@@ -76,10 +76,10 @@ public:
void resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ);
void SuspendDynamics();
void SuspendDynamics(bool);
void RestoreDynamics();
virtual void getOrientation(MT_Quaternion& orn);
virtual void setOrientation(const MT_Quaternion& orn);
virtual void setOrientation(const MT_Matrix3x3& orn);
virtual void setPosition(const MT_Point3& pos);
virtual void setScaling(const MT_Vector3& scaling);

View File

@@ -100,16 +100,24 @@ bool KX_TouchEventManager::newBroadphaseResponse(void *client_data,
void KX_TouchEventManager::RegisterSensor(SCA_ISensor* sensor)
{
KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
m_sensors.push_back(touchsensor);
m_sensors.insert(touchsensor);
touchsensor->RegisterSumo(this);
}
void KX_TouchEventManager::RemoveSensor(SCA_ISensor* sensor)
{
KX_TouchSensor* touchsensor = static_cast<KX_TouchSensor*>(sensor);
m_sensors.erase(touchsensor);
touchsensor->UnregisterSumo(this);
}
void KX_TouchEventManager::EndFrame()
{
vector<SCA_ISensor*>::iterator it;
set<SCA_ISensor*>::iterator it;
for ( it = m_sensors.begin();
!(it==m_sensors.end());it++)
{
@@ -124,7 +132,7 @@ void KX_TouchEventManager::NextFrame()
{
if (m_sensors.size() > 0)
{
vector<SCA_ISensor*>::iterator it;
set<SCA_ISensor*>::iterator it;
for (it = m_sensors.begin();!(it==m_sensors.end());++it)
static_cast<KX_TouchSensor*>(*it)->SynchronizeTransform();
@@ -157,20 +165,3 @@ void KX_TouchEventManager::NextFrame()
(*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();
}
// remove the sensor forever :)
SCA_EventManager::RemoveSensor(sensor);
}

View File

@@ -71,8 +71,8 @@ public:
PHY_IPhysicsEnvironment* physEnv);
virtual void NextFrame();
virtual void EndFrame();
virtual void RemoveSensor(class SCA_ISensor* sensor);
virtual void RegisterSensor(SCA_ISensor* sensor);
virtual void RemoveSensor(SCA_ISensor* sensor);
SCA_LogicManager* GetLogicManager() { return m_logicmgr;}
PHY_IPhysicsEnvironment *GetPhysicsEnvironment() { return m_physEnv; }

View File

@@ -153,6 +153,14 @@ void KX_TouchSensor::RegisterSumo(KX_TouchEventManager *touchman)
}
}
void KX_TouchSensor::UnregisterSumo(KX_TouchEventManager* touchman)
{
if (m_physCtrl)
{
touchman->GetPhysicsEnvironment()->removeCollisionCallback(m_physCtrl);
}
}
bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_CollData* colldata)
{
// KX_TouchEventManager* toucheventmgr = (KX_TouchEventManager*)m_eventmgr;

View File

@@ -76,6 +76,7 @@ public:
virtual void ReParent(SCA_IObject* parent);
virtual void RegisterSumo(KX_TouchEventManager* touchman);
virtual void UnregisterSumo(KX_TouchEventManager* touchman);
// virtual DT_Bool HandleCollision(void* obj1,void* obj2,
// const DT_CollData * coll_data);

View File

@@ -146,19 +146,19 @@ void compatible_eulFast(float *eul, float *oldrot)
{
float dx, dy, dz;
/* verschillen van ong 360 graden corrigeren */
/* angular difference of 360 degrees */
dx= eul[0] - oldrot[0];
dy= eul[1] - oldrot[1];
dz= eul[2] - oldrot[2];
if( fabs(dx) > 5.1) {
if( fabs(dx) > MT_PI) {
if(dx > 0.0) eul[0] -= MT_2_PI; else eul[0]+= MT_2_PI;
}
if( fabs(dy) > 5.1) {
if( fabs(dy) > MT_PI) {
if(dy > 0.0) eul[1] -= MT_2_PI; else eul[1]+= MT_2_PI;
}
if( fabs(dz) > 5.1 ) {
if( fabs(dz) > MT_PI ) {
if(dz > 0.0) eul[2] -= MT_2_PI; else eul[2]+= MT_2_PI;
}
}
@@ -195,6 +195,8 @@ void KX_TrackToActuator::ProcessReplica()
// the replica is tracking the same object => register it
if (m_object)
m_object->RegisterActuator(this);
if (m_parentobj)
m_parentobj->AddRef();
SCA_IActuator::ProcessReplica();
}
@@ -210,6 +212,26 @@ bool KX_TrackToActuator::UnlinkObject(SCA_IObject* clientobj)
return false;
}
void KX_TrackToActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
{
void **h_obj = (*obj_map)[m_object];
if (h_obj) {
if (m_object)
m_object->UnregisterActuator(this);
m_object = (SCA_IObject*)(*h_obj);
m_object->RegisterActuator(this);
}
void **h_parobj = (*obj_map)[m_parentobj];
if (h_parobj) {
if (m_parentobj)
m_parentobj->Release();
m_parentobj= (KX_GameObject*)(*h_parobj);
m_parentobj->AddRef();
}
}
bool KX_TrackToActuator::Update(double curtime, bool frame)
{
bool result = false;

View File

@@ -68,6 +68,7 @@ class KX_TrackToActuator : public SCA_IActuator
virtual void ProcessReplica();
virtual bool UnlinkObject(SCA_IObject* clientobj);
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
virtual bool Update(double curtime, bool frame);
/* Python part */

View File

@@ -65,6 +65,7 @@ public:
{
}
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl) {}
virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl) {}
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;}
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;}

View File

@@ -337,12 +337,33 @@ void CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float
{
m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
}
m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal);
// not required
//m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal);
btTransform xform = m_body->getCenterOfMassTransform();
xform.setRotation(btQuaternion(quatImag0,quatImag1,quatImag2,quatReal));
m_body->setCenterOfMassTransform(xform);
m_bulletMotionState->setWorldTransform(xform);
// not required
//m_bulletMotionState->setWorldTransform(xform);
}
}
void CcdPhysicsController::setWorldOrientation(const btMatrix3x3& orn)
{
if (m_body)
{
m_body->activate(true);
if (m_body->isStaticObject())
{
m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
}
// not required
//m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal);
btTransform xform = m_body->getCenterOfMassTransform();
xform.setBasis(orn);
m_body->setCenterOfMassTransform(xform);
// not required
//m_bulletMotionState->setWorldTransform(xform);
}
}
@@ -356,12 +377,13 @@ void CcdPhysicsController::setPosition(float posX,float posY,float posZ)
{
m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
}
m_MotionState->setWorldPosition(posX,posY,posZ);
// not required, this function is only used to update the physic controller
//m_MotionState->setWorldPosition(posX,posY,posZ);
btTransform xform = m_body->getCenterOfMassTransform();
xform.setOrigin(btVector3(posX,posY,posZ));
m_body->setCenterOfMassTransform(xform);
m_bulletMotionState->setWorldTransform(xform);
// not required
//m_bulletMotionState->setWorldTransform(xform);
}

View File

@@ -106,6 +106,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
btRigidBody* m_body;
class PHY_IMotionState* m_MotionState;
btMotionState* m_bulletMotionState;
friend class CcdPhysicsEnvironment; // needed when updating the controller
void* m_newClientInfo;
@@ -115,6 +116,9 @@ class CcdPhysicsController : public PHY_IPhysicsController
void CreateRigidbody();
protected:
void setWorldOrientation(const btMatrix3x3& mat);
public:
int m_collisionDelay;
@@ -194,7 +198,6 @@ class CcdPhysicsController : public PHY_IPhysicsController
return m_cci.m_collisionFilterMask;
}
virtual void calcXform() {} ;
virtual void SetMargin(float margin) {};
virtual float GetMargin() const {return 0.f;};

View File

@@ -368,7 +368,7 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
body->setUserPointer(ctrl);
body->setGravity( m_gravity );
m_controllers.push_back(ctrl);
m_controllers.insert(ctrl);
//use explicit group/filter for finer control over collision in bullet => near/radar sensor
m_dynamicsWorld->addRigidBody(body, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
@@ -434,38 +434,46 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctrl)
{
//also remove constraint
m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody());
{
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_controllers.begin(), m_controllers.end(), ctrl);
if (!(i == m_controllers.end()))
{
std::swap(*i, m_controllers.back());
m_controllers.pop_back();
}
}
m_controllers.erase(ctrl);
//remove it from the triggers
{
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
if (!(i == m_triggerControllers.end()))
{
std::swap(*i, m_triggerControllers.back());
m_triggerControllers.pop_back();
}
}
m_triggerControllers.erase(ctrl);
}
void CcdPhysicsEnvironment::updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask)
{
// this function is used when the collisionning group of a controller is changed
// remove and add the collistioning object
btRigidBody* body = ctrl->GetRigidBody();
btVector3 inertia;
m_dynamicsWorld->removeCollisionObject(body);
body->setCollisionFlags(newCollisionFlags);
body->getCollisionShape()->calculateLocalInertia(newMass, inertia);
body->setMassProps(newMass, inertia);
m_dynamicsWorld->addCollisionObject(body, newCollisionGroup, newCollisionMask);
// to avoid nasty interaction, we must update the property of the controller as well
ctrl->m_cci.m_mass = newMass;
ctrl->m_cci.m_collisionFilterGroup = newCollisionGroup;
ctrl->m_cci.m_collisionFilterMask = newCollisionMask;
ctrl->m_cci.m_collisionFlags = newCollisionFlags;
}
void CcdPhysicsEnvironment::enableCcdPhysicsController(CcdPhysicsController* ctrl)
{
if (m_controllers.insert(ctrl).second)
{
btRigidBody* body = ctrl->GetRigidBody();
body->setUserPointer(ctrl);
m_dynamicsWorld->addCollisionObject(body,
ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
}
}
void CcdPhysicsEnvironment::beginFrame()
{
@@ -475,12 +483,12 @@ void CcdPhysicsEnvironment::beginFrame()
bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
{
std::set<CcdPhysicsController*>::iterator it;
int i;
int i,numCtrl = GetNumControllers();
for (i=0;i<numCtrl;i++)
for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
CcdPhysicsController* ctrl = GetPhysicsController(i);
ctrl->SynchronizeMotionStates(timeStep);
(*it)->SynchronizeMotionStates(timeStep);
}
float subStep = timeStep / float(m_numTimeSubSteps);
@@ -489,11 +497,9 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
m_dynamicsWorld->stepSimulation(subStep,0);//perform always a full simulation step
}
numCtrl = GetNumControllers();
for (i=0;i<numCtrl;i++)
for (it=m_controllers.begin(); it!=m_controllers.end(); it++)
{
CcdPhysicsController* ctrl = GetPhysicsController(i);
ctrl->SynchronizeMotionStates(timeStep);
(*it)->SynchronizeMotionStates(timeStep);
}
for (i=0;i<m_wrapperVehicles.size();i++)
@@ -820,20 +826,6 @@ CcdPhysicsEnvironment::~CcdPhysicsEnvironment()
}
int CcdPhysicsEnvironment::GetNumControllers()
{
return m_controllers.size();
}
CcdPhysicsController* CcdPhysicsEnvironment::GetPhysicsController( int index)
{
return m_controllers[index];
}
void CcdPhysicsEnvironment::setConstraintParam(int constraintId,int param,float value0,float value1)
{
btTypedConstraint* typedConstraint = getConstraintById(constraintId);
@@ -873,12 +865,14 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
{
CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl;
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_controllers.begin(), m_controllers.end(), ctrl);
if ((i == m_controllers.end()))
{
addCcdPhysicsController(ctrl1);
}
// addSensor() is a "light" function for bullet because it is used
// dynamically when the sensor is activated. Use enableCcdPhysicsController() instead
//if (m_controllers.insert(ctrl1).second)
//{
// addCcdPhysicsController(ctrl1);
//}
enableCcdPhysicsController(ctrl1);
//Collision filter/mask is now set at the time of the creation of the controller
//force collision detection with everything, including static objects (might hurt performance!)
//ctrl1->GetRigidBody()->getBroadphaseHandle()->m_collisionFilterMask = btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::SensorTrigger;
@@ -891,21 +885,15 @@ void CcdPhysicsEnvironment::addSensor(PHY_IPhysicsController* ctrl)
void CcdPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
{
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl);
if (!(i == m_triggerControllers.end()))
{
std::swap(*i, m_triggerControllers.back());
m_triggerControllers.pop_back();
}
m_triggerControllers.erase((CcdPhysicsController*)ctrl);
}
void CcdPhysicsEnvironment::removeSensor(PHY_IPhysicsController* ctrl)
{
removeCollisionCallback(ctrl);
//printf("removeSensor\n");
removeCcdPhysicsController((CcdPhysicsController*)ctrl);
}
void CcdPhysicsEnvironment::addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)
{
/* printf("addTouchCallback\n(response class = %i)\n",response_class);
@@ -943,10 +931,9 @@ void CcdPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ctr
CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl);
//printf("requestCollisionCallback\n");
m_triggerControllers.push_back(ccdCtrl);
m_triggerControllers.insert(ccdCtrl);
}
void CcdPhysicsEnvironment::CallbackTriggers()
{
@@ -979,11 +966,10 @@ void CcdPhysicsEnvironment::CallbackTriggers()
CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer());
CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(obj1->getUserPointer());
std::vector<CcdPhysicsController*>::iterator i =
std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl0);
std::set<CcdPhysicsController*>::const_iterator i = m_triggerControllers.find(ctrl0);
if (i == m_triggerControllers.end())
{
i = std::find(m_triggerControllers.begin(), m_triggerControllers.end(), ctrl1);
i = m_triggerControllers.find(ctrl1);
}
if (!(i == m_triggerControllers.end()))
@@ -1093,7 +1079,6 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radi
CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo);
return sphereController;
}

View File

@@ -18,6 +18,7 @@ subject to the following restrictions:
#include "PHY_IPhysicsEnvironment.h"
#include <vector>
#include <set>
class CcdPhysicsController;
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
@@ -183,6 +184,15 @@ protected:
void removeCcdPhysicsController(CcdPhysicsController* ctrl);
void updateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask);
void disableCcdPhysicsController(CcdPhysicsController* ctrl)
{
removeCcdPhysicsController(ctrl);
}
void enableCcdPhysicsController(CcdPhysicsController* ctrl);
btBroadphaseInterface* getBroadphase();
@@ -200,12 +210,6 @@ protected:
}
int GetNumControllers();
CcdPhysicsController* GetPhysicsController( int index);
const btPersistentManifold* GetManifold(int index) const;
@@ -220,9 +224,9 @@ protected:
std::vector<CcdPhysicsController*> m_controllers;
std::set<CcdPhysicsController*> m_controllers;
std::vector<CcdPhysicsController*> m_triggerControllers;
std::set<CcdPhysicsController*> m_triggerControllers;
PHY_ResponseCallback m_triggerCallbacks[PHY_NUM_RESPONSE];
void* m_triggerCallbacksUserPtrs[PHY_NUM_RESPONSE];

View File

@@ -80,6 +80,7 @@ public:
{
}
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl) {}
virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl) {}
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) {return 0;}
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;}

View File

@@ -98,12 +98,17 @@ void SM_Scene::addTouchCallback(int response_class, DT_ResponseCallback callback
void SM_Scene::addSensor(SM_Object& object)
{
object.calcXform();
m_objectList.push_back(&object);
DT_AddObject(m_scene, object.getObjectHandle());
DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[SENSOR_RESPONSE]);
DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass[SENSOR_RESPONSE]);
DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[SENSOR_RESPONSE]);
T_ObjectList::iterator i =
std::find(m_objectList.begin(), m_objectList.end(), &object);
if (i == m_objectList.end())
{
object.calcXform();
m_objectList.push_back(&object);
DT_AddObject(m_scene, object.getObjectHandle());
DT_SetResponseClass(m_respTable, object.getObjectHandle(), m_ResponseClass[SENSOR_RESPONSE]);
DT_SetResponseClass(m_secondaryRespTable, object.getObjectHandle(), m_secondaryResponseClass [SENSOR_RESPONSE]);
DT_SetResponseClass(m_fixRespTable, object.getObjectHandle(), m_fixResponseClass[SENSOR_RESPONSE]);
}
}
void SM_Scene::add(SM_Object& object) {

View File

@@ -228,6 +228,12 @@ void SumoPhysicsEnvironment::requestCollisionCallback(PHY_IPhysicsController* ct
m_sumoScene->requestCollisionCallback(*smObject);
}
}
void SumoPhysicsEnvironment::removeCollisionCallback(PHY_IPhysicsController* ctrl)
{
// intentionally empty
}
PHY_IPhysicsController* SumoPhysicsEnvironment::CreateSphereController(float radius,const PHY__Vector3& position)
{
DT_ShapeHandle shape = DT_NewSphere(0.0);

View File

@@ -84,6 +84,7 @@ public:
virtual void removeSensor(PHY_IPhysicsController* ctrl);
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user);
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl);
virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl);
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position);
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight);

View File

@@ -104,6 +104,7 @@ class PHY_IPhysicsEnvironment
virtual void removeSensor(PHY_IPhysicsController* ctrl)=0;
virtual void addTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)=0;
virtual void requestCollisionCallback(PHY_IPhysicsController* ctrl)=0;
virtual void removeCollisionCallback(PHY_IPhysicsController* ctrl)=0;
//These two methods are *solely* used to create controllers for sensor! Don't use for anything else
virtual PHY_IPhysicsController* CreateSphereController(float radius,const PHY__Vector3& position) =0;
virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0;

View File

@@ -0,0 +1,158 @@
# $Id$
# Documentation for BL_ShapeActionActuator
from SCA_IActuator import *
class BL_ShapeActionActuator(SCA_IActuator):
"""
ShapeAction Actuators apply an shape action to an mesh object.
"""
def setAction(action, reset = True):
"""
Sets the current action.
@param action: The name of the action to set as the current action.
@type action: string
@param reset: Optional parameter indicating whether to reset the
blend timer or not. A value of 1 indicates that the
timer should be reset. A value of 0 will leave it
unchanged. If reset is not specified, the timer will
be reset.
"""
def setStart(start):
"""
Specifies the starting frame of the animation.
@param start: the starting frame of the animation
@type start: float
"""
def setEnd(end):
"""
Specifies the ending frame of the animation.
@param end: the ending frame of the animation
@type end: float
"""
def setBlendin(blendin):
"""
Specifies the number of frames of animation to generate
when making transitions between actions.
@param blendin: the number of frames in transition.
@type blendin: float
"""
def setPriority(priority):
"""
Sets the priority of this actuator.
@param priority: Specifies the new priority. Actuators will lower
priority numbers will override actuators with higher
numbers.
@type priority: integer
"""
def setFrame(frame):
"""
Sets the current frame for the animation.
@param frame: Specifies the new current frame for the animation
@type frame: float
"""
def setProperty(prop):
"""
Sets the property to be used in FromProp playback mode.
@param prop: the name of the property to use.
@type prop: string.
"""
def setBlendtime(blendtime):
"""
Sets the internal frame timer.
Allows the script to directly modify the internal timer
used when generating transitions between actions.
@param blendtime: The new time. This parameter must be in the range from 0.0 to 1.0.
@type blendtime: float
"""
def setType(mode):
"""
Sets the operation mode of the actuator
@param mode: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND
@type mode: integer
"""
def setContinue(cont):
"""
Set the actions continue option True or False. see getContinue.
@param cont: The continue option.
@type cont: bool
"""
def getType():
"""
Returns the operation mode of the actuator
@rtype: integer
@return: KX_ACTIONACT_PLAY, KX_ACTIONACT_PROPERTY, KX_ACTIONACT_FLIPPER, KX_ACTIONACT_LOOPSTOP, KX_ACTIONACT_LOOPEND
"""
def getContinue():
"""
When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame.
@rtype: bool
"""
def getAction():
"""
getAction() returns the name of the action associated with this actuator.
@rtype: string
"""
def getStart():
"""
Returns the starting frame of the action.
@rtype: float
"""
def getEnd():
"""
Returns the last frame of the action.
@rtype: float
"""
def getBlendin():
"""
Returns the number of interpolation animation frames to be generated when this actuator is triggered.
@rtype: float
"""
def getPriority():
"""
Returns the priority for this actuator. Actuators with lower Priority numbers will
override actuators with higher numbers.
@rtype: integer
"""
def getFrame():
"""
Returns the current frame number.
@rtype: float
"""
def getProperty():
"""
Returns the name of the property to be used in FromProp mode.
@rtype: string
"""

View File

@@ -0,0 +1,24 @@
# $Id$
# Documentation for KX_ActuatorSensor
from SCA_IActuator import *
class KX_ActuatorSensor(SCA_ISensor):
"""
Actuator sensor detect change in actuator state of the parent object.
It generates a positive pulse if the corresponding actuator is activated
and a negative pulse if the actuator is deactivated.
"""
def getActuator():
"""
Return the Actuator with which the sensor operates.
@rtype: string
"""
def setActuator(name):
"""
Sets the Actuator with which to operate. If there is no Actuator
of this name, the function has no effect.
@param name: actuator name
@type name: string
"""

View File

@@ -4,7 +4,7 @@ from SCA_IActuator import *
class KX_ConstraintActuator(SCA_IActuator):
"""
A constraint actuator limits the position or orientation of an object.
A constraint actuator limits the position, rotation, distance or orientation of an object.
"""
def setDamp(time):
"""
@@ -24,7 +24,7 @@ class KX_ConstraintActuator(SCA_IActuator):
"""
Sets the lower bound of the constraint.
For rotational constraints, lower is specified in degrees.
For rotational and orientation constraints, lower is specified in degrees.
@type lower: float
"""
@@ -32,7 +32,7 @@ class KX_ConstraintActuator(SCA_IActuator):
"""
Gets the lower bound of the constraint.
For rotational constraints, the lower bound is returned in radians.
For rotational and orientation constraints, the lower bound is returned in radians.
@rtype: float
"""
@@ -40,7 +40,7 @@ class KX_ConstraintActuator(SCA_IActuator):
"""
Sets the upper bound of the constraint.
For rotational constraints, upper is specified in degrees.
For rotational and orientation constraints, upper is specified in degrees.
@type upper: float
"""
@@ -48,7 +48,7 @@ class KX_ConstraintActuator(SCA_IActuator):
"""
Gets the upper bound of the constraint.
For rotational constraints, the upper bound is returned in radians.
For rotational and orientation constraints, the upper bound is returned in radians.
@rtype: float
"""
@@ -60,6 +60,9 @@ class KX_ConstraintActuator(SCA_IActuator):
@param limit: Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ,
Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY or KX_CONSTRAINTACT_ROTZ
Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ,
KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ,
Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ
"""
def getLimit():
"""
@@ -68,5 +71,110 @@ class KX_ConstraintActuator(SCA_IActuator):
See module L{GameLogic} for valid constraints.
@return: Position constraints: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY, KX_CONSTRAINTACT_LOCZ,
Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY or KX_CONSTRAINTACT_ROTZ
Rotation constraints: KX_CONSTRAINTACT_ROTX, KX_CONSTRAINTACT_ROTY, KX_CONSTRAINTACT_ROTZ,
Distance contraints: KX_ACT_CONSTRAINT_DIRPX, KX_ACT_CONSTRAINT_DIRPY, KX_ACT_CONSTRAINT_DIRPZ,
KX_ACT_CONSTRAINT_DIRNX, KX_ACT_CONSTRAINT_DIRNY, KX_ACT_CONSTRAINT_DIRNZ,
Orientation constraints: KX_ACT_CONSTRAINT_ORIX, KX_ACT_CONSTRAINT_ORIY, KX_ACT_CONSTRAINT_ORIZ
"""
def setRotDamp(duration):
"""
Sets the time constant of the orientation constraint.
@param duration: If the duration is negative, it is set to 0.
@type duration: integer
"""
def getRotDamp():
"""
Returns the damping time for application of the constraint.
@rtype: integer
"""
def setDirection(vector):
"""
Sets the reference direction in world coordinate for the orientation constraint
@type vector: 3-tuple
"""
def getDirection():
"""
Returns the reference direction of the orientation constraint in world coordinate.
@rtype: 3-tuple
"""
def setOption(option):
"""
Sets several options of the distance constraint.
@type option: integer
@param option: Binary combination of the following values:
64 : Activate alignment to surface
128 : Detect material rather than property
256 : No deactivation if ray does not hit target
512 : Activate distance control
"""
def getOption():
"""
Returns the option parameter.
@rtype: integer
"""
def setTime(duration):
"""
Sets the activation time of the actuator.
@type duration: integer
@param duration: The actuator disables itself after this many frame.
If set to 0 or negative, the actuator is not limited in time.
"""
def getTime():
"""
Returns the time parameter.
@rtype: integer
"""
def setProperty(property):
"""
Sets the name of the property or material for the ray detection of the distance constraint.
@type property: string
@param property: If empty, the ray will detect any collisioning object.
"""
def getProperty():
"""
Returns the property parameter.
@rtype: string
"""
def setDistance(distance):
"""
Sets the target distance in distance constraint.
@type distance: float
"""
def getDistance():
"""
Returns the distance parameter.
@rtype: float
"""
def setRayLength(length):
"""
Sets the maximum ray length of the distance constraint.
@type length: float
"""
def getRayLength():
"""
Returns the length of the ray
@rtype: float
"""

View File

@@ -214,6 +214,18 @@ class KX_GameObject:
"""
Removes this objects parent.
"""
def getChildren():
"""
Return a list of immediate children of this object.
@rtype: list
@return: a list of all this objects children.
"""
def getChildrenRecursive():
"""
Return a list of children of this object, including all their childrens children.
@rtype: list
@return: a list of all this objects children recursivly.
"""
def getMesh(mesh):
"""
Gets the mesh object for this object.
@@ -241,6 +253,16 @@ class KX_GameObject:
@type other: L{KX_GameObject} or list [x, y, z]
@rtype: float
"""
def getVectTo(other):
"""
Returns the vector and the distance to another object or point.
The vector is normalized unless the distance is 0, in which a NULL vector is returned.
@param other: a point or another L{KX_GameObject} to get the vector and distance to.
@type other: L{KX_GameObject} or list [x, y, z]
@rtype: 3-tuple (float, 3-tuple (x,y,z), 3-tuple (x,y,z))
@return: (distance, globalVector(3), localVector(3))
"""
def rayCastTo(other,dist,prop):
"""
Look towards another point/object and find first object hit within dist that matches prop.

View File

@@ -6,7 +6,7 @@ class KX_IpoActuator(SCA_IActuator):
"""
IPO actuator activates an animation.
"""
def set(mode, startframe, endframe, force):
def set(mode, startframe, endframe, mode):
"""
Sets the properties of the actuator.
@@ -16,8 +16,8 @@ class KX_IpoActuator(SCA_IActuator):
@type startframe: integer
@param endframe: last frame to use
@type endframe: integer
@param force: interpret this ipo as a force
@type force: boolean (KX_TRUE, KX_FALSE)
@param mode: special mode
@type mode: integer (0=normal, 1=interpret location as force, 2=additive)
"""
def setProperty(property):
"""
@@ -60,6 +60,19 @@ class KX_IpoActuator(SCA_IActuator):
"""
Returns whether to interpret the ipo as a force rather than a displacement.
@rtype: boolean
"""
def setIpoAdd(add):
"""
Set whether to interpret the ipo as additive rather than absolute.
@type add: boolean
@param add: KX_TRUE or KX_FALSE
"""
def getIpoAdd():
"""
Returns whether to interpret the ipo as additive rather than absolute.
@rtype: boolean
"""
def setType(mode):

View File

@@ -6,6 +6,7 @@ class KX_ObjectActuator(SCA_IActuator):
"""
The object actuator ("Motion Actuator") applies force, torque, displacement, angular displacement,
velocity, or angular velocity to an object.
Servo control allows to regulate force to achieve a certain speed target.
"""
def getForce():
"""
@@ -107,15 +108,17 @@ class KX_ObjectActuator(SCA_IActuator):
def getLinearVelocity():
"""
Returns the linear velocity applied by the actuator.
For the servo control actuator, this is the target speed.
@rtype: list [vx, vy, vz, local]
@return: A four item list, containing the vector velocity, and whether
the velocity is applied in local coordinates (True) or world
coordinates (False)
coordinates (False)
"""
def setLinearVelocity(vx, vy, vz, local):
"""
Sets the linear velocity applied by the actuator.
For the servo control actuator, sets the target speed.
@type vx: float
@param vx: the x component of the velocity vector.
@@ -124,8 +127,8 @@ class KX_ObjectActuator(SCA_IActuator):
@type vz: float
@param vz: the z component of the velocity vector.
@type local: boolean
@param local: - False: the velocity vector is applied in world coordinates.
- True: the velocity vector is applied in local coordinates.
@param local: - False: the velocity vector is in world coordinates.
- True: the velocity vector is in local coordinates.
"""
def getAngularVelocity():
"""
@@ -150,5 +153,100 @@ class KX_ObjectActuator(SCA_IActuator):
@param local: - False: the velocity vector is applied in world coordinates.
- True: the velocity vector is applied in local coordinates.
"""
def getDamping():
"""
Returns the damping parameter of the servo controller.
@rtype: integer
@return: the time constant of the servo controller in frame unit.
"""
def setDamping(damp):
"""
Sets the damping parameter of the servo controller.
@type damp: integer
@param damp: the damping parameter in frame unit.
"""
def getForceLimitX():
"""
Returns the min/max force limit along the X axis used by the servo controller.
@rtype: list [min, max, enabled]
@return: A three item list, containing the min and max limits of the force as float
and whether the limits are active(true) or inactive(true)
"""
def setForceLimitX(min, max, enable):
"""
Sets the min/max force limit along the X axis and activates or deactivates the limits in the servo controller.
@type min: float
@param min: the minimum value of the force along the X axis.
@type max: float
@param max: the maximum value of the force along the X axis.
@type enable: boolean
@param enable: - True: the force will be limited to the min/max
- False: the force will not be limited
"""
def getForceLimitY():
"""
Returns the min/max force limit along the Y axis used by the servo controller.
@rtype: list [min, max, enabled]
@return: A three item list, containing the min and max limits of the force as float
and whether the limits are active(true) or inactive(true)
"""
def setForceLimitY(min, max, enable):
"""
Sets the min/max force limit along the Y axis and activates or deactivates the limits in the servo controller.
@type min: float
@param min: the minimum value of the force along the Y axis.
@type max: float
@param max: the maximum value of the force along the Y axis.
@type enable: boolean
@param enable: - True: the force will be limited to the min/max
- False: the force will not be limited
"""
def getForceLimitZ():
"""
Returns the min/max force limit along the Z axis used by the servo controller.
@rtype: list [min, max, enabled]
@return: A three item list, containing the min and max limits of the force as float
and whether the limits are active(true) or inactive(true)
"""
def setForceLimitZ(min, max, enable):
"""
Sets the min/max force limit along the Z axis and activates or deactivates the limits in the servo controller.
@type min: float
@param min: the minimum value of the force along the Z axis.
@type max: float
@param max: the maximum value of the force along the Z axis.
@type enable: boolean
@param enable: - True: the force will be limited to the min/max
- False: the force will not be limited
"""
def getPID():
"""
Returns the PID coefficient of the servo controller.
@rtype: list [P, I, D]
@return: A three item list, containing the PID coefficient as floats:
P : proportional coefficient
I : Integral coefficient
D : Derivate coefficient
"""
def setPID(P, I, D):
"""
Sets the PID coefficients of the servo controller.
@type P: flat
@param P: proportional coefficient
@type I: float
@param I: Integral coefficient
@type D: float
@param D: Derivate coefficient
"""

View File

@@ -0,0 +1,26 @@
# $Id$
# Documentation for KX_StateActuator
from SCA_IActuator import *
class KX_StateActuator(SCA_IActuator):
"""
State actuator changes the state mask of parent object.
"""
def setOperation(op):
"""
Set the type of bit operation to be applied on object state mask.
Use setMask() to specify the bits that will be modified.
@param op: bit operation (0=Copy, 1=Add, 2=Substract, 3=Invert)
@type op: integer
"""
def setMask(mask):
"""
Set the value that defines the bits that will be modified by the operation.
The bits that are 1 in the value will be updated in the object state,
the bits that are 0 are will be left unmodified expect for the Copy operation
which copies the value to the object state.
@param mask: bits that will be modified
@type mask: integer
"""

View File

@@ -59,4 +59,22 @@ class SCA_ISensor(SCA_ILogicBrick):
@type invert: boolean
@param invert: true if activates on negative events; false if activates on positive events.
"""
def getLevel():
"""
Returns whether this sensor is a level detector or a edge detector.
It makes a difference only in case of logic state transition (state actuator).
A level detector will immediately generate a pulse, negative or positive
depending on the sensor condition, as soon as the state is activated.
A edge detector will wait for a state change before generating a pulse.
@rtype: boolean
@return: true if sensor is level sensitive, false if it is edge sensitive
"""
def setLevel(level):
"""
Set whether to detect level or edge transition when entering a state.
@param level: Detect level instead of edge? (KX_TRUE, KX_FALSE)
@type level: boolean
"""

View File

@@ -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

View File

@@ -43,6 +43,7 @@
#include "STR_String.h"
#include "RAS_ICanvas.h"
#include "RAS_Rect.h"
#include "RAS_2DFilterManager.h"
#include <iostream>
@@ -158,7 +159,8 @@ void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propN
texflag[passindex] = 0;
if(glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1)
{
texflag[passindex] |= 0x1;
if(GLEW_ARB_depth_texture)
texflag[passindex] |= 0x1;
}
if(glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture") != -1)
{
@@ -261,7 +263,7 @@ void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
glGenTextures(1, (GLuint*)&texname[0]);
glBindTexture(GL_TEXTURE_2D, texname[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturewidth, textureheight, 0, GL_RGB,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturewidth, textureheight, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -293,10 +295,13 @@ void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
}
}
void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height)
void RAS_2DFilterManager::UpdateOffsetMatrix(RAS_ICanvas* canvas)
{
canvaswidth = texturewidth = width;
canvasheight = textureheight = height;
RAS_Rect canvas_rect = canvas->GetWindowArea();
canvaswidth = canvas->GetWidth();
canvasheight = canvas->GetHeight();
texturewidth = canvaswidth + canvas_rect.GetLeft();
textureheight = canvasheight + canvas_rect.GetBottom();
GLint i,j;
i = 0;
@@ -352,7 +357,7 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
if(canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight())
{
UpdateOffsetMatrix(canvas->GetWidth(), canvas->GetHeight());
UpdateOffsetMatrix(canvas);
SetupTextures(need_depth, need_luminance);
}
GLuint viewport[4]={0};
@@ -360,19 +365,21 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
if(need_depth){
glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texname[1]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0, 0, texturewidth,textureheight, 0);
}
if(need_luminance){
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0, 0 , texturewidth,textureheight, 0);
}
glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
glViewport(0, 0, texturewidth, textureheight);
glViewport(0,0, texturewidth, textureheight);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);

View File

@@ -42,7 +42,7 @@ private:
void SetupTextures(bool depth, bool luminance);
void FreeTextures();
void UpdateOffsetMatrix(int width, int height);
void UpdateOffsetMatrix(RAS_ICanvas* canvas);
float textureoffsets[18];
float view[4];

View File

@@ -94,7 +94,6 @@ void RAS_BucketManager::RenderAlphaBuckets(
const MT_Scalar cam_origin = cameratrans.getOrigin()[2];
for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit)
{
(*bit)->ClearScheduledPolygons();
for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit)
{
if ((*mit).m_bVisible)
@@ -133,28 +132,15 @@ void RAS_BucketManager::Renderbuckets(
rasty->ClearCachingInfo();
RAS_MaterialBucket::StartFrame();
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
{
(*bucket)->ClearScheduledPolygons();
}
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
{
RAS_IPolyMaterial *tmp = (*bucket)->GetPolyMaterial();
if(tmp->IsZSort() || tmp->GetFlag() &RAS_FORCEALPHA )
rasty->SetAlphaTest(true);
else
rasty->SetAlphaTest(false);
(*bucket)->Render(cameratrans,rasty,rendertools);
}
rasty->SetAlphaTest(false);
RenderAlphaBuckets(cameratrans, rasty, rendertools);
RAS_MaterialBucket::EndFrame();
}
RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material, bool &bucketCreated)
RAS_MaterialBucket* RAS_BucketManager::FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated)
{
bucketCreated = false;
BucketList::iterator it;
@@ -172,7 +158,7 @@ RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMate
RAS_MaterialBucket *bucket = new RAS_MaterialBucket(material);
bucketCreated = true;
if (bucket->IsTransparant())
if (bucket->IsAlpha())
m_AlphaBuckets.push_back(bucket);
else
m_MaterialBuckets.push_back(bucket);
@@ -195,3 +181,28 @@ void RAS_BucketManager::RAS_BucketManagerClearAll()
m_MaterialBuckets.clear();
m_AlphaBuckets.clear();
}
void RAS_BucketManager::ReleaseDisplayLists()
{
BucketList::iterator bit;
RAS_MaterialBucket::T_MeshSlotList::iterator mit;
for (bit = m_MaterialBuckets.begin(); bit != m_MaterialBuckets.end(); ++bit) {
for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
if(mit->m_DisplayList) {
mit->m_DisplayList->Release();
mit->m_DisplayList = NULL;
}
}
}
for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) {
for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
if(mit->m_DisplayList) {
mit->m_DisplayList->Release();
mit->m_DisplayList = NULL;
}
}
}
}

View File

@@ -58,8 +58,9 @@ public:
RAS_IRasterizer* rasty,
class RAS_IRenderTools* rendertools);
RAS_MaterialBucket* RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material, bool &bucketCreated);
RAS_MaterialBucket* FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated);
void ReleaseDisplayLists();
private:
void RAS_BucketManagerClearAll();

View File

@@ -42,7 +42,7 @@ struct RAS_CameraData
int m_viewporttop;
float m_focallength;
RAS_CameraData(float lens = 35., float clipstart = 0.1, float clipend = 100., bool perspective = true,
RAS_CameraData(float lens = 35.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true,
float focallength = 0.0f, bool viewport = false, int viewportleft = 0, int viewportbottom = 0,
int viewportright = 0, int viewporttop = 0) :
m_lens(lens),

View File

@@ -136,6 +136,14 @@ public:
GetDisplayArea(
) = 0;
/**
* Used to get canvas area within blender.
*/
virtual
RAS_Rect &
GetWindowArea(
) = 0;
/**
* Set the visible vieport
*/

View File

@@ -39,7 +39,8 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
int tilexrep,
int tileyrep,
int mode,
bool transparant,
int transp,
bool alpha,
bool zsort,
int lightlayer,
bool bIsTriangle,
@@ -51,7 +52,8 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
m_tilexrep(tilexrep),
m_tileyrep(tileyrep),
m_drawingmode (mode),
m_transparant(transparant),
m_transp(transp),
m_alpha(alpha),
m_zsort(zsort),
m_lightlayer(lightlayer),
m_bIsTriangle(bIsTriangle),
@@ -74,6 +76,7 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
this->m_multimode == lhs.m_multimode &&
this->m_flag == lhs.m_flag &&
this->m_drawingmode == lhs.m_drawingmode &&
this->m_transp == lhs.m_transp &&
this->m_lightlayer == lhs.m_lightlayer &&
this->m_texturename.hash() == lhs.m_texturename.hash() &&
this->m_materialname.hash() == lhs.m_materialname.hash()
@@ -85,7 +88,8 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
this->m_tile == lhs.m_tile &&
this->m_tilexrep == lhs.m_tilexrep &&
this->m_tileyrep == lhs.m_tileyrep &&
this->m_transparant == lhs.m_transparant &&
this->m_transp == lhs.m_transp &&
this->m_alpha == lhs.m_alpha &&
this->m_zsort == lhs.m_zsort &&
this->m_drawingmode == lhs.m_drawingmode &&
this->m_bIsTriangle == lhs.m_bIsTriangle &&
@@ -109,9 +113,9 @@ int RAS_IPolyMaterial::GetLightLayer() const
return m_lightlayer;
}
bool RAS_IPolyMaterial::IsTransparant() const
bool RAS_IPolyMaterial::IsAlpha() const
{
return m_transparant;
return m_alpha || m_zsort;
}
bool RAS_IPolyMaterial::IsZSort() const
@@ -139,6 +143,11 @@ const STR_String& RAS_IPolyMaterial::GetMaterialName() const
return m_materialname;
}
dword RAS_IPolyMaterial::GetMaterialNameHash() const
{
return m_materialname.hash();
}
const STR_String& RAS_IPolyMaterial::GetTextureName() const
{
return m_texturename;

View File

@@ -52,7 +52,7 @@ enum MaterialProps
RAS_AUTOGEN =128,
RAS_NORMAL =256,
RAS_DEFMULTI =512,
RAS_FORCEALPHA =1024
RAS_BLENDERGLSL =1024
};
/**
@@ -67,7 +67,8 @@ protected:
int m_tile;
int m_tilexrep,m_tileyrep;
int m_drawingmode; // tface->mode
bool m_transparant;
int m_transp;
bool m_alpha;
bool m_zsort;
int m_lightlayer;
bool m_bIsTriangle;
@@ -102,7 +103,8 @@ public:
int tilexrep,
int tileyrep,
int mode,
bool transparant,
int transp,
bool alpha,
bool zsort,
int lightlayer,
bool bIsTriangle,
@@ -132,12 +134,13 @@ public:
virtual bool Equals(const RAS_IPolyMaterial& lhs) const;
bool Less(const RAS_IPolyMaterial& rhs) const;
int GetLightLayer() const;
bool IsTransparant() const;
bool IsAlpha() const;
bool IsZSort() const;
bool UsesTriangles() const;
unsigned int hash() const;
int GetDrawingMode() const;
const STR_String& GetMaterialName() const;
dword GetMaterialNameHash() const;
const STR_String& GetTextureName() const;
const unsigned int GetFlag() const;

View File

@@ -372,10 +372,6 @@ public:
virtual void SetAmbientColor(float red, float green, float blue)=0;
virtual void SetAmbient(float factor)=0;
/**
* Sets alpha testing
*/
virtual void SetAlphaTest(bool enable)=0;
/**
* Sets a polygon offset. z depth will be: z1 = mult*z0 + add
@@ -398,8 +394,10 @@ public:
virtual void DisableMotionBlur()=0;
virtual float GetMotionBlurValue()=0;
virtual int GetMotionBlurState()=0;
virtual void SetMotionBlurState(int newstate)=0;
virtual int GetMotionBlurState()=0;
virtual void SetMotionBlurState(int newstate)=0;
virtual void SetBlendingMode(int blendmode)=0;
};
#endif //__RAS_IRASTERIZER

View File

@@ -76,26 +76,11 @@ KX_MeshSlot::~KX_MeshSlot()
RAS_MaterialBucket::RAS_MaterialBucket(RAS_IPolyMaterial* mat)
:m_bModified(true)
{
m_bScheduled=true;
m_material = mat;
}
void RAS_MaterialBucket::SchedulePolygons(int drawingmode)
{
m_bScheduled = true;
}
void RAS_MaterialBucket::ClearScheduledPolygons()
{
m_bScheduled = false;
}
RAS_IPolyMaterial* RAS_MaterialBucket::GetPolyMaterial() const
{
return m_material;
@@ -134,9 +119,14 @@ void RAS_MaterialBucket::MarkVisibleMeshSlot(KX_MeshSlot& ms,
(*it).m_RGBAcolor= rgbavec;
}
bool RAS_MaterialBucket::IsTransparant() const
bool RAS_MaterialBucket::IsAlpha() const
{
return (m_material->IsTransparant());
return (m_material->IsAlpha());
}
bool RAS_MaterialBucket::IsZSort() const
{
return (m_material->IsZSort());
}

View File

@@ -125,11 +125,9 @@ public:
class RAS_IRasterizer* rasty,
class RAS_IRenderTools* rendertools);
void SchedulePolygons(int drawingmode);
void ClearScheduledPolygons();
RAS_IPolyMaterial* GetPolyMaterial() const;
bool IsTransparant() const;
bool IsAlpha() const;
bool IsZSort() const;
static void StartFrame();
static void EndFrame();
@@ -162,7 +160,6 @@ public:
private:
T_MeshSlotList m_meshSlots;
bool m_bScheduled;
bool m_bModified;
RAS_IPolyMaterial* m_material;
double* m_pOGLMatrix;

View File

@@ -35,6 +35,8 @@
#include "MT_MinMax.h"
#include "MT_Point3.h"
#include <algorithm>
STR_String RAS_MeshObject::s_emptyname = "";
@@ -201,26 +203,33 @@ void RAS_MeshObject::DebugColor(unsigned int abgr)
m_debugcolor = abgr;
}
void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
{
const vecVertexArray & vertexvec = GetVertexCache(mat);
for (vector<KX_VertexArray*>::const_iterator it = vertexvec.begin(); it != vertexvec.end(); ++it)
{
KX_VertexArray::iterator vit;
for (vit=(*it)->begin(); vit != (*it)->end(); vit++)
{
vit->SetRGBA(rgba);
}
}
}
void RAS_MeshObject::SchedulePoly(const KX_VertexIndex& idx,
int numverts,
RAS_IPolyMaterial* mat)
{
//int indexpos = m_IndexArrayCount[idx.m_vtxarray];
//m_IndexArrayCount[idx.m_vtxarray] = indexpos + 3;
KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[0]);
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[1]);
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[2]);
if (!mat->UsesTriangles()) //if (!m_bUseTriangles)
{
//m_IndexArrayCount[idx.m_vtxarray] = indexpos+4;
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
}
}
if (!mat->UsesTriangles())
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
}
void RAS_MeshObject::ScheduleWireframePoly(const KX_VertexIndex& idx,
@@ -409,7 +418,6 @@ void RAS_MeshObject::Bucketize(double* oglmatrix,
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
RAS_MaterialBucket* bucket = *it;
bucket->SchedulePolygons(0);
// KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
bucket->SetMeshSlot(ms);
}
@@ -434,7 +442,6 @@ void RAS_MeshObject::MarkVisible(double* oglmatrix,
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
RAS_MaterialBucket* bucket = *it;
bucket->SchedulePolygons(0);
// KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
bucket->MarkVisibleMeshSlot(ms,visible,useObjectColor,rgbavec);
}
@@ -453,7 +460,6 @@ void RAS_MeshObject::RemoveFromBuckets(double* oglmatrix,
{
RAS_MaterialBucket* bucket = *it;
// RAS_IPolyMaterial* polymat = bucket->GetPolyMaterial();
bucket->SchedulePolygons(0);
//KX_ArrayOptimizer* oa = GetArrayOptimizer(polymat);
bucket->RemoveMeshSlot(ms);
}
@@ -572,31 +578,36 @@ void RAS_MeshObject::UpdateMaterialList()
struct RAS_MeshObject::polygonSlot
{
float m_z;
RAS_Polygon *m_poly;
polygonSlot(float z, RAS_Polygon* poly) :
m_z(z),
m_poly(poly)
{}
/**
* pnorm and pval form the plane equation that the distance from is used to
* sort against.
*/
polygonSlot(const MT_Vector3 &pnorm, const MT_Scalar &pval, RAS_MeshObject *mesh, RAS_Polygon* poly) :
m_poly(poly)
float m_z;
int m_index[4];
polygonSlot() {}
/* pnorm is the normal from the plane equation that the distance from is
* used to sort again. */
void get(const KX_VertexArray& vertexarray, const KX_IndexArray& indexarray,
int offset, int nvert, const MT_Vector3& pnorm)
{
const KX_VertexIndex &base = m_poly->GetIndexBase();
RAS_TexVert *vert = mesh->GetVertex(base.m_vtxarray, base.m_indexarray[0], poly->GetMaterial()->GetPolyMaterial());
m_z = MT_dot(pnorm, vert->getLocalXYZ()) + pval;
for(int i = 1; i < m_poly->VertexCount(); i++)
{
vert = mesh->GetVertex(base.m_vtxarray, base.m_indexarray[i], poly->GetMaterial()->GetPolyMaterial());
float z = MT_dot(pnorm, vert->getLocalXYZ()) + pval;
m_z += z;
MT_Vector3 center(0, 0, 0);
int i;
for(i=0; i<nvert; i++) {
m_index[i] = indexarray[offset+i];
center += vertexarray[m_index[i]].getLocalXYZ();
}
m_z /= m_poly->VertexCount();
/* note we don't divide center by the number of vertices, since all
* polygons have the same number of vertices, and that we leave out
* the 4-th component of the plane equation since it is constant. */
m_z = MT_dot(pnorm, center);
}
void set(KX_IndexArray& indexarray, int offset, int nvert)
{
int i;
for(i=0; i<nvert; i++)
indexarray[offset+i] = m_index[i];
}
};
@@ -616,100 +627,100 @@ struct RAS_MeshObject::fronttoback
}
};
void RAS_MeshObject::SortPolygons(const MT_Transform &transform)
{
// Limitations: sorting is quite simple, and handles many
// cases wrong, partially due to polygons being sorted per
// bucket.
//
// a) mixed triangles/quads are sorted wrong
// b) mixed materials are sorted wrong
// c) more than 65k faces are sorted wrong
// d) intersecting objects are sorted wrong
// e) intersecting polygons are sorted wrong
//
// a) can be solved by making all faces either triangles or quads
// if they need to be z-sorted. c) could be solved by allowing
// larger buckets, b) and d) cannot be solved easily if we want
// to avoid excessive state changes while drawing. e) would
// require splitting polygons.
if (!m_zsort)
return;
// Extract camera Z plane...
const MT_Vector3 pnorm(transform.getBasis()[2]);
const MT_Scalar pval = transform.getOrigin()[2];
unsigned int numpolys = m_Polygons.size();
std::multiset<polygonSlot, backtofront> alphapolyset;
std::multiset<polygonSlot, fronttoback> solidpolyset;
for (unsigned int p = 0; p < numpolys; p++)
{
RAS_Polygon* poly = m_Polygons[p];
if (poly->IsVisible())
{
if (poly->GetMaterial()->GetPolyMaterial()->IsTransparant())
{
alphapolyset.insert(polygonSlot(pnorm, pval, this, poly));
} else {
solidpolyset.insert(polygonSlot(pnorm, pval, this, poly));
}
}
}
// Clear current array data.
// unneeded: const MT_Scalar pval = transform.getOrigin()[2];
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
vector<KX_IndexArray*> *indexcache = &GetArrayOptimizer((*it)->GetPolyMaterial())->m_IndexArrayCache1;
for (vector<KX_IndexArray*>::iterator iit = indexcache->begin(); iit != indexcache->end(); ++iit)
(*iit)->clear();
}
if(!(*it)->IsZSort())
continue;
std::multiset<polygonSlot, fronttoback>::iterator sit = solidpolyset.begin();
for (; sit != solidpolyset.end(); ++sit)
SchedulePoly((*sit).m_poly->GetVertexIndexBase(), (*sit).m_poly->VertexCount(), (*sit).m_poly->GetMaterial()->GetPolyMaterial());
std::multiset<polygonSlot, backtofront>::iterator ait = alphapolyset.begin();
for (; ait != alphapolyset.end(); ++ait)
SchedulePoly((*ait).m_poly->GetVertexIndexBase(), (*ait).m_poly->VertexCount(), (*ait).m_poly->GetMaterial()->GetPolyMaterial());
RAS_IPolyMaterial *mat = (*it)->GetPolyMaterial();
KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
vecIndexArrays& indexarrays = ao->m_IndexArrayCache1;
vecVertexArray& vertexarrays = ao->m_VertexArrayCache1;
unsigned int i, j, nvert = (mat->UsesTriangles())? 3: 4;
for(i=0; i<indexarrays.size(); i++) {
KX_IndexArray& indexarray = *indexarrays[i];
KX_VertexArray& vertexarray = *vertexarrays[i];
unsigned int totpoly = indexarray.size()/nvert;
vector<polygonSlot> slots(totpoly);
/* get indices and z into temporary array */
for(j=0; j<totpoly; j++)
slots[j].get(vertexarray, indexarray, j*nvert, nvert, pnorm);
/* sort (stable_sort might be better, if flickering happens?) */
std::sort(slots.begin(), slots.end(), backtofront());
/* get indices from temporary array again */
for(j=0; j<totpoly; j++)
slots[j].set(indexarray, j*nvert, nvert);
}
}
}
void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawingmode)
void RAS_MeshObject::SchedulePolygons(int drawingmode)
{
// int nummaterials = m_materials.size();
int i;
if (m_bModified)
{
int i, numpolys = m_Polygons.size();
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
RAS_MaterialBucket* bucket = *it;
bucket->SchedulePolygons(drawingmode);
if (bucket->GetPolyMaterial()->IsZSort())
if ((*it)->IsZSort())
m_zsort = true;
}
int numpolys = m_Polygons.size();
if ((drawingmode > RAS_IRasterizer::KX_BOUNDINGBOX) &&
(drawingmode < RAS_IRasterizer::KX_SOLID))
if (drawingmode == RAS_IRasterizer::KX_WIREFRAME)
{
for (i=0;i<numpolys;i++)
{
RAS_Polygon* poly = m_Polygons[i];
if (poly->IsVisible())
ScheduleWireframePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetEdgeCode()
,poly->GetMaterial()->GetPolyMaterial());
ScheduleWireframePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetEdgeCode(),
poly->GetMaterial()->GetPolyMaterial());
}
m_zsort = false;
}
else
{
if (!m_zsort)
for (i=0;i<numpolys;i++)
{
for (i=0;i<numpolys;i++)
{
RAS_Polygon* poly = m_Polygons[i];
if (poly->IsVisible())
{
SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetMaterial()->GetPolyMaterial());
}
}
RAS_Polygon* poly = m_Polygons[i];
if (poly->IsVisible())
SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),
poly->GetMaterial()->GetPolyMaterial());
}
}
m_bModified = false;
m_MeshMod = true;
}
}

View File

@@ -137,6 +137,18 @@ class RAS_MeshObject
struct backtofront;
struct fronttoback;
void SchedulePoly(
const KX_VertexIndex& idx,
int numverts,
RAS_IPolyMaterial* mat
);
void ScheduleWireframePoly(
const KX_VertexIndex& idx,
int numverts,
int edgecode,
RAS_IPolyMaterial* mat
);
protected:
enum { BUCKET_MAX_INDICES = 65535 };//2048};//8192};
@@ -189,16 +201,14 @@ public:
);
void DebugColor(unsigned int abgr);
void SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba);
/**
* Sorts the polygons by their transformed z values.
*/
void SortPolygons(const MT_Transform &transform);
void SchedulePolygons(
const MT_Transform &transform,
int drawingmode
);
void SchedulePolygons(int drawingmode);
void ClearArrayData();
@@ -215,19 +225,7 @@ public:
int numverts,
RAS_IPolyMaterial* polymat
);
void SchedulePoly(
const KX_VertexIndex& idx,
int numverts,
RAS_IPolyMaterial* mat
);
void ScheduleWireframePoly(
const KX_VertexIndex& idx,
int numverts,
int edgecode,
RAS_IPolyMaterial* mat
);
// find (and share) or add vertices
// for some speedup, only the last 20 added vertices are searched for equality

View File

@@ -67,6 +67,7 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_motionblurvalue(-1.0),
m_texco_num(0),
m_attrib_num(0),
m_last_blendmode(0),
m_materialCachingInfo(0)
{
m_viewmatrix.Identity();
@@ -171,6 +172,8 @@ bool RAS_OpenGLRasterizer::Init()
m_ambg = 0.0f;
m_ambb = 0.0f;
SetBlendingMode(0);
glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -189,18 +192,6 @@ void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
}
void RAS_OpenGLRasterizer::SetAlphaTest(bool enable)
{
if (enable)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.6f);
}
else glDisable(GL_ALPHA_TEST);
}
void RAS_OpenGLRasterizer::SetAmbient(float factor)
{
float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
@@ -353,6 +344,8 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
glEnable (GL_CULL_FACE);
}
SetBlendingMode(0);
glShadeModel(GL_SMOOTH);
m_2DCanvas->BeginFrame();
@@ -1389,3 +1382,34 @@ void RAS_OpenGLRasterizer::DisableMotionBlur()
m_motionblur = 0;
m_motionblurvalue = -1.0;
}
void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
{
if(blendmode == m_last_blendmode)
return;
if(blendmode == 0) {
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if(blendmode == 1) {
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
}
else if(blendmode == 2) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
}
else if(blendmode == 4) {
glDisable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);
}
m_last_blendmode = blendmode;
}

View File

@@ -99,6 +99,7 @@ protected:
TexCoGen m_attrib[RAS_MAX_ATTRIB];
int m_texco_num;
int m_attrib_num;
int m_last_blendmode;
/** Stores the caching information for the last material activated. */
RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
@@ -142,8 +143,6 @@ public:
virtual void SetFocalLength(const float focallength);
virtual float GetFocalLength();
virtual void SetAlphaTest(bool enable);
virtual void SwapBuffers();
virtual void IndexPrimitives(
const vecVertexArray& vertexarrays,
@@ -282,8 +281,8 @@ public:
virtual void EnableMotionBlur(float motionblurvalue);
virtual void DisableMotionBlur();
virtual float GetMotionBlurValue(){return m_motionblurvalue;};
virtual int GetMotionBlurState(){return m_motionblur;};
virtual void SetMotionBlurState(int newstate)
virtual int GetMotionBlurState(){return m_motionblur;};
virtual void SetMotionBlurState(int newstate)
{
if(newstate<0)
m_motionblur = 0;
@@ -292,6 +291,8 @@ public:
else
m_motionblur = newstate;
};
virtual void SetBlendingMode(int blendmode);
};
#endif //__RAS_OPENGLRASTERIZER

View File

@@ -37,24 +37,6 @@
#include "RAS_Polygon.h"
/*
RAS_TexVert* RAS_Polygon::GetVertex(int index)
{
if (m_bucket)
return m_bucket->GetVertex(m_vertexindexbase.m_vtxarray, m_vertexindexbase.m_indexarray[index]);
else
return NULL;
}
*/
/*void RAS_Polygon::Bucketize(double* oglmatrix)
{
//Transform(trans);
if (m_bucket)
m_bucket->AddPolygon(this,oglmatrix);
}
*/
RAS_Polygon::RAS_Polygon(RAS_MaterialBucket* bucket,
bool visible,
int numverts,

View File

@@ -104,7 +104,7 @@ SetSGClientObject(
}
void
bool
SG_IObject::
ActivateReplicationCallback(
SG_IObject *replica
@@ -112,8 +112,10 @@ ActivateReplicationCallback(
if (m_callbacks.m_replicafunc)
{
// Call client provided replication func
m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo);
if (m_callbacks.m_replicafunc(replica,m_SGclientObject,m_SGclientInfo) == NULL)
return false;
}
return true;
};
void

View File

@@ -202,7 +202,7 @@ public:
protected :
void
bool
ActivateReplicationCallback(
SG_IObject *replica
);

View File

@@ -68,7 +68,7 @@ SG_Node* SG_Node::GetSGReplica()
SG_Node* replica = new SG_Node(*this);
if (replica == NULL) return NULL;
ProcessSGReplica(replica);
ProcessSGReplica(&replica);
return replica;
}
@@ -76,25 +76,42 @@ SG_Node* SG_Node::GetSGReplica()
void
SG_Node::
ProcessSGReplica(
SG_Node* replica
SG_Node** replica
){
// Apply the replication call back function.
ActivateReplicationCallback(replica);
if (!ActivateReplicationCallback(*replica))
{
delete (*replica);
*replica = NULL;
return;
}
// clear the replica node of it's parent.
static_cast<SG_Node*>(replica)->m_SGparent = NULL;
static_cast<SG_Node*>(*replica)->m_SGparent = NULL;
if (m_children.begin() != m_children.end())
{
// if this node has children, the replica has too, so clear and clone children
replica->ClearSGChildren();
(*replica)->ClearSGChildren();
NodeList::iterator childit;
for (childit = m_children.begin();childit!=m_children.end();++childit)
{
replica->AddChild((*childit)->GetSGReplica());
SG_Node* childnode = (*childit)->GetSGReplica();
if (childnode)
(*replica)->AddChild(childnode);
}
}
// Nodes without children and without client object are
// not worth to keep, they will just take up CPU
// This can happen in partial replication of hierarchy
// during group duplication.
if ((*replica)->m_children.empty() &&
(*replica)->GetSGClientObject() == NULL)
{
delete (*replica);
*replica = NULL;
}
}

View File

@@ -205,7 +205,7 @@ private:
void
ProcessSGReplica(
SG_Node* replica
SG_Node** replica
);
/**