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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2008-07-08 22:32:42 +0400
committerCampbell Barton <ideasman42@gmail.com>2008-07-08 22:32:42 +0400
commitf43c66f384d6dca227a7081bbe7e4f763debe7fd (patch)
treeac15e2727efd7ebd68419c8378805f115a81b7c6
parent178be13f65aa7a21e877501805bfab047c9d004c (diff)
parentbbf1ce2762651f0d3f3a9c302c3575c68ca21ca7 (diff)
svn merge -r15478:HEAD https://svn.blender.org/svnroot/bf-blender/trunk/blender/
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp9
-rw-r--r--projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj6
-rw-r--r--source/blender/blenkernel/BKE_bmeshCustomData.h4
-rw-r--r--source/blender/blenkernel/BKE_customdata.h5
-rw-r--r--source/blender/blenkernel/intern/BME_Customdata.c9
-rw-r--r--source/blender/blenkernel/intern/BME_conversions.c137
-rw-r--r--source/blender/blenkernel/intern/BME_eulers.c14
-rw-r--r--source/blender/blenkernel/intern/BME_structure.c1
-rw-r--r--source/blender/blenkernel/intern/BME_tools.c82
-rw-r--r--source/blender/blenkernel/intern/customdata.c117
-rw-r--r--source/blender/blenkernel/intern/library.c60
-rw-r--r--source/blender/blenlib/BLI_mempool.h4
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c2
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c13
-rw-r--r--source/blender/include/BDR_drawobject.h1
-rw-r--r--source/blender/include/BIF_editarmature.h2
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h5
-rw-r--r--source/blender/src/buttons_logic.c61
-rw-r--r--source/blender/src/drawarmature.c17
-rw-r--r--source/blender/src/drawobject.c8
-rw-r--r--source/blender/src/drawview.c4
-rw-r--r--source/blender/src/editarmature.c51
-rw-r--r--source/blender/src/editmesh_add.c18
-rw-r--r--source/blender/src/editsima.c2
-rw-r--r--source/blender/src/header_view3d.c15
-rw-r--r--source/blender/src/space.c16
-rw-r--r--source/blender/src/view.c2
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp3
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp7
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h30
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.cpp2
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h1
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h15
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp39
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h14
-rw-r--r--source/gameengine/Ketsji/KX_IPO_SGController.cpp87
-rw-r--r--source/gameengine/Ketsji/KX_IPO_SGController.h7
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp171
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.h12
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp2
-rw-r--r--source/gameengine/SceneGraph/SG_Controller.h4
44 files changed, 776 insertions, 299 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 82a76b3c706..293f8fc1661 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -302,6 +302,15 @@ GHOST_TSuccess GHOST_SystemWin32::init()
{
GHOST_TSuccess success = GHOST_System::init();
+ /* Disable scaling on high DPI displays on Vista */
+ HMODULE user32 = ::LoadLibraryA("user32.dll");
+ typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
+ LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
+ (LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
+ if (SetProcessDPIAware)
+ SetProcessDPIAware();
+ FreeLibrary(user32);
+
// Determine whether this system has a high frequency performance counter. */
m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
if (m_hasPerformanceCounter) {
diff --git a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj
index 34c195cf23d..0dfbcaa5577 100644
--- a/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj
+++ b/projectfiles_vc7/blender/blenlib/BLI_blenlib.vcproj
@@ -359,6 +359,9 @@
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_memarena.c">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\intern\BLI_mempool.c">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\intern\boxpack2d.c">
</File>
<File
@@ -474,6 +477,9 @@
RelativePath="..\..\..\source\blender\blenlib\BLI_memarena.h">
</File>
<File
+ RelativePath="..\..\..\source\blender\blenlib\BLI_mempool.h">
+ </File>
+ <File
RelativePath="..\..\..\source\blender\blenlib\intern\BLI_scanfill.h">
</File>
<File
diff --git a/source/blender/blenkernel/BKE_bmeshCustomData.h b/source/blender/blenkernel/BKE_bmeshCustomData.h
index 423f75e532d..4f5f2641f54 100644
--- a/source/blender/blenkernel/BKE_bmeshCustomData.h
+++ b/source/blender/blenkernel/BKE_bmeshCustomData.h
@@ -38,7 +38,7 @@
#ifndef BKE_BMESHCUSTOMDATA_H
#define BKE_BMESHCUSTOMDATA_H
-struct BME_mempool;
+struct BLI_mempool;
/*Custom Data Types and defines
Eventual plan is to move almost everything to custom data and let caller
@@ -62,7 +62,7 @@ typedef struct BME_CustomDataLayer {
typedef struct BME_CustomData {
struct BME_CustomDataLayer *layers; /*Custom Data Layers*/
- struct BME_mempool *pool; /*pool for alloc of blocks*/
+ struct BLI_mempool *pool; /*pool for alloc of blocks*/
int totlayer, totsize; /*total layers and total size in bytes of each block*/
} BME_CustomData;
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 81c2e4a4b94..12f68c771e0 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -41,6 +41,7 @@ extern const CustomDataMask CD_MASK_MESH;
extern const CustomDataMask CD_MASK_EDITMESH;
extern const CustomDataMask CD_MASK_DERIVEDMESH;
extern const CustomDataMask CD_MASK_BMESH;
+extern const CustomDataMask CD_MASK_FACECORNERS;
/* for ORIGINDEX layer type, indicates no original index for this element */
#define ORIGINDEX_NONE -1
@@ -264,4 +265,8 @@ void CustomData_set_layer_unique_name(struct CustomData *data, int index);
/* for file reading compatibility, returns false if the layer was freed,
only after this test passes, layer->data should be assigned */
int CustomData_verify_versions(struct CustomData *data, int index);
+
+void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata);
+void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata);
+void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize);
#endif
diff --git a/source/blender/blenkernel/intern/BME_Customdata.c b/source/blender/blenkernel/intern/BME_Customdata.c
index 8b48efbdbd2..1fc8a4071dc 100644
--- a/source/blender/blenkernel/intern/BME_Customdata.c
+++ b/source/blender/blenkernel/intern/BME_Customdata.c
@@ -40,6 +40,7 @@
#include "bmesh_private.h"
#include <string.h>
#include "MEM_guardedalloc.h"
+#include "BLI_mempool.h"
/********************* Layer type information **********************/
typedef struct BME_LayerTypeInfo {
@@ -83,7 +84,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc
if(data->totlayer){
/*alloc memory*/
data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
- data->pool = BME_mempool_create(data->totsize, initalloc, initalloc);
+ data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc);
/*initialize layer data*/
for(i=0; i < BME_CD_NUMTYPES; i++){
if(init->layout[i]){
@@ -102,7 +103,7 @@ void BME_CD_Create(BME_CustomData *data, BME_CustomDataInit *init, int initalloc
void BME_CD_Free(BME_CustomData *data)
{
- if(data->pool) BME_mempool_destroy(data->pool);
+ if(data->pool) BLI_mempool_destroy(data->pool);
}
/*Block level ops*/
@@ -119,7 +120,7 @@ void BME_CD_free_block(BME_CustomData *data, void **block)
typeInfo->free((char*)*block + offset, 1, typeInfo->size);
}
}
- BME_mempool_free(data->pool, *block);
+ BLI_mempool_free(data->pool, *block);
*block = NULL;
}
@@ -130,7 +131,7 @@ static void BME_CD_alloc_block(BME_CustomData *data, void **block)
if (*block) BME_CD_free_block(data, block); //if we copy layers that have their own free functions like deformverts
if (data->totsize > 0)
- *block = BME_mempool_alloc(data->pool);
+ *block = BLI_mempool_alloc(data->pool);
else
*block = NULL;
}
diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c
index 7952546de7c..f375ca62726 100644
--- a/source/blender/blenkernel/intern/BME_conversions.c
+++ b/source/blender/blenkernel/intern/BME_conversions.c
@@ -55,14 +55,104 @@
#include "bmesh_private.h"
#include "BSE_edit.h"
-/*Converts an EditMesh to a BME_Mesh.*/
-static void bmesh_init_cdPool(CustomData *data, int allocsize){
- if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize);
+
+static void BME_corners_to_loops(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){
+ int i, j;
+ BME_Loop *l;
+ MTFace *texface;
+ MTexPoly *texpoly;
+ MCol *mcol;
+ MLoopCol *mloopcol;
+ MLoopUV *mloopuv;
+
+ for(i=0; i < numTex; i++){
+ texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+
+ texpoly->tpage = texface->tpage;
+ texpoly->flag = texface->flag;
+ texpoly->transp = texface->transp;
+ texpoly->mode = texface->mode;
+ texpoly->tile = texface->tile;
+ texpoly->unwrap = texface->unwrap;
+
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+ mloopuv->uv[0] = texface->uv[j][0];
+ mloopuv->uv[1] = texface->uv[j][1];
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+
+ }
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+ mloopcol->r = mcol[j].r;
+ mloopcol->g = mcol[j].g;
+ mloopcol->b = mcol[j].b;
+ mloopcol->a = mcol[j].a;
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
}
+static void BME_loops_to_corners(BME_Mesh *bm, CustomData *facedata, void *face_block, BME_Poly *f,int numCol, int numTex){
+ int i, j;
+ BME_Loop *l;
+ MTFace *texface;
+ MTexPoly *texpoly;
+ MCol *mcol;
+ MLoopCol *mloopcol;
+ MLoopUV *mloopuv;
+
+ for(i=0; i < numTex; i++){
+ texface = CustomData_em_get_n(facedata, face_block, CD_MTFACE, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+
+ texface->tpage = texpoly->tpage;
+ texface->flag = texpoly->flag;
+ texface->transp = texpoly->transp;
+ texface->mode = texpoly->mode;
+ texface->tile = texpoly->tile;
+ texface->unwrap = texpoly->unwrap;
+
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+ texface->uv[j][0] = mloopuv->uv[0];
+ texface->uv[j][1] = mloopuv->uv[1];
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+
+ }
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_em_get_n(facedata, face_block, CD_MCOL, i);
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+ mcol[j].r = mloopcol->r;
+ mcol[j].g = mloopcol->g;
+ mcol[j].b = mloopcol->b;
+ mcol[j].a = mloopcol->a;
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
+}
+/*move the EditMesh conversion functions to editmesh_tools.c*/
BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
BME_Mesh *bm;
- int allocsize[4] = {512,512,2048,512};
+ int allocsize[4] = {512,512,2048,512}, numTex, numCol;
BME_Vert *v1, *v2;
BME_Edge *e, *edar[4];
BME_Poly *f;
@@ -74,8 +164,21 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
int len;
bm = BME_make_mesh(allocsize);
+ /*copy custom data layout*/
CustomData_copy(&em->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
- bmesh_init_cdPool(&bm->vdata, allocsize[0]);
+ CustomData_copy(&em->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+
+ /*copy face corner data*/
+ CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
+ /*initialize memory pools*/
+ CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
+ CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
+ CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
+ CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
+ /*needed later*/
+ numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+ numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
BME_model_begin(bm);
/*add verts*/
@@ -86,7 +189,6 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
v1->flag = eve->f;
v1->h = eve->h;
v1->bweight = eve->bweight;
-
/*Copy Custom Data*/
CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v1->data);
eve->tmp.v = (EditVert*)v1;
@@ -106,15 +208,10 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
if(eed->seam) e->flag |= ME_SEAM;
if(eed->h & EM_FGON) e->flag |= ME_FGON;
if(eed->h & 1) e->flag |= ME_HIDE;
-
- /* link the edges for face construction;
- * kind of a dangerous thing - remember to cast back to BME_Edge before using! */
- /*Copy CustomData*/
-
eed->tmp.e = (EditEdge*)e;
+ CustomData_bmesh_copy_data(&em->edata, &bm->edata, eed->data, &e->data);
eed = eed->next;
}
-
/*add faces.*/
efa= em->faces.first;
while(efa) {
@@ -143,12 +240,13 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
if(efa->f & 1) f->flag |= ME_FACE_SEL;
else f->flag &= ~ME_FACE_SEL;
}
+ CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data);
+ BME_corners_to_loops(bm, &em->fdata, efa->data, f,numCol,numTex);
efa = efa->next;
}
BME_model_end(bm);
return bm;
}
-
/* adds the geometry in the bmesh to G.editMesh (does not free G.editMesh)
* if td != NULL, the transdata will be mapped to the EditVert's co */
EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
@@ -163,7 +261,7 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
EditEdge *eed;
EditFace *efa;
- int totvert, len, i;
+ int totvert, len, i, numTex, numCol;
em = G.editMesh;
@@ -171,6 +269,13 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
CustomData_copy(&bm->vdata, &em->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&bm->edata, &em->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&bm->pdata, &em->fdata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_from_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
+ numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+ numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
+
+
/* convert to EditMesh */
/* make editverts */
totvert = BLI_countlist(&(bm->verts));
@@ -202,6 +307,8 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
if(e->flag & ME_HIDE) eed->h |= 1;
if(G.scene->selectmode==SCE_SELECT_EDGE)
EM_select_edge(eed, eed->f & SELECT);
+
+ CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
}
}
@@ -228,6 +335,8 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
if(f->flag & ME_HIDE) efa->h= 1;
if((G.f & G_FACESELECT) && (efa->f & SELECT))
EM_select_face(efa, 1); /* flush down */
+ CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data);
+ BME_loops_to_corners(bm, &em->fdata, efa->data, f,numCol,numTex);
}
}
diff --git a/source/blender/blenkernel/intern/BME_eulers.c b/source/blender/blenkernel/intern/BME_eulers.c
index 3403f5829fe..801e0b8bdec 100644
--- a/source/blender/blenkernel/intern/BME_eulers.c
+++ b/source/blender/blenkernel/intern/BME_eulers.c
@@ -39,6 +39,7 @@
#include "DNA_mesh_types.h"
#include "BKE_utildefines.h"
+#include "BKE_customdata.h"
#include "BKE_bmesh.h"
#include "BLI_blenlib.h"
@@ -618,8 +619,8 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
BME_disk_append_edge(e, v2);
f2 = BME_addpolylist(bm,f);
- f1loop = BME_create_loop(bm,v2,e,f,NULL);
- f2loop = BME_create_loop(bm,v1,e,f2,NULL);
+ f1loop = BME_create_loop(bm,v2,e,f,v2loop);
+ f2loop = BME_create_loop(bm,v1,e,f2,v1loop);
f1loop->prev = v2loop->prev;
f2loop->prev = v1loop->prev;
@@ -663,16 +664,16 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
* Takes a an edge and pointer to one of its vertices and collapses
* the edge on that vertex.
*
- * Before: OE KE
+ * Before: OE KE
* ------- -------
* | || |
- * OV KV TV
+ * OV KV TV
*
*
* After: OE
* ---------------
* | |
- * OV TV
+ * OV TV
*
*
* Restrictions:
@@ -723,6 +724,8 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv)
/*remove ke from tv's disk cycle*/
BME_disk_remove_edge(ke, tv);
+
+
/*deal with radial cycle of ke*/
if(ke->loop){
/*first step, fix the neighboring loops of all loops in ke's radial cycle*/
@@ -763,6 +766,7 @@ int BME_JEKV(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv)
}
+
/*Validate disk cycles*/
diskbase = BME_disk_getpointer(ov->edge,ov);
edok = BME_cycle_validate(valance1, diskbase);
diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c
index 92ef9e3e03c..ca27f5efd10 100644
--- a/source/blender/blenkernel/intern/BME_structure.c
+++ b/source/blender/blenkernel/intern/BME_structure.c
@@ -41,7 +41,6 @@
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_ghash.h"
-
/**
* MISC utility functions.
*
diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c
index 916e6bee59f..90259031e5c 100644
--- a/source/blender/blenkernel/intern/BME_tools.c
+++ b/source/blender/blenkernel/intern/BME_tools.c
@@ -215,10 +215,42 @@ static void BME_data_interp_from_verts(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2,
src[1]= v2->data;
w[0] = 1.0f-fac;
w[1] = fac;
- CustomData_em_interp(&bm->vdata, src, w, NULL, 2, v->data);
+ CustomData_bmesh_interp(&bm->vdata, src, w, NULL, 2, v->data);
}
}
+
+static void BME_data_facevert_edgesplit(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, BME_Edge *e1, float fac){
+ void *src[2];
+ float w[2];
+ BME_Loop *l=NULL, *v1loop = NULL, *vloop = NULL, *v2loop = NULL;
+
+ w[0] = 1.0f - fac;
+ w[1] = fac;
+
+ if(!e1->loop) return;
+ l = e1->loop;
+ do{
+ if(l->v == v1){
+ v1loop = l;
+ vloop = v1loop->next;
+ v2loop = vloop->next;
+ }else if(l->v == v){
+ v1loop = l->next;
+ vloop = l;
+ v2loop = l->prev;
+
+ }
+
+ src[0] = v1loop->data;
+ src[1] = v2loop->data;
+
+ CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->data);
+ l = l->radial.next->data;
+ }while(l!=e1->loop);
+}
+
+
/* a wrapper for BME_SEMV that transfers element flags */ /*add custom data interpolation in here!*/
static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
BME_Vert *nv, *v2;
@@ -238,9 +270,37 @@ static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge
(*ne)->crease = e->crease;
(*ne)->bweight = e->bweight;
}
+ /*v->nv->v2*/
+ BME_data_facevert_edgesplit(bm,v2, v, nv, e, 0.75);
return nv;
}
+static void BME_collapse_vert(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv, float fac){
+ void *src[2];
+ float w[2];
+ BME_Loop *l=NULL, *kvloop=NULL, *tvloop=NULL;
+ BME_Vert *tv = BME_edge_getothervert(ke,kv);
+
+ w[0] = 1.0f - fac;
+ w[1] = fac;
+
+ if(ke->loop){
+ l = ke->loop;
+ do{
+ if(l->v == tv && l->next->v == kv){
+ tvloop = l;
+ kvloop = l->next;
+
+ src[0] = kvloop->data;
+ src[1] = tvloop->data;
+ CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, kvloop->data);
+ }
+ l=l->radial.next->data;
+ }while(l!=ke->loop);
+ }
+ BME_JEKV(bm,ke,kv);
+}
+
static int BME_bevel_is_split_vert(BME_Loop *l) {
@@ -367,6 +427,8 @@ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, B
ov = BME_edge_getothervert(e1,v);
sv = BME_split_edge(bm,v,e1,&ne,0);
//BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/
+ //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
+ //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
sv->tflag1 |= BME_BEVEL_BEVEL;
ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
@@ -408,6 +470,8 @@ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, B
ov = BME_edge_getothervert(l->e,v);
sv = BME_split_edge(bm,v,l->e,&ne,0);
//BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/
+ //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
+ //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
sv->tflag1 |= BME_BEVEL_BEVEL;
ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
@@ -586,12 +650,15 @@ static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int opti
if (kl->v == kv) {
BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
- BME_JEKV(bm,kl->e,kv);
+ BME_collapse_vert(bm, kl->e, kv, 1.0);
+ //BME_JEKV(bm,kl->e,kv);
+
}
else {
BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
- BME_JEKV(bm,kl->e,kv);
+ BME_collapse_vert(bm, kl->e, kv, 1.0);
+ //BME_JEKV(bm,kl->e,kv);
}
l = l->prev;
}
@@ -620,12 +687,14 @@ static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int opti
if (kl->v == kv) {
BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
- BME_JEKV(bm,kl->e,kv);
+ BME_collapse_vert(bm, kl->e, kv, 1.0);
+ //BME_JEKV(bm,kl->e,kv);
}
else {
BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
- BME_JEKV(bm,kl->e,kv);
+ BME_collapse_vert(bm, kl->e, kv, 1.0);
+ //BME_JEKV(bm,kl->e,kv);
}
}
@@ -1092,7 +1161,8 @@ static void bmesh_dissolve_disk(BME_Mesh *bm, BME_Vert *v){
e = BME_disk_nextedge(e,v);
}while(e != v->edge);
}
- BME_JEKV(bm,v->edge,v);
+ BME_collapse_vert(bm, v->edge, v, 1.0);
+ //BME_JEKV(bm,v->edge,v);
}
}
static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) {
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 6d5f5c914aa..ab573b7edd6 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -360,8 +360,80 @@ static void layerDefault_origspace_face(void *data, int count)
}
/* --------- */
+static void layerDefault_mloopcol(void *data, int count)
+{
+ static MLoopCol default_mloopcol = {255,255,255,255};
+ MLoopCol *mlcol = (MLoopCol*)data;
+ int i;
+ for(i = 0; i < count; i++)
+ mlcol[i] = default_mloopcol;
+}
+static void layerInterp_mloopcol(void **sources, float *weights,
+ float *sub_weights, int count, void *dest)
+{
+ MLoopCol *mc = dest;
+ int i;
+ float *sub_weight;
+ struct {
+ float a;
+ float r;
+ float g;
+ float b;
+ } col;
+ col.a = col.r = col.g = col.b = 0;
+
+ sub_weight = sub_weights;
+ for(i = 0; i < count; ++i){
+ float weight = weights ? weights[i] : 1;
+ MLoopCol *src = sources[i];
+ if(sub_weights){
+ col.a += src->a * (*sub_weight) * weight;
+ col.r += src->r * (*sub_weight) * weight;
+ col.g += src->g * (*sub_weight) * weight;
+ col.b += src->b * (*sub_weight) * weight;
+ sub_weight++;
+ } else {
+ col.a += src->a * weight;
+ col.r += src->r * weight;
+ col.g += src->g * weight;
+ col.b += src->b * weight;
+ }
+ }
+ mc->a = (int)col.a;
+ mc->r = (int)col.r;
+ mc->g = (int)col.g;
+ mc->b = (int)col.b;
+}
+static void layerInterp_mloopuv(void **sources, float *weights,
+ float *sub_weights, int count, void *dest)
+{
+ MLoopUV *mluv = dest;
+ int i;
+ float *sub_weight;
+ struct {
+ float u;
+ float v;
+ }uv;
+ uv.u = uv.v = 0.0;
+
+ sub_weight = sub_weights;
+ for(i = 0; i < count; ++i){
+ float weight = weights ? weights[i] : 1;
+ MLoopUV *src = sources[i];
+ if(sub_weights){
+ uv.u += src->uv[0] * (*sub_weight) * weight;
+ uv.v += src->uv[1] * (*sub_weight) * weight;
+ sub_weight++;
+ } else {
+ uv.u += src->uv[0] * weight;
+ uv.v += src->uv[1] * weight;
+ }
+ }
+ mluv->uv[0] = uv.u;
+ mluv->uv[1] = uv.v;
+}
static void layerInterp_mcol(void **sources, float *weights,
float *sub_weights, int count, void *dest)
@@ -433,6 +505,8 @@ static void layerDefault_mcol(void *data, int count)
mcol[i] = default_mcol;
}
+
+
const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
@@ -457,8 +531,8 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
- {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, NULL, NULL, NULL},
- {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, NULL, NULL, NULL},
+ {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
+ {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
{sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
};
@@ -481,7 +555,11 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT;
const CustomDataMask CD_MASK_BMESH =
- CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL;
+ CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
+const CustomDataMask CD_MASK_FACECORNERS =
+ CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
+ CD_MASK_MLOOPCOL;
+
static const LayerTypeInfo *layerType_getInfo(int type)
{
@@ -1457,6 +1535,36 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
}
/*Bmesh functions*/
+
+void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata)
+{
+ int i;
+ for(i=0; i < fdata->totlayer; i++){
+ if(fdata->layers[i].type == CD_MTFACE){
+ CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0);
+ CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0);
+ }
+ else if(fdata->layers[i].type == CD_MCOL)
+ CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
+ }
+}
+void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata){
+ int i;
+ for(i=0; i < pdata->totlayer; i++){
+ if(pdata->layers[i].type == CD_MTEXPOLY)
+ CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), 0);
+ }
+ for(i=0; i < ldata->totlayer; i++){
+ if(ldata->layers[i].type == CD_MLOOPCOL)
+ CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), 0);
+ }
+}
+
+
+void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
+ if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize);
+}
+
void CustomData_bmesh_free_block(CustomData *data, void **block)
{
const LayerTypeInfo *typeInfo;
@@ -1485,7 +1593,7 @@ static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
CustomData_bmesh_free_block(data, block);
if (data->totsize > 0)
- *block = BLI_mempool_alloc(data->pool);
+ *block = BLI_mempool_calloc(data->pool);
else
*block = NULL;
}
@@ -1602,7 +1710,6 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights
for(i = 0; i < data->totlayer; ++i) {
CustomDataLayer *layer = &data->layers[i];
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
-
if(typeInfo->interp) {
for(j = 0; j < count; ++j)
sources[j] = (char *)src_blocks[j] + layer->offset;
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 24f91ab4f9f..a5ec326fe81 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -224,48 +224,50 @@ void flag_all_listbases_ids(short flag, short value)
/* note: MAX_LIBARRAY define should match this code */
int set_listbasepointers(Main *main, ListBase **lb)
{
+ int a = 0;
+
/* BACKWARDS! also watch order of free-ing! (mesh<->mat) */
- lb[0]= &(main->ipo);
- lb[1]= &(main->key);
- lb[2]= &(main->image);
- lb[3]= &(main->tex);
- lb[4]= &(main->mat);
- lb[5]= &(main->vfont);
+ lb[a++]= &(main->ipo);
+ lb[a++]= &(main->key);
+ lb[a++]= &(main->nodetree);
+ lb[a++]= &(main->image);
+ lb[a++]= &(main->tex);
+ lb[a++]= &(main->mat);
+ lb[a++]= &(main->vfont);
/* Important!: When adding a new object type,
* the specific data should be inserted here
*/
- lb[6]= &(main->armature);
- lb[7]= &(main->action);
+ lb[a++]= &(main->armature);
+ lb[a++]= &(main->action);
- lb[8]= &(main->mesh);
- lb[9]= &(main->curve);
- lb[10]= &(main->mball);
+ lb[a++]= &(main->mesh);
+ lb[a++]= &(main->curve);
+ lb[a++]= &(main->mball);
- lb[11]= &(main->wave);
- lb[12]= &(main->latt);
- lb[13]= &(main->lamp);
- lb[14]= &(main->camera);
+ lb[a++]= &(main->wave);
+ lb[a++]= &(main->latt);
+ lb[a++]= &(main->lamp);
+ lb[a++]= &(main->camera);
- lb[15]= &(main->text);
- lb[16]= &(main->sound);
- lb[17]= &(main->group);
- lb[18]= &(main->nodetree);
- lb[19]= &(main->brush);
- lb[20]= &(main->script);
- lb[21]= &(main->particle);
+ lb[a++]= &(main->text);
+ lb[a++]= &(main->sound);
+ lb[a++]= &(main->group);
+ lb[a++]= &(main->brush);
+ lb[a++]= &(main->script);
+ lb[a++]= &(main->particle);
- lb[22]= &(main->world);
- lb[23]= &(main->screen);
- lb[24]= &(main->object);
- lb[25]= &(main->scene);
- lb[26]= &(main->library);
+ lb[a++]= &(main->world);
+ lb[a++]= &(main->screen);
+ lb[a++]= &(main->object);
+ lb[a++]= &(main->scene);
+ lb[a++]= &(main->library);
- lb[27]= NULL;
+ lb[a]= NULL;
- return 27;
+ return a;
}
/* *********** ALLOC AND FREE *****************
diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index a706e5f3874..8b31459dd38 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -36,7 +36,9 @@ typedef struct BLI_mempool BLI_mempool;
BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk);
void *BLI_mempool_alloc(BLI_mempool *pool);
+void *BLI_mempool_calloc(BLI_mempool *pool);
void BLI_mempool_free(BLI_mempool *pool, void *addr);
void BLI_mempool_destroy(BLI_mempool *pool);
-#endif \ No newline at end of file
+
+#endif
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index a85883f6572..a97b9ca6672 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -523,6 +523,7 @@ static void bvh_div_nodes(BVHTree *tree, BVHNode *node, int start, int end, char
return;
}
+#if 0
static void verify_tree(BVHTree *tree)
{
int i, j, check = 0;
@@ -569,6 +570,7 @@ static void verify_tree(BVHTree *tree)
printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf);
}
+#endif
void BLI_bvhtree_balance(BVHTree *tree)
{
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 7bbf0c4732e..7ac7b8b1791 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -89,7 +89,6 @@ BLI_mempool *BLI_mempool_create(int esize, int tote, int pchunk)
curnode->next = NULL;
return pool;
}
-
void *BLI_mempool_alloc(BLI_mempool *pool){
void *retval=NULL;
BLI_freenode *curnode=NULL;
@@ -117,6 +116,16 @@ void *BLI_mempool_alloc(BLI_mempool *pool){
//memset(retval, 0, pool->esize);
return retval;
}
+
+void *BLI_mempool_calloc(BLI_mempool *pool){
+ void *retval=NULL;
+ retval = BLI_mempool_alloc(pool);
+ memset(retval, 0, pool->esize);
+ return retval;
+}
+
+
+
void BLI_mempool_free(BLI_mempool *pool, void *addr){ //doesnt protect against double frees, dont be stupid!
BLI_freenode *newhead = addr;
newhead->next = pool->free;
@@ -128,4 +137,4 @@ void BLI_mempool_destroy(BLI_mempool *pool)
for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) MEM_freeN(mpchunk->data);
BLI_freelistN(&(pool->chunks));
MEM_freeN(pool);
-} \ No newline at end of file
+}
diff --git a/source/blender/include/BDR_drawobject.h b/source/blender/include/BDR_drawobject.h
index 8b88c996b48..40f2ac1d12a 100644
--- a/source/blender/include/BDR_drawobject.h
+++ b/source/blender/include/BDR_drawobject.h
@@ -64,6 +64,7 @@ void get_local_bounds(struct Object *ob, float *center, float *size);
/* drawing flags: */
#define DRAW_PICKING 1
#define DRAW_CONSTCOLOR 2
+#define DRAW_SCENESET 4
void draw_object(struct Base *base, int flag);
void drawaxes(float size, int flag, char drawtype);
diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h
index 0e1557ac378..24112c7f11a 100644
--- a/source/blender/include/BIF_editarmature.h
+++ b/source/blender/include/BIF_editarmature.h
@@ -80,7 +80,7 @@ void clear_armature(struct Object *ob, char mode);
void delete_armature(void);
void deselectall_armature(int toggle, int doundo);
void deselectall_posearmature (struct Object *ob, int test, int doundo);
-int draw_armature(struct Base *base, int dt);
+int draw_armature(struct Base *base, int dt, int flag);
void extrude_armature(int forked);
void subdivide_armature(int numcuts);
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 3cf80a4efa6..77ebef744eb 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -339,8 +339,9 @@ typedef struct FreeCamera {
/* ipoactuator->flag */
#define ACT_IPOFORCE (1 << 0)
#define ACT_IPOEND (1 << 1)
-#define ACT_IPOFORCE_LOCAL (1 << 2)
-#define ACT_IPOCHILD (1 << 4)
+#define ACT_IPOLOCAL (1 << 2)
+#define ACT_IPOCHILD (1 << 4)
+#define ACT_IPOADD (1 << 5)
/* ipoactuator->flag for k2k */
#define ACT_K2K_PREV 1
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index 616a5a227c4..7050e61a6ac 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -1581,6 +1581,18 @@ static void change_object_actuator(void *act, void *arg)
}
}
+static void change_ipo_actuator(void *arg1_but, void *arg2_ia)
+{
+ bIpoActuator *ia = arg2_ia;
+ uiBut *but = arg1_but;
+
+ if (but->retval & ACT_IPOFORCE)
+ ia->flag &= ~ACT_IPOADD;
+ else if (but->retval & ACT_IPOADD)
+ ia->flag &= ~ACT_IPOFORCE;
+ but->retval = B_REDR;
+}
+
void update_object_actuator_PID(void *act, void *arg)
{
bObjectActuator *oa = act;
@@ -1799,42 +1811,49 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
str = "Ipo types %t|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
- uiDefButS(block, MENU, B_REDR, str, xco+20, yco-24, width-40 - (width-40)/3, 19, &ia->type, 0, 0, 0, 0, "");
- uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR,
- "Child", xco+20+0.666*(width-40), yco-24, (width-40)/3, 19,
+ uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, (width-20)/2, 19, &ia->type, 0, 0, 0, 0, "");
+
+ but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE,
+ "Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19,
&ia->flag, 0, 0, 0, 0,
- "Add all children Objects as well");
+ "Convert Ipo to force. Force is applied in global or local coordinate according to Local flag");
+ uiButSetFunc(but, change_ipo_actuator, but, ia);
+
+ but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD,
+ "Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19,
+ &ia->flag, 0, 0, 0, 0,
+ "Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag");
+ uiButSetFunc(but, change_ipo_actuator, but, ia);
+
+ /* Only show the do-force-local toggle if force is requested */
+ if (ia->flag & (ACT_IPOFORCE|ACT_IPOADD)) {
+ uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0,
+ "L", xco+width-30, yco-24, 20, 19,
+ &ia->flag, 0, 0, 0, 0,
+ "Let the ipo acts in local coordinates, used in Force and Add mode.");
+ }
if(ia->type==ACT_IPO_FROM_PROP) {
uiDefBut(block, TEX, 0,
- "Prop: ", xco+20, yco-44, width-40, 19,
+ "Prop: ", xco+10, yco-44, width-80, 19,
ia->name, 0.0, 31.0, 0, 0,
"Use this property to define the Ipo position");
}
else {
uiDefButI(block, NUM, 0,
- "Sta", xco+20, yco-44, (width-100)/2, 19,
+ "Sta", xco+10, yco-44, (width-80)/2, 19,
&ia->sta, 0.0, MAXFRAMEF, 0, 0,
"Start frame, (subtract 1 to match blenders frame numbers)");
uiDefButI(block, NUM, 0,
- "End", xco+18+(width-90)/2, yco-44, (width-100)/2, 19,
+ "End", xco+10+(width-80)/2, yco-44, (width-80)/2, 19,
&ia->end, 0.0, MAXFRAMEF, 0, 0,
"End frame, (subtract 1 to match blenders frame numbers)");
-
- uiDefButBitS(block, TOG, ACT_IPOFORCE, B_REDR,
- "Force", xco+width-78, yco-44, 43, 19,
- &ia->flag, 0, 0, 0, 0,
- "Convert Ipo to force");
-
- /* Only show the do-force-local toggle if force is requested */
- if (ia->flag & ACT_IPOFORCE) {
- uiDefButBitS(block, TOG, ACT_IPOFORCE_LOCAL, 0,
- "L", xco+width-35, yco-44, 15, 19,
- &ia->flag, 0, 0, 0, 0,
- "Let the force-ipo act in local coordinates.");
- }
-
}
+ uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR,
+ "Child", xco+10+(width-80), yco-44, 60, 19,
+ &ia->flag, 0, 0, 0, 0,
+ "Update IPO on all children Objects as well");
+
yco-= ysize;
break;
}
diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c
index 73915a69139..6d78b21dfbb 100644
--- a/source/blender/src/drawarmature.c
+++ b/source/blender/src/drawarmature.c
@@ -2500,7 +2500,7 @@ static void draw_ghost_poses(Base *base)
/* ********************************** Armature Drawing - Main ************************* */
/* called from drawobject.c, return 1 if nothing was drawn */
-int draw_armature(Base *base, int dt)
+int draw_armature(Base *base, int dt, int flag)
{
Object *ob= base->object;
bArmature *arm= ob->data;
@@ -2544,15 +2544,16 @@ int draw_armature(Base *base, int dt)
if (arm->ghostep)
draw_ghost_poses(base);
}
+ if ((flag & DRAW_SCENESET)==0) {
+ if(ob==OBACT)
+ arm->flag |= ARM_POSEMODE;
+ else if(G.f & G_WEIGHTPAINT)
+ arm->flag |= ARM_POSEMODE;
- if(ob==OBACT)
- arm->flag |= ARM_POSEMODE;
- else if(G.f & G_WEIGHTPAINT)
- arm->flag |= ARM_POSEMODE;
-
- draw_pose_paths(ob);
+ draw_pose_paths(ob);
+ }
}
- }
+ }
draw_pose_channels(base, dt);
arm->flag &= ~ARM_POSEMODE;
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 628fc2108fe..455b85aa499 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -4736,7 +4736,7 @@ static void drawSolidSelect(Base *base)
}
else if(ob->type==OB_ARMATURE) {
if(!(ob->flag & OB_POSEMODE)) {
- draw_armature(base, OB_WIRE);
+ draw_armature(base, OB_WIRE, 0);
}
}
@@ -4857,7 +4857,7 @@ void drawRBpivot(bRigidBodyJointConstraint *data){
setlinestyle(0);
}
-/* flag can be DRAW_PICKING and/or DRAW_CONSTCOLOR */
+/* flag can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET */
void draw_object(Base *base, int flag)
{
static int warning_recursive= 0;
@@ -5061,7 +5061,7 @@ void draw_object(Base *base, int flag)
/* draw outline for selected solid objects, mesh does itself */
if((G.vd->flag & V3D_SELECT_OUTLINE) && ob->type!=OB_MESH) {
- if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=G.obedit) {
+ if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=G.obedit && (flag && DRAW_SCENESET)==0) {
if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) {
drawSolidSelect(base);
}
@@ -5208,7 +5208,7 @@ void draw_object(Base *base, int flag)
break;
case OB_ARMATURE:
if(dt>OB_WIRE) set_gl_material(0); // we use defmaterial
- empty_object= draw_armature(base, dt);
+ empty_object= draw_armature(base, dt, flag);
if(dt>OB_WIRE) set_gl_material(-1);
break;
default:
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 6e58d1a786e..f0ab3461ab9 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -3149,7 +3149,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata)
if(v3d->lay & base->lay) {
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
- draw_object(base, DRAW_CONSTCOLOR);
+ draw_object(base, DRAW_CONSTCOLOR|DRAW_SCENESET);
if(base->object->transflag & OB_DUPLI) {
draw_dupli_objects_color(v3d, base, TH_WIRE);
@@ -3391,7 +3391,7 @@ void drawview3d_render(struct View3D *v3d, float viewmat[][4], int winx, int win
where_is_object(base->object);
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
- draw_object(base, DRAW_CONSTCOLOR);
+ draw_object(base, DRAW_CONSTCOLOR|DRAW_SCENESET);
if(base->object->transflag & OB_DUPLI) {
draw_dupli_objects(v3d, base);
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 39f93510358..6310dd0a262 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -1646,8 +1646,9 @@ void load_editArmature(void)
}
/* toggle==0: deselect
- toggle==1: swap
+ toggle==1: swap (based on test)
toggle==2: only active tag
+ toggle==3: swap (no test)
*/
void deselectall_armature(int toggle, int doundo)
{
@@ -1670,18 +1671,30 @@ void deselectall_armature(int toggle, int doundo)
else sel= toggle;
/* Set the flags */
- for (eBone=G.edbo.first;eBone;eBone=eBone->next){
- if (sel==1) {
+ for (eBone=G.edbo.first;eBone;eBone=eBone->next) {
+ if (sel==3) {
+ /* invert selection of bone */
+ if ((arm->layer & eBone->layer) && (eBone->flag & BONE_HIDDEN_A)==0) {
+ eBone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ eBone->flag &= ~BONE_ACTIVE;
+ }
+ }
+ else if (sel==1) {
+ /* select bone */
if(arm->layer & eBone->layer && (eBone->flag & BONE_HIDDEN_A)==0) {
eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
if(eBone->parent)
eBone->parent->flag |= (BONE_TIPSEL);
}
}
- else if (sel==2)
+ else if (sel==2) {
+ /* clear active flag */
eBone->flag &= ~(BONE_ACTIVE);
- else
+ }
+ else {
+ /* deselect bone */
eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE);
+ }
}
allqueue(REDRAWVIEW3D, 0);
@@ -3276,8 +3289,9 @@ int do_pose_selectbuffer(Base *base, unsigned int *buffer, short hits)
}
/* test==0: deselect all
- test==1: swap select
- test==2: only clear active tag
+ test==1: swap select (apply to all the opposite of current situation)
+ test==2: only clear active tag
+ test==3: swap select (no test / inverse selection status of all independently)
*/
void deselectall_posearmature (Object *ob, int test, int doundo)
{
@@ -3307,16 +3321,27 @@ void deselectall_posearmature (Object *ob, int test, int doundo)
/* Set the flags accordingly */
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if ((pchan->bone->layer & arm->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
- if (selectmode==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
- else if (selectmode==1) pchan->bone->flag |= BONE_SELECTED;
- else pchan->bone->flag &= ~BONE_ACTIVE;
+ if (test==3) {
+ pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+ pchan->bone->flag &= ~BONE_ACTIVE;
+ }
+ else {
+ if (selectmode==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
+ else if (selectmode==1) pchan->bone->flag |= BONE_SELECTED;
+ else pchan->bone->flag &= ~BONE_ACTIVE;
+ }
}
}
/* action editor */
- deselect_actionchannels(ob->action, 0); /* deselects for sure */
- if (selectmode == 1)
- deselect_actionchannels(ob->action, 1); /* swaps */
+ if (test == 3) {
+ deselect_actionchannels(ob->action, 2); /* inverts selection */
+ }
+ else {
+ deselect_actionchannels(ob->action, 0); /* deselects for sure */
+ if (selectmode == 1)
+ deselect_actionchannels(ob->action, 1); /* swaps */
+ }
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWBUTSOBJECT, 0);
diff --git a/source/blender/src/editmesh_add.c b/source/blender/src/editmesh_add.c
index 952ae957f34..9516f39b05c 100644
--- a/source/blender/src/editmesh_add.c
+++ b/source/blender/src/editmesh_add.c
@@ -379,7 +379,7 @@ static EditFace *addface_from_edges(void)
/* find the 4 edges */
for(eed= em->edges.first; eed; eed= eed->next) {
- if(eed->f & SELECT) {
+ if( (eed->f & SELECT) || (eed->v1->f & eed->v2->f & SELECT) ) {
if(eedar[0]==NULL) eedar[0]= eed;
else if(eedar[1]==NULL) eedar[1]= eed;
else if(eedar[2]==NULL) eedar[2]= eed;
@@ -765,6 +765,7 @@ void addedgeface_mesh(void)
/* if 4 edges exist, we just create the face, convex or not */
efa= addface_from_edges();
if(efa==NULL) {
+
/* the order of vertices can be anything, 6 cases to check */
if( convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co) ) {
efa= addfacelist(neweve[0], neweve[1], neweve[2], neweve[3], NULL, NULL);
@@ -775,17 +776,16 @@ void addedgeface_mesh(void)
else if( convex(neweve[0]->co, neweve[2]->co, neweve[1]->co, neweve[3]->co) ) {
efa= addfacelist(neweve[0], neweve[2], neweve[1], neweve[3], NULL, NULL);
}
-
- else if( convex(neweve[1]->co, neweve[2]->co, neweve[3]->co, neweve[0]->co) ) {
- efa= addfacelist(neweve[1], neweve[2], neweve[3], neweve[0], NULL, NULL);
+ else if( convex(neweve[0]->co, neweve[1]->co, neweve[3]->co, neweve[2]->co) ) {
+ efa= addfacelist(neweve[0], neweve[1], neweve[3], neweve[2], NULL, NULL);
}
- else if( convex(neweve[1]->co, neweve[3]->co, neweve[0]->co, neweve[2]->co) ) {
- efa= addfacelist(neweve[1], neweve[3], neweve[0], neweve[2], NULL, NULL);
+ else if( convex(neweve[0]->co, neweve[3]->co, neweve[2]->co, neweve[1]->co) ) {
+ efa= addfacelist(neweve[0], neweve[3], neweve[2], neweve[1], NULL, NULL);
}
- else if( convex(neweve[1]->co, neweve[3]->co, neweve[2]->co, neweve[0]->co) ) {
- efa= addfacelist(neweve[1], neweve[3], neweve[2], neweve[0], NULL, NULL);
+ else if( convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co) ) {
+ efa= addfacelist(neweve[0], neweve[3], neweve[1], neweve[2], NULL, NULL);
}
- else error("The selected vertices form a concave quad");
+ else printf("cannot find nice quad from concave set of vertices\n");
}
}
}
diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c
index fcf76e8a13c..8383d375c4a 100644
--- a/source/blender/src/editsima.c
+++ b/source/blender/src/editsima.c
@@ -694,7 +694,7 @@ void mouse_select_sima(void)
EditFace *efa;
MTFace *tf, *nearesttf;
EditFace *nearestefa=NULL;
- int a, selectsticky, edgeloop, actface, nearestuv, nearestedge, i, shift, island;
+ int a, selectsticky, edgeloop, actface, nearestuv, nearestedge, i, shift, island=0;
char sticky= 0;
int flush = 0; /* 0 == dont flush, 1 == sel, -1 == desel; only use when selection sync is enabled */
unsigned int hitv[4], nearestv;
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index 8e5713a3635..184b7930dd8 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -1313,6 +1313,9 @@ static void do_view3d_select_armaturemenu(void *arg, int event)
case 3: /* Select Parent(s) */
select_bone_parent();
break;
+ case 4: /* Swap Select All */
+ deselectall_armature(3, 1);
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -1331,6 +1334,8 @@ static uiBlock *view3d_select_armaturemenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Swap Select All|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Parent(s)|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
if(curarea->headertype==HEADERTOP) {
@@ -1356,12 +1361,15 @@ static void do_view3d_select_pose_armaturemenu(void *arg, int event)
case 2: /* Select/Deselect all */
deselectall_posearmature(OBACT, 1, 1);
break;
- case 3:
+ case 3: /* Select Target(s) of Constraint(s) */
pose_select_constraint_target();
break;
- case 4:
+ case 4: /* Select Bone's Parent */
select_bone_parent();
break;
+ case 5: /* Swap Select All */
+ deselectall_posearmature(OBACT, 3, 1);
+ break;
}
allqueue(REDRAWVIEW3D, 0);
}
@@ -1379,6 +1387,7 @@ static uiBlock *view3d_select_pose_armaturemenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Swap Select All|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Constraint Target|W", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Parent(s)|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
@@ -4106,7 +4115,7 @@ static uiBlock *view3d_pose_armature_ikmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_pose_armature_ikmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_pose_armature_ikmenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add IK to Bone...|Ctrl I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Add IK to Bone...|Shift I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear IK...|Alt I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiBlockSetDirection(block, UI_RIGHT);
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 2b23e977902..5e1780dfe62 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -2199,10 +2199,14 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case IKEY:
if(G.qual==LR_CTRLKEY) {
- if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
- pose_add_IK();
- else if(ob && G.obedit)
- selectswap_mesh();
+ if((ob) && (ob->flag & OB_POSEMODE) && (ob->type==OB_ARMATURE))
+ deselectall_posearmature(ob, 3, 1);
+ else if(ob && G.obedit) {
+ if(G.obedit->type == OB_ARMATURE)
+ deselectall_armature(3, 1);
+ else
+ selectswap_mesh();
+ }
else
selectswap();
}
@@ -2210,6 +2214,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
pose_clear_IK();
}
+ else if(G.qual==LR_SHIFTKEY) {
+ if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
+ pose_add_IK();
+ }
break;
case JKEY:
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index 0e7e2e5eacb..4c56e5ce64e 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -1272,7 +1272,7 @@ void viewmoveNDOF(int mode)
float q1[4];
float obofs[3];
float reverse;
- float diff[4];
+ //float diff[4];
float d, curareaX, curareaY;
float mat[3][3];
float upvec[3];
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 93d59a03e01..f23defb16a4 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -2343,7 +2343,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
{
KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
struct Object* blenderobj = converter->FindBlenderObject(gameobj);
- gameobj->SetState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
+ gameobj->SetInitState((blenderobj->init_state)?blenderobj->init_state:blenderobj->state);
+ gameobj->ResetState();
}
#endif //CONVERT_LOGIC
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 6e05ea31fe8..9b1bc1e6b90 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -233,7 +233,8 @@ void BL_ConvertActuators(char* maggiename,
STR_String propname = ( ipoact->name ? ipoact->name : "");
// first bit?
bool ipo_as_force = (ipoact->flag & ACT_IPOFORCE);
- bool force_local = (ipoact->flag & ACT_IPOFORCE_LOCAL);
+ bool local = (ipoact->flag & ACT_IPOLOCAL);
+ bool ipo_add = (ipoact->flag & ACT_IPOADD);
KX_IpoActuator* tmpbaseact = new KX_IpoActuator(
gameobj,
@@ -244,8 +245,8 @@ void BL_ConvertActuators(char* maggiename,
ipoact->type + 1, // + 1, because Blender starts to count at zero,
// Ketsji at 1, because zero is reserved for "NoDef"
ipo_as_force,
- force_local
- );
+ ipo_add,
+ local);
baseact = tmpbaseact;
break;
}
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index 04cc119efee..2bcb604dd23 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -76,18 +76,36 @@ static inline void Py_Fatal(char *M) {
virtual PyTypeObject *GetType(void) {return &Type;}; \
virtual PyParentObject *GetParents(void) {return Parents;}
+
// This defines the _getattr_up macro
// which allows attribute and method calls
// to be properly passed up the hierarchy.
#define _getattr_up(Parent) \
- PyObject *rvalue = Py_FindMethod(Methods, this, const_cast<char*>(attr.ReadPtr())); \
- if (rvalue == NULL) \
- { \
+ PyObject *rvalue = NULL; \
+ if (attr=="__methods__") { \
+ PyObject *_attr_string = NULL; \
+ PyMethodDef *meth = Methods; \
+ rvalue = Parent::_getattr(attr); \
+ if (rvalue==NULL) { \
+ PyErr_Clear(); \
+ rvalue = PyList_New(0); \
+ } \
+ if (meth) { \
+ for (; meth->ml_name != NULL; meth++) { \
+ _attr_string = PyString_FromString(meth->ml_name); \
+ PyList_Append(rvalue, _attr_string); \
+ Py_DECREF(_attr_string); \
+ } \
+ } \
+ } else { \
+ rvalue = Py_FindMethod(Methods, this, const_cast<char*>(attr.ReadPtr())); \
+ if (rvalue == NULL) { \
PyErr_Clear(); \
- return Parent::_getattr(attr); \
+ rvalue = Parent::_getattr(attr); \
} \
- else \
- return rvalue
+ } \
+ return rvalue; \
+
/**
* These macros are helpfull when embedding Python routines. The second
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
index eb4008e9275..ee7ea0bad80 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
@@ -111,7 +111,7 @@ void SCA_ActuatorSensor::Update()
{
if (m_actuator)
{
- m_midresult = m_actuator->IsActive();
+ m_midresult = m_actuator->IsActive() && !m_actuator->IsNegativeEvent();
}
}
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index 774b27c5ad4..7ffb21b5490 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -87,6 +87,7 @@ public:
bool IsNegativeEvent() const;
virtual ~SCA_IActuator();
+ void ClrLink() { m_links=0; }
void IncLink() { m_links++; }
void DecLink();
bool IsNoLink() const { return !m_links; }
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index 27e7d5faada..c5bb4a41552 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -40,7 +40,7 @@
MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
-SCA_IObject::SCA_IObject(PyTypeObject* T): m_state(0), CValue(T)
+SCA_IObject::SCA_IObject(PyTypeObject* T): m_initState(0), m_state(0), CValue(T)
{
m_suspended = false;
}
@@ -164,7 +164,9 @@ void SCA_IObject::ReParentLogic()
{
SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
newactuator->ReParent(this);
+ // actuators are initially not connected to any controller
newactuator->SetActive(false);
+ newactuator->ClrLink();
oldactuators[act++] = newactuator;
}
@@ -175,6 +177,7 @@ void SCA_IObject::ReParentLogic()
{
SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
newcontroller->ReParent(this);
+ newcontroller->SetActive(false);
oldcontrollers[con++]=newcontroller;
}
@@ -186,6 +189,9 @@ void SCA_IObject::ReParentLogic()
{
SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
newsensor->ReParent(this);
+ newsensor->SetActive(false);
+ // sensors are initially not connected to any controller
+ newsensor->ClrLink();
oldsensors[sen++] = newsensor;
}
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index 07b4310a91e..38a7ed29dca 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -69,6 +69,11 @@ protected:
bool m_suspended;
/**
+ * init state of object (used when object is created)
+ */
+ unsigned int m_initState;
+
+ /**
* current state = bit mask of state that are active
*/
unsigned int m_state;
@@ -118,6 +123,16 @@ public:
void Resume(void);
/**
+ * Set init state
+ */
+ void SetInitState(unsigned int initState) { m_initState = initState; }
+
+ /**
+ * initialize the state when object is created
+ */
+ void ResetState(void) { SetState(m_initState); }
+
+ /**
* Set the object state
*/
void SetState(unsigned int state);
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index f2ed6a803c2..4ce49e71507 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -126,6 +126,8 @@ public:
/** Resume sensing. */
void Resume();
+ void ClrLink()
+ { m_links = 0; }
void IncLink()
{ m_links++; }
void DecLink();
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 45ac4b680b9..9966dcf93a4 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -405,34 +405,25 @@ void KX_GameObject::ResetDebugColor()
SetDebugColor(0xff000000);
}
+void KX_GameObject::InitIPO(bool ipo_as_force,
+ bool ipo_add,
+ bool ipo_local)
+{
+ SGControllerList::iterator it = GetSGNode()->GetSGControllerList().begin();
+ while (it != GetSGNode()->GetSGControllerList().end()) {
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true);
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, ipo_as_force);
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, ipo_add);
+ (*it)->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, ipo_local);
+ it++;
+ }
+}
void KX_GameObject::UpdateIPO(float curframetime,
- bool recurse,
- bool ipo_as_force,
- bool force_local)
+ bool recurse)
{
-
- // The ipo-actuator needs a sumo reference... this is retrieved (unfortunately)
- // by the iposgcontr itself...
-// ipocontr->SetSumoReference(gameobj->GetSumoScene(),
-// gameobj->GetSumoObject());
-
-
- // The ipo has to be treated as a force, and not a displacement!
- // For this case, we send some settings to the controller. This
- // may need some caching...
- if (ipo_as_force) {
- SGControllerList::iterator it = GetSGNode()->GetSGControllerList().begin();
-
- while (it != GetSGNode()->GetSGControllerList().end()) {
- (*it)->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, ipo_as_force);
- (*it)->SetOption(SG_Controller::SG_CONTR_IPO_FORCES_ACT_LOCAL, force_local);
- it++;
- }
- }
-
- // The rest is the 'normal' update procedure.
+ // just the 'normal' update procedure.
GetSGNode()->SetSimulatedTime(curframetime,recurse);
GetSGNode()->UpdateWorldData(curframetime);
UpdateTransform();
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 5e44a36515d..b4f50087742 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -490,14 +490,22 @@ public:
);
/**
+ * Function to set IPO option at start of IPO
+ */
+ void
+ InitIPO(
+ bool ipo_as_force,
+ bool ipo_add,
+ bool ipo_local
+ );
+
+ /**
* Odd function to update an ipo. ???
*/
void
UpdateIPO(
float curframetime,
- bool recurse,
- bool ipo_as_force,
- bool force_ipo_local
+ bool recurse
);
/**
* Updates Material Ipo data
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
index 5303e9a9e85..d3aa924665e 100644
--- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
@@ -55,7 +55,8 @@ typedef unsigned long uint_ptr;
// start on another frame, the 1.0 should change.
KX_IpoSGController::KX_IpoSGController()
: m_ipo_as_force(false),
- m_force_ipo_acts_local(false),
+ m_ipo_add(false),
+ m_ipo_local(false),
m_modified(true),
m_ipo_start_initialized(false),
m_ipotime(1.0)
@@ -75,8 +76,23 @@ void KX_IpoSGController::SetOption(
m_ipo_as_force = (value != 0);
m_modified = true;
break;
- case SG_CONTR_IPO_FORCES_ACT_LOCAL:
- m_force_ipo_acts_local = (value != 0);
+ case SG_CONTR_IPO_IPO_ADD:
+ m_ipo_add = (value != 0);
+ m_modified = true;
+ break;
+ case SG_CONTR_IPO_RESET:
+ if (m_ipo_start_initialized && value) {
+ m_ipo_start_initialized = false;
+ m_modified = true;
+ }
+ break;
+ case SG_CONTR_IPO_LOCAL:
+ if (value/* && ((SG_Node*)m_pObject)->GetSGParent() == NULL*/) {
+ // only accept local Ipo if the object has no parent
+ m_ipo_local = true;
+ } else {
+ m_ipo_local = false;
+ }
m_modified = true;
break;
default:
@@ -129,15 +145,19 @@ bool KX_IpoSGController::Update(double currentTime)
{
if (m_game_object && ob)
{
- m_game_object->GetPhysicsController()->ApplyForce(m_force_ipo_acts_local ?
+ m_game_object->GetPhysicsController()->ApplyForce(m_ipo_local ?
ob->GetWorldOrientation() * m_ipo_xform.GetPosition() :
m_ipo_xform.GetPosition(), false);
}
}
else
{
- //by default, leave object as it stands
- MT_Point3 newPosition = ob->GetLocalPosition();
+ // Local ipo should be defined with the object position at (0,0,0)
+ // Local transform is applied to the object based on initial position
+ MT_Point3 newPosition(0.0,0.0,0.0);
+
+ if (!m_ipo_add)
+ newPosition = ob->GetLocalPosition();
//apply separate IPO channels if there is any data in them
//Loc and dLoc act by themselves or are additive
//LocX and dLocX
@@ -145,23 +165,28 @@ bool KX_IpoSGController::Update(double currentTime)
newPosition[0] = (m_ipo_channels_active[OB_DLOC_X] ? m_ipo_xform.GetPosition()[0] + m_ipo_xform.GetDeltaPosition()[0] : m_ipo_xform.GetPosition()[0]);
}
else if (m_ipo_channels_active[OB_DLOC_X] && m_ipo_start_initialized) {
- newPosition[0] = (m_ipo_start_point[0] + m_ipo_xform.GetDeltaPosition()[0]);
+ newPosition[0] = (((!m_ipo_add)?m_ipo_start_point[0]:0.0) + m_ipo_xform.GetDeltaPosition()[0]);
}
//LocY and dLocY
if (m_ipo_channels_active[OB_LOC_Y]) {
newPosition[1] = (m_ipo_channels_active[OB_DLOC_Y] ? m_ipo_xform.GetPosition()[1] + m_ipo_xform.GetDeltaPosition()[1] : m_ipo_xform.GetPosition()[1]);
}
else if (m_ipo_channels_active[OB_DLOC_Y] && m_ipo_start_initialized) {
- newPosition[1] = (m_ipo_start_point[1] + m_ipo_xform.GetDeltaPosition()[1]);
+ newPosition[1] = (((!m_ipo_add)?m_ipo_start_point[1]:0.0) + m_ipo_xform.GetDeltaPosition()[1]);
}
//LocZ and dLocZ
if (m_ipo_channels_active[OB_LOC_Z]) {
newPosition[2] = (m_ipo_channels_active[OB_DLOC_Z] ? m_ipo_xform.GetPosition()[2] + m_ipo_xform.GetDeltaPosition()[2] : m_ipo_xform.GetPosition()[2]);
}
else if (m_ipo_channels_active[OB_DLOC_Z] && m_ipo_start_initialized) {
- newPosition[2] = (m_ipo_start_point[2] + m_ipo_xform.GetDeltaPosition()[2]);
+ newPosition[2] = (((!m_ipo_add)?m_ipo_start_point[2]:0.0) + m_ipo_xform.GetDeltaPosition()[2]);
+ }
+ if (m_ipo_add) {
+ if (m_ipo_local)
+ newPosition = m_ipo_start_point + m_ipo_start_scale*(m_ipo_start_orient*newPosition);
+ else
+ newPosition = m_ipo_start_point + newPosition;
}
-
ob->SetLocalPosition(newPosition);
}
}
@@ -170,21 +195,23 @@ bool KX_IpoSGController::Update(double currentTime)
if (m_ipo_as_force) {
if (m_game_object && ob) {
- m_game_object->ApplyTorque(m_force_ipo_acts_local ?
+ m_game_object->ApplyTorque(m_ipo_local ?
ob->GetWorldOrientation() * m_ipo_xform.GetEulerAngles() :
m_ipo_xform.GetEulerAngles(), false);
}
} else {
- double yaw, pitch, roll; //final Euler angles
+ double yaw=0, pitch=0, roll=0; //final Euler angles
double tempYaw=0, tempPitch=0, tempRoll=0; //temp holders
- ob->GetLocalOrientation().getEuler(yaw, pitch, roll);
+ if (!m_ipo_add)
+ ob->GetLocalOrientation().getEuler(yaw, pitch, roll);
//RotX and dRotX
if (m_ipo_channels_active[OB_ROT_X]) {
yaw = (m_ipo_channels_active[OB_DROT_X] ? (m_ipo_xform.GetEulerAngles()[0] + m_ipo_xform.GetDeltaEulerAngles()[0]) : m_ipo_xform.GetEulerAngles()[0] );
}
else if (m_ipo_channels_active[OB_DROT_X] && m_ipo_start_initialized) {
- m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
+ if (!m_ipo_add)
+ m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
yaw = tempYaw + m_ipo_xform.GetDeltaEulerAngles()[0];
}
@@ -193,7 +220,8 @@ bool KX_IpoSGController::Update(double currentTime)
pitch = (m_ipo_channels_active[OB_DROT_Y] ? (m_ipo_xform.GetEulerAngles()[1] + m_ipo_xform.GetDeltaEulerAngles()[1]) : m_ipo_xform.GetEulerAngles()[1] );
}
else if (m_ipo_channels_active[OB_DROT_Y] && m_ipo_start_initialized) {
- m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
+ if (!m_ipo_add)
+ m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
pitch = tempPitch + m_ipo_xform.GetDeltaEulerAngles()[1];
}
@@ -202,23 +230,34 @@ bool KX_IpoSGController::Update(double currentTime)
roll = (m_ipo_channels_active[OB_DROT_Z] ? (m_ipo_xform.GetEulerAngles()[2] + m_ipo_xform.GetDeltaEulerAngles()[2]) : m_ipo_xform.GetEulerAngles()[2] );
}
else if (m_ipo_channels_active[OB_DROT_Z] && m_ipo_start_initialized) {
- m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
+ if (!m_ipo_add)
+ m_ipo_start_orient.getEuler(tempYaw, tempPitch, tempRoll);
roll = tempRoll + m_ipo_xform.GetDeltaEulerAngles()[2];
}
-
- ob->SetLocalOrientation(MT_Vector3(yaw, pitch, roll));
+ if (m_ipo_add) {
+ MT_Matrix3x3 rotation(MT_Vector3(yaw, pitch, roll));
+ if (m_ipo_local)
+ rotation = m_ipo_start_orient * rotation;
+ else
+ rotation = rotation * m_ipo_start_orient;
+ ob->SetLocalOrientation(rotation);
+ } else {
+ ob->SetLocalOrientation(MT_Vector3(yaw, pitch, roll));
+ }
}
}
//modifies scale?
if (m_ipo_channels_active[OB_SIZE_X] || m_ipo_channels_active[OB_SIZE_Y] || m_ipo_channels_active[OB_SIZE_Z] || m_ipo_channels_active[OB_DSIZE_X] || m_ipo_channels_active[OB_DSIZE_Y] || m_ipo_channels_active[OB_DSIZE_Z]) {
//default is no scale change
- MT_Vector3 newScale = ob->GetLocalScale();
+ MT_Vector3 newScale(1.0,1.0,1.0);
+ if (!m_ipo_add)
+ newScale = ob->GetLocalScale();
if (m_ipo_channels_active[OB_SIZE_X]) {
newScale[0] = (m_ipo_channels_active[OB_DSIZE_X] ? (m_ipo_xform.GetScaling()[0] + m_ipo_xform.GetDeltaScaling()[0]) : m_ipo_xform.GetScaling()[0]);
}
else if (m_ipo_channels_active[OB_DSIZE_X] && m_ipo_start_initialized) {
- newScale[0] = (m_ipo_xform.GetDeltaScaling()[0] + m_ipo_start_scale[0]);
+ newScale[0] = (m_ipo_xform.GetDeltaScaling()[0] + ((!m_ipo_add)?m_ipo_start_scale[0]:0.0));
}
//RotY dRotY
@@ -226,7 +265,7 @@ bool KX_IpoSGController::Update(double currentTime)
newScale[1] = (m_ipo_channels_active[OB_DSIZE_Y] ? (m_ipo_xform.GetScaling()[1] + m_ipo_xform.GetDeltaScaling()[1]): m_ipo_xform.GetScaling()[1]);
}
else if (m_ipo_channels_active[OB_DSIZE_Y] && m_ipo_start_initialized) {
- newScale[1] = (m_ipo_xform.GetDeltaScaling()[1] + m_ipo_start_scale[1]);
+ newScale[1] = (m_ipo_xform.GetDeltaScaling()[1] + ((!m_ipo_add)?m_ipo_start_scale[1]:0.0));
}
//RotZ and dRotZ
@@ -234,7 +273,11 @@ bool KX_IpoSGController::Update(double currentTime)
newScale[2] = (m_ipo_channels_active[OB_DSIZE_Z] ? (m_ipo_xform.GetScaling()[2] + m_ipo_xform.GetDeltaScaling()[2]) : m_ipo_xform.GetScaling()[2]);
}
else if (m_ipo_channels_active[OB_DSIZE_Z] && m_ipo_start_initialized) {
- newScale[2] = (m_ipo_xform.GetDeltaScaling()[2] + m_ipo_start_scale[2]);
+ newScale[2] = (m_ipo_xform.GetDeltaScaling()[2] + ((!m_ipo_add)?m_ipo_start_scale[2]:1.0));
+ }
+
+ if (m_ipo_add) {
+ newScale = m_ipo_start_scale * newScale;
}
ob->SetLocalScale(newScale);
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.h b/source/gameengine/Ketsji/KX_IPO_SGController.h
index 7b5a151b41c..0bd8980f11c 100644
--- a/source/gameengine/Ketsji/KX_IPO_SGController.h
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.h
@@ -48,8 +48,11 @@ class KX_IpoSGController : public SG_Controller
/** Interpret the ipo as a force rather than a displacement? */
bool m_ipo_as_force;
- /** Ipo-as-force acts in local rather than in global coordinates? */
- bool m_force_ipo_acts_local;
+ /** Add Ipo curve to current loc/rot/scale */
+ bool m_ipo_add;
+
+ /** Ipo must be applied in local coordinate rather than in global coordinates (used for force and Add mode)*/
+ bool m_ipo_local;
/** Were settings altered since the last update? */
bool m_modified;
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index cf246342cf9..b7103f49aee 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -59,40 +59,6 @@ STR_String KX_IpoActuator::S_KX_ACT_IPO_FROM_PROP_STRING = "FromProp";
/* ------------------------------------------------------------------------- */
/* Native functions */
/* ------------------------------------------------------------------------- */
-/** Another poltergeist? This seems to be a very transient class... */
-class CIpoAction : public CAction
-{
- float m_curtime;
- bool m_recurse;
- KX_GameObject* m_gameobj;
- bool m_ipo_as_force;
- bool m_force_ipo_local;
-
-public:
- CIpoAction(KX_GameObject* gameobj,
- float curtime,
- bool recurse,
- bool ipo_as_force,
- bool force_ipo_local) :
- m_curtime(curtime) ,
- m_recurse(recurse),
- m_gameobj(gameobj),
- m_ipo_as_force(ipo_as_force),
- m_force_ipo_local(force_ipo_local)
- {
- /* intentionally empty */
- };
-
- virtual void Execute() const
- {
- m_gameobj->UpdateIPO(
- m_curtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- };
-
-};
KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
const STR_String& propname,
@@ -101,7 +67,8 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
bool recurse,
int acttype,
bool ipo_as_force,
- bool force_ipo_local,
+ bool ipo_add,
+ bool ipo_local,
PyTypeObject* T)
: SCA_IActuator(gameobj,T),
m_bNegativeEvent(false),
@@ -112,7 +79,8 @@ KX_IpoActuator::KX_IpoActuator(SCA_IObject* gameobj,
m_direction(1),
m_propname(propname),
m_ipo_as_force(ipo_as_force),
- m_force_ipo_local(force_ipo_local),
+ m_ipo_add(ipo_add),
+ m_ipo_local(ipo_local),
m_type((IpoActType)acttype)
{
m_starttime = -2.0*fabs(m_endframe - m_startframe) - 1.0;
@@ -160,7 +128,7 @@ bool KX_IpoActuator::ClampLocalTime()
void KX_IpoActuator::SetStartTime(float curtime)
{
- float direction = m_startframe < m_endframe ? 1.0 : -1.0;
+ float direction = m_startframe < m_endframe ? 1.0f : -1.0f;
curtime = curtime - KX_KetsjiEngine::GetSuspendedDelta();
if (m_direction > 0)
@@ -195,31 +163,26 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
// maybe there are events for us in the queue !
bool bNegativeEvent = false;
int numevents = 0;
+ bool bIpoStart = false;
if (frame)
{
numevents = m_events.size();
- for (vector<CValue*>::iterator i=m_events.end(); !(i==m_events.begin());)
- {
- --i;
- if ((*i)->GetNumber() == 0.0f)
- bNegativeEvent = true;
-
- (*i)->Release();
- }
- m_events.clear();
+ bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
}
- double start_smaller_then_end = ( m_startframe < m_endframe ? 1.0 : -1.0);
+ float start_smaller_then_end = ( m_startframe < m_endframe ? 1.0f : -1.0f);
bool result=true;
if (!bNegativeEvent)
{
- if (m_starttime < -2.0*start_smaller_then_end*(m_endframe - m_startframe))
+ if (m_starttime < -2.0f*start_smaller_then_end*(m_endframe - m_startframe))
{
// start for all Ipo, initial start for LOOP_STOP
m_starttime = curtime - KX_KetsjiEngine::GetSuspendedDelta();
m_bIpoPlaying = true;
+ bIpoStart = true;
}
}
@@ -230,7 +193,7 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
{
// Check if playing forwards. result = ! finished
- if (start_smaller_then_end > 0.0)
+ if (start_smaller_then_end > 0.f)
result = (m_localtime < m_endframe && m_bIpoPlaying);
else
result = (m_localtime > m_endframe && m_bIpoPlaying);
@@ -241,14 +204,10 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
/* Perform clamping */
ClampLocalTime();
-
- CIpoAction ipoaction(
- (KX_GameObject*)GetParent(),
- m_localtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- GetParent()->Execute(ipoaction);
+
+ if (bIpoStart)
+ ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
+ ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
} else
{
m_localtime=m_startframe;
@@ -270,13 +229,9 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
m_direction = -m_direction;
}
- CIpoAction ipoaction(
- (KX_GameObject*) GetParent(),
- m_localtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- GetParent()->Execute(ipoaction);
+ if (bIpoStart && m_direction > 0)
+ ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
+ ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
break;
}
case KX_ACT_IPO_FLIPPER:
@@ -299,14 +254,10 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
if (ClampLocalTime() && m_localtime == m_startframe)
result = false;
-
- CIpoAction ipoaction(
- (KX_GameObject*) GetParent(),
- m_localtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- GetParent()->Execute(ipoaction);
+
+ if (bIpoStart)
+ ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
+ ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
break;
}
@@ -352,8 +303,12 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
if (!m_bNegativeEvent){
/* Perform wraparound */
SetLocalTime(curtime);
- m_localtime = m_startframe + fmod(m_localtime, m_startframe - m_endframe);
+ if (start_smaller_then_end > 0.f)
+ m_localtime = m_startframe + fmod(m_localtime - m_startframe, m_endframe - m_startframe);
+ else
+ m_localtime = m_startframe - fmod(m_startframe - m_localtime, m_startframe - m_endframe);
SetStartTime(curtime);
+ bIpoStart = true;
}
else
{
@@ -365,13 +320,9 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
}
}
- CIpoAction ipoaction(
- (KX_GameObject*) GetParent(),
- m_localtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- GetParent()->Execute(ipoaction);
+ if (m_bIpoPlaying && bIpoStart)
+ ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
+ ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
break;
}
@@ -391,14 +342,9 @@ bool KX_IpoActuator::Update(double curtime, bool frame)
{
m_localtime = propval->GetNumber();
- CIpoAction ipoaction(
- (KX_GameObject*) GetParent(),
- m_localtime,
- m_recurse,
- m_ipo_as_force,
- m_force_ipo_local);
- GetParent()->Execute(ipoaction);
-
+ if (bIpoStart)
+ ((KX_GameObject*)GetParent())->InitIPO(m_ipo_as_force, m_ipo_add, m_ipo_local);
+ ((KX_GameObject*)GetParent())->UpdateIPO(m_localtime,m_recurse);
} else
{
result = false;
@@ -493,6 +439,10 @@ PyMethodDef KX_IpoActuator::Methods[] = {
METH_VARARGS, SetIpoAsForce_doc},
{"getIpoAsForce", (PyCFunction) KX_IpoActuator::sPyGetIpoAsForce,
METH_VARARGS, GetIpoAsForce_doc},
+ {"setIpoAdd", (PyCFunction) KX_IpoActuator::sPySetIpoAdd,
+ METH_VARARGS, SetIpoAdd_doc},
+ {"getIpoAdd", (PyCFunction) KX_IpoActuator::sPyGetIpoAdd,
+ METH_VARARGS, GetIpoAdd_doc},
{"setType", (PyCFunction) KX_IpoActuator::sPySetType,
METH_VARARGS, SetType_doc},
{"getType", (PyCFunction) KX_IpoActuator::sPyGetType,
@@ -512,11 +462,11 @@ PyObject* KX_IpoActuator::_getattr(const STR_String& attr) {
/* set --------------------------------------------------------------------- */
char KX_IpoActuator::Set_doc[] =
-"set(mode, startframe, endframe, force?)\n"
-"\t - mode: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
+"set(type, startframe, endframe, mode?)\n"
+"\t - type: Play, PingPong, Flipper, LoopStop, LoopEnd or FromProp (string)\n"
"\t - startframe: first frame to use (int)\n"
"\t - endframe : last frame to use (int)\n"
-"\t - force? : interpret this ipo as a force? (KX_TRUE, KX_FALSE)"
+"\t - mode? : special mode (0=normal, 1=interpret location as force, 2=additive)"
"\tSet the properties of the actuator.\n";
PyObject* KX_IpoActuator::PySet(PyObject* self,
PyObject* args,
@@ -543,7 +493,8 @@ PyObject* KX_IpoActuator::PySet(PyObject* self,
m_type = modenum;
m_startframe = startFrame;
m_endframe = stopFrame;
- m_ipo_as_force = PyArgToBool(forceToggle);
+ m_ipo_as_force = forceToggle == 1;
+ m_ipo_add = forceToggle == 2;
break;
default:
; /* error */
@@ -641,6 +592,8 @@ PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self,
}
m_ipo_as_force = PyArgToBool(boolArg);
+ if (m_ipo_as_force)
+ m_ipo_add = false;
Py_Return;
}
@@ -654,6 +607,36 @@ PyObject* KX_IpoActuator::PyGetIpoAsForce(PyObject* self,
return BoolToPyArg(m_ipo_as_force);
}
+/* 6. setIpoAsForce: */
+char KX_IpoActuator::SetIpoAdd_doc[] =
+"setIpoAdd(add?)\n"
+"\t - add? : add flag (KX_TRUE, KX_FALSE)\n"
+"\tSet whether to interpret the ipo as additive rather than absolute.\n";
+PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int boolArg;
+
+ if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ return NULL;
+ }
+
+ m_ipo_add = PyArgToBool(boolArg);
+ if (m_ipo_add)
+ m_ipo_as_force = false;
+
+ Py_Return;
+}
+/* 7. getIpoAsForce: */
+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) {
+ return BoolToPyArg(m_ipo_add);
+}
+
/* 8. setType: */
char KX_IpoActuator::SetType_doc[] =
"setType(mode)\n"
@@ -701,7 +684,7 @@ PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self,
return NULL;
}
- m_force_ipo_local = PyArgToBool(boolArg);
+ m_ipo_local = PyArgToBool(boolArg);
Py_Return;
}
@@ -713,7 +696,7 @@ char KX_IpoActuator::GetForceIpoActsLocal_doc[] =
PyObject* KX_IpoActuator::PyGetForceIpoActsLocal(PyObject* self,
PyObject* args,
PyObject* kwds) {
- return BoolToPyArg(m_force_ipo_local);
+ return BoolToPyArg(m_ipo_local);
}
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h
index 79e8daa3f87..ae554fb0fce 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.h
+++ b/source/gameengine/Ketsji/KX_IpoActuator.h
@@ -75,8 +75,11 @@ protected:
/** Interpret the ipo as a force? */
bool m_ipo_as_force;
- /** Apply a force-ipo locally? */
- bool m_force_ipo_local;
+ /** Add Ipo curve to current loc/rot/scale */
+ bool m_ipo_add;
+
+ /** The Ipo curve is applied in local coordinates */
+ bool m_ipo_local;
bool m_bIpoPlaying;
@@ -113,7 +116,8 @@ public:
bool recurse,
int acttype,
bool ipo_as_force,
- bool force_ipo_local,
+ bool ipo_add,
+ bool ipo_local,
PyTypeObject* T=&Type);
virtual ~KX_IpoActuator() {};
@@ -144,6 +148,8 @@ public:
KX_PYMETHOD_DOC(KX_IpoActuator,GetEnd);
KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAsForce);
KX_PYMETHOD_DOC(KX_IpoActuator,GetIpoAsForce);
+ KX_PYMETHOD_DOC(KX_IpoActuator,SetIpoAdd);
+ KX_PYMETHOD_DOC(KX_IpoActuator,GetIpoAdd);
KX_PYMETHOD_DOC(KX_IpoActuator,SetType);
KX_PYMETHOD_DOC(KX_IpoActuator,GetType);
KX_PYMETHOD_DOC(KX_IpoActuator,SetForceIpoActsLocal);
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp
index 5c433cb68b1..8b379bcd44f 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp
@@ -77,6 +77,12 @@ CValue* KX_ParentActuator::GetReplica()
bool KX_ParentActuator::Update()
{
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
KX_GameObject *obj = (KX_GameObject*) GetParent();
KX_Scene *scene = PHY_GetActiveScene();
switch (m_mode) {
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index fd4b96b6a92..065800379d8 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -601,6 +601,8 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
}
}
}
+ // ready to set initial state
+ newobj->ResetState();
}
diff --git a/source/gameengine/SceneGraph/SG_Controller.h b/source/gameengine/SceneGraph/SG_Controller.h
index d65a2f0c256..c32885b915f 100644
--- a/source/gameengine/SceneGraph/SG_Controller.h
+++ b/source/gameengine/SceneGraph/SG_Controller.h
@@ -101,7 +101,9 @@ public:
enum SG_Controller_option {
SG_CONTR_NODEF = 0,
SG_CONTR_IPO_IPO_AS_FORCE,
- SG_CONTR_IPO_FORCES_ACT_LOCAL,
+ SG_CONTR_IPO_IPO_ADD,
+ SG_CONTR_IPO_LOCAL,
+ SG_CONTR_IPO_RESET,
SG_CONTR_CAMIPO_LENS,
SG_CONTR_CAMIPO_CLIPEND,
SG_CONTR_CAMIPO_CLIPSTART,