Merging with trunk
15568 - 15963
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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(){
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
{
|
||||
if (m_pDeformer)
|
||||
m_pDeformer->Relink (map);
|
||||
KX_GameObject::Relink(map);
|
||||
};
|
||||
void ProcessReplica(KX_GameObject* replica);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -45,7 +45,6 @@ public:
|
||||
SCA_RandomEventManager(class SCA_LogicManager* logicmgr);
|
||||
|
||||
virtual void NextFrame();
|
||||
virtual void RegisterSensor(SCA_ISensor* sensor);
|
||||
};
|
||||
|
||||
#endif //__KX_RANDOMEVENTMGR
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -130,6 +130,12 @@ public:
|
||||
) {
|
||||
return m_displayarea;
|
||||
};
|
||||
|
||||
RAS_Rect &
|
||||
GetWindowArea(
|
||||
) {
|
||||
return m_displayarea;
|
||||
}
|
||||
|
||||
void
|
||||
BeginFrame(
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include <gl/gl.h>
|
||||
//#include <gl/gl.h>
|
||||
|
||||
#include "GPC_Canvas.h"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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()")
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ---------------------------------------------------- */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 :
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ---------------------------------------------------- */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,8 @@ public:
|
||||
int tilexrep,
|
||||
int tileyrep,
|
||||
int mode,
|
||||
bool transparant,
|
||||
int transp,
|
||||
bool alpha,
|
||||
bool zsort,
|
||||
int lightlayer,
|
||||
bool bIsTriangle,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -45,7 +45,6 @@ public:
|
||||
m_logicmgr(logicmgr)
|
||||
{}
|
||||
virtual void NextFrame();
|
||||
virtual void RegisterSensor(SCA_ISensor* sensor);
|
||||
};
|
||||
|
||||
#endif //__KX_RAYEVENTMGR
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -95,6 +95,9 @@ public:
|
||||
virtual bool
|
||||
UnlinkObject(SCA_IObject* clientobj);
|
||||
|
||||
virtual void
|
||||
Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
|
||||
|
||||
virtual bool
|
||||
Update();
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
158
source/gameengine/PyDoc/BL_ShapeActionActuator.py
Normal file
158
source/gameengine/PyDoc/BL_ShapeActionActuator.py
Normal 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
|
||||
"""
|
||||
|
||||
|
||||
24
source/gameengine/PyDoc/KX_ActuatorSensor.py
Normal file
24
source/gameengine/PyDoc/KX_ActuatorSensor.py
Normal 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
|
||||
"""
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
|
||||
|
||||
26
source/gameengine/PyDoc/KX_StateActuator.py
Normal file
26
source/gameengine/PyDoc/KX_StateActuator.py
Normal 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
|
||||
"""
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -136,6 +136,14 @@ public:
|
||||
GetDisplayArea(
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Used to get canvas area within blender.
|
||||
*/
|
||||
virtual
|
||||
RAS_Rect &
|
||||
GetWindowArea(
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Set the visible vieport
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -202,7 +202,7 @@ public:
|
||||
|
||||
protected :
|
||||
|
||||
void
|
||||
bool
|
||||
ActivateReplicationCallback(
|
||||
SG_IObject *replica
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ private:
|
||||
|
||||
void
|
||||
ProcessSGReplica(
|
||||
SG_Node* replica
|
||||
SG_Node** replica
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user