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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMaxime Curioni <maxime.curioni@gmail.com>2008-07-12 09:02:47 +0400
committerMaxime Curioni <maxime.curioni@gmail.com>2008-07-12 09:02:47 +0400
commit8398730043faeb9af860ca7a408a5a4ba49b46f1 (patch)
treebc38242ec4333e81f5aea3205fffa21f669abffe /source
parentd124d3c5cdfdc9d470a4734281396b97c4d3afb5 (diff)
soc-2008-mxcurioni: merge with trunk - rev 15540
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_bmeshCustomData.h4
-rw-r--r--source/blender/blenkernel/BKE_customdata.h6
-rw-r--r--source/blender/blenkernel/intern/BME_Customdata.c9
-rw-r--r--source/blender/blenkernel/intern/BME_conversions.c271
-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/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/customdata.c117
-rw-r--r--source/blender/blenkernel/intern/library.c60
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenkernel/intern/particle.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c10
-rw-r--r--source/blender/blenkernel/intern/pointcache.c16
-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/blenlib/intern/storage.c1
-rw-r--r--source/blender/blenlib/intern/util.c1
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp41
-rw-r--r--source/blender/include/BDR_drawobject.h1
-rw-r--r--source/blender/include/BIF_editarmature.h2
-rw-r--r--source/blender/include/BSE_sequence.h2
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h10
-rw-r--r--source/blender/makesdna/DNA_space_types.h11
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_gamma.c2
-rw-r--r--source/blender/python/api2_2x/sceneSequence.c74
-rw-r--r--source/blender/radiosity/intern/source/radrender.c15
-rw-r--r--source/blender/render/intern/source/convertblender.c1
-rw-r--r--source/blender/src/buttons_logic.c98
-rw-r--r--source/blender/src/buttons_object.c2
-rw-r--r--source/blender/src/buttons_scene.c2
-rw-r--r--source/blender/src/buttons_shading.c6
-rw-r--r--source/blender/src/drawarmature.c17
-rw-r--r--source/blender/src/drawimage.c2
-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/editnla.c35
-rw-r--r--source/blender/src/editsima.c16
-rw-r--r--source/blender/src/edittime.c4
-rw-r--r--source/blender/src/header_image.c23
-rw-r--r--source/blender/src/header_view3d.c15
-rw-r--r--source/blender/src/sequence.c10
-rw-r--r--source/blender/src/space.c21
-rw-r--r--source/blender/src/transform_conversions.c9
-rw-r--r--source/blender/src/usiblender.c2
-rw-r--r--source/blender/src/view.c2
-rw-r--r--source/blender/src/vpaint.c36
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp2
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp30
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.h5
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp121
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.cpp174
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.h14
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.h11
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp61
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h6
-rw-r--r--source/gameengine/Converter/BL_SkinMeshObject.cpp84
-rw-r--r--source/gameengine/Converter/BL_SkinMeshObject.h94
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp8
-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/BL_BlenderShader.cpp80
-rw-r--r--source/gameengine/Ketsji/BL_BlenderShader.h15
-rw-r--r--source/gameengine/Ketsji/BL_Material.cpp6
-rw-r--r--source/gameengine/Ketsji/BL_Material.h7
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp100
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp92
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h17
-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_KetsjiEngine.cpp46
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.h1
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp80
-rw-r--r--source/gameengine/Ketsji/KX_Light.h16
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp43
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h8
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp16
-rw-r--r--source/gameengine/PyDoc/BL_ActionActuator.py15
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp16
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h59
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp51
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp61
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h6
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp25
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h8
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp102
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp94
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h8
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.cpp42
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.h24
-rw-r--r--source/gameengine/SceneGraph/SG_Controller.h4
-rw-r--r--source/kernel/gen_system/GEN_HashedPtr.h1
-rw-r--r--source/kernel/gen_system/GEN_Map.h18
108 files changed, 2017 insertions, 1178 deletions
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..e84c7d30956 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,9 @@ 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);
+
+/*BMesh specific customdata stuff*/
+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, int total);
+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..daf0de5b748 100644
--- a/source/blender/blenkernel/intern/BME_conversions.c
+++ b/source/blender/blenkernel/intern/BME_conversions.c
@@ -55,14 +55,200 @@
#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);
+
+/*merge these functions*/
+static void BME_DMcorners_to_loops(BME_Mesh *bm, CustomData *facedata, int index, 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_get_layer_n(facedata, CD_MTFACE, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+
+ texpoly->tpage = texface[index].tpage;
+ texpoly->flag = texface[index].flag;
+ texpoly->transp = texface[index].transp;
+ texpoly->mode = texface[index].mode;
+ texpoly->tile = texface[index].tile;
+ texpoly->unwrap = texface[index].unwrap;
+
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+ mloopuv->uv[0] = texface[index].uv[j][0];
+ mloopuv->uv[1] = texface[index].uv[j][1];
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
+
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_get_layer_n(facedata, CD_MCOL, i);
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+ mloopcol->r = mcol[(index*4)+j].r;
+ mloopcol->g = mcol[(index*4)+j].g;
+ mloopcol->b = mcol[(index*4)+j].b;
+ mloopcol->a = mcol[(index*4)+j].a;
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
+}
+
+static void BME_DMloops_to_corners(BME_Mesh *bm, CustomData *facedata, int index, 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_get_layer_n(facedata, CD_MTFACE, i);
+ texpoly = CustomData_bmesh_get_n(&bm->pdata, f->data, CD_MTEXPOLY, i);
+
+ texface[index].tpage = texpoly->tpage;
+ texface[index].flag = texpoly->flag;
+ texface[index].transp = texpoly->transp;
+ texface[index].mode = texpoly->mode;
+ texface[index].tile = texpoly->tile;
+ texface[index].unwrap = texpoly->unwrap;
+
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPUV, i);
+ texface[index].uv[j][0] = mloopuv->uv[0];
+ texface[index].uv[j][1] = mloopuv->uv[1];
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+
+ }
+ for(i=0; i < numCol; i++){
+ mcol = CustomData_get_layer_n(facedata,CD_MCOL, i);
+ j = 0;
+ l = f->loopbase;
+ do{
+ mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->data, CD_MLOOPCOL, i);
+ mcol[(index*4) + j].r = mloopcol->r;
+ mcol[(index*4) + j].g = mloopcol->g;
+ mcol[(index*4) + j].b = mloopcol->b;
+ mcol[(index*4) + j].a = mloopcol->a;
+ j++;
+ l = l->next;
+ }while(l!=f->loopbase);
+ }
}
+
+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 +260,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 +285,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 +304,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 +336,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 +357,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 +365,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,0);
+ 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 +403,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 +431,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);
}
}
@@ -248,7 +453,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
MVert *mvert, *mv;
MEdge *medge, *me;
MFace *mface, *mf;
- int totface,totedge,totvert,i,len;
+ int totface,totedge,totvert,i,len, numTex, numCol;
BME_Vert *v1=NULL,*v2=NULL, **vert_array;
BME_Edge *e=NULL;
BME_Poly *f=NULL;
@@ -256,6 +461,22 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
EdgeHash *edge_hash = BLI_edgehash_new();
bm = BME_make_mesh(allocsize);
+ /*copy custom data layout*/
+ CustomData_copy(&dm->vertData, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&dm->edgeData, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
+ CustomData_copy(&dm->faceData, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
+
+ /*copy face corner data*/
+ CustomData_to_bmeshpoly(&dm->faceData, &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);
+
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
totface = dm->getNumFaces(dm);
@@ -272,6 +493,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
vert_array[i] = v1;
v1->flag = mv->flag;
v1->bweight = mv->bweight/255.0f;
+ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v1->data);
}
/*add edges*/
for(i=0,me = medge; i < totedge;i++,me++){
@@ -282,6 +504,7 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
e->bweight = me->bweight/255.0f;
e->flag = (unsigned char)me->flag;
BLI_edgehash_insert(edge_hash,me->v1,me->v2,e);
+ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->data);
}
/*add faces.*/
for(i=0,mf = mface; i < totface;i++,mf++){
@@ -305,6 +528,8 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
f = BME_MF(bm,v1,v2,edar,len);
f->mat_nr = mf->mat_nr;
f->flag = mf->flag;
+ CustomData_to_bmesh_block(&dm->faceData,&bm->pdata,i,&f->data);
+ BME_DMcorners_to_loops(bm, &dm->faceData,i,f, numCol,numTex);
}
BME_model_end(bm);
@@ -318,7 +543,7 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
MFace *mface, *mf;
MEdge *medge, *me;
MVert *mvert, *mv;
- int totface,totedge,totvert,i,bmeshok,len;
+ int totface,totedge,totvert,i,bmeshok,len, numTex, numCol;
BME_Vert *v1=NULL;
BME_Edge *e=NULL, *oe=NULL;
@@ -354,12 +579,21 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
/*convert back to mesh*/
result = CDDM_from_template(dm,totvert,totedge,totface);
+ CustomData_merge(&bm->vdata, &result->vertData, CD_MASK_BMESH, CD_CALLOC, totvert);
+ CustomData_merge(&bm->edata, &result->edgeData, CD_MASK_BMESH, CD_CALLOC, totedge);
+ CustomData_merge(&bm->pdata, &result->faceData, CD_MASK_BMESH, CD_CALLOC, totface);
+ CustomData_from_bmeshpoly(&result->faceData, &bm->pdata, &bm->ldata,totface);
+ numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
+ numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
+
+
/*Make Verts*/
mvert = CDDM_get_verts(result);
for(i=0,v1=bm->verts.first,mv=mvert;v1;v1=v1->next,i++,mv++){
VECCOPY(mv->co,v1->co);
mv->flag = (unsigned char)v1->flag;
mv->bweight = (char)(255.0*v1->bweight);
+ CustomData_from_bmesh_block(&bm->vdata, &result->vertData, &v1->data, i);
}
medge = CDDM_get_edges(result);
i=0;
@@ -377,6 +611,7 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
me->crease = (char)(255.0*e->crease);
me->bweight = (char)(255.0*e->bweight);
me->flag = e->flag;
+ CustomData_from_bmesh_block(&bm->edata, &result->edgeData, &e->data, i);
me++;
i++;
}
@@ -398,9 +633,11 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
if(mf->v3 == 0 || (len == 4 && mf->v4 == 0)){
test_index_face(mf, NULL, i, len);
}
- i++;
mf->mat_nr = (unsigned char)f->mat_nr;
mf->flag = (unsigned char)f->flag;
+ CustomData_from_bmesh_block(&bm->pdata, &result->faceData, &f->data, i);
+ BME_DMloops_to_corners(bm, &result->faceData, i, f,numCol,numTex);
+ i++;
}
}
}
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/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 30405660658..4d3f9143b85 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1052,7 +1052,7 @@ void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
/* store vertex indices in tmp union */
for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
- ev->tmp.l = (long) i++;
+ ev->tmp.l = (long) i;
for( ; ee; ee = ee->next, ++edge_r) {
edge_r->crease = (unsigned char) (ee->crease*255.0f);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 4880a246e1c..501293ecd81 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}
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
@@ -480,7 +554,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;
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)
{
@@ -1456,6 +1534,36 @@ void CustomData_from_em_block(const CustomData *source, CustomData *dest,
}
/*Bmesh functions*/
+/*needed to convert to/from different face reps*/
+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 total){
+ 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), total);
+ }
+ 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), total);
+ }
+}
+
+
+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;
@@ -1484,7 +1592,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;
}
@@ -1601,7 +1709,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 7c50b409693..c3dddf06e7c 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/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index a0841bb9f03..f13f8ef0298 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -4920,7 +4920,7 @@ static void waveModifier_deformVertsEM(
if(!wmd->texture && !wmd->defgrp_name[0] && !(wmd->flag & MOD_WAVE_NORM))
dm = derivedData;
- else if(derivedData) dm = derivedData;
+ else if(derivedData) dm = CDDM_copy(derivedData);
else dm = CDDM_from_editmesh(editData, ob->data);
if(wmd->flag & MOD_WAVE_NORM) {
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 18fca5439ef..24a3d348ae7 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1371,7 +1371,7 @@ void psys_particle_on_shape(int distr, int index, float *fuv, float *vec, float
/************************************************/
void psys_particle_on_emitter(Object *ob, ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor){
if(psmd){
- if(psmd->psys->part->distr==PART_DISTR_GRID){
+ if(psmd->psys->part->distr==PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT){
if(vec){
VECCOPY(vec,fuv);
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 458171cc232..f70648965f4 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -168,7 +168,7 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
int i, totpart, totsaved = 0;
if(new_totpart<0) {
- if(psys->part->distr==PART_DISTR_GRID) {
+ if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
totpart= psys->part->grid_res;
totpart*=totpart*totpart;
}
@@ -1056,7 +1056,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
dm= CDDM_from_mesh((Mesh*)ob->data, ob);
/* special handling of grid distribution */
- if(part->distr==PART_DISTR_GRID){
+ if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
distribute_particles_in_grid(dm,psys);
dm->release(dm);
return 0;
@@ -1600,7 +1600,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
NormalQuat(pa->r_rot);
- if(part->distr!=PART_DISTR_GRID){
+ if(part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
/* any unique random number will do (r_ave[0]) */
if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
pa->flag |= PARS_UNEXIST;
@@ -4515,7 +4515,7 @@ void psys_changed_type(ParticleSystem *psys)
if(part->from == PART_FROM_PARTICLE) {
if(part->type != PART_REACTOR)
part->from = PART_FROM_FACE;
- if(part->distr == PART_DISTR_GRID)
+ if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
part->distr = PART_DISTR_JIT;
}
@@ -4710,7 +4710,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
oldtotpart = psys->totpart;
oldtotchild = psys->totchild;
- if(part->distr == PART_DISTR_GRID)
+ if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
totpart = part->grid_res*part->grid_res*part->grid_res;
else
totpart = psys->part->totpart;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 57ecffbb796..43805959e62 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -459,9 +459,10 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
PTCacheID pid;
ParticleSystem *psys;
ModifierData *md;
- int reset;
+ int reset, skip;
reset= 0;
+ skip= 0;
if(ob->soft) {
BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
@@ -469,11 +470,18 @@ int BKE_ptcache_object_reset(Object *ob, int mode)
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- BKE_ptcache_id_from_particles(&pid, ob, psys);
- reset |= BKE_ptcache_id_reset(&pid, mode);
-
+ /* Baked softbody hair has to be checked first, because we don't want to reset */
+ /* particles or softbody in that case -jahka */
if(psys->soft) {
BKE_ptcache_id_from_softbody(&pid, ob, psys->soft);
+ if(mode == PSYS_RESET_ALL || !(psys->part->type == PART_HAIR && (pid.cache->flag & PTCACHE_BAKED)))
+ reset |= BKE_ptcache_id_reset(&pid, mode);
+ else
+ skip = 1;
+ }
+
+ if(skip == 0) {
+ BKE_ptcache_id_from_particles(&pid, ob, psys);
reset |= BKE_ptcache_id_reset(&pid, mode);
}
}
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/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index ca7a376d3a2..fbcc56ac21d 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -382,6 +382,7 @@ void BLI_adddirstrings()
pwuser = getpwuid(files[num].s.st_uid);
if ( pwuser ) {
strcpy(files[num].owner, pwuser->pw_name);
+ free(pwuser);
} else {
sprintf(files[num].owner, "%d", files[num].s.st_uid);
}
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index 5a85fbfc375..48ebf770e1b 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -1722,6 +1722,7 @@ void BLI_where_am_i(char *fullname, const char *name)
path = br_find_exe( NULL );
if (path) {
strcpy(fullname, path);
+ free(path);
return;
}
#endif
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index b59908fef39..fe352610a40 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -842,7 +842,7 @@ typedef struct RGBA
} RGBA;
-#if 0
+/* debug only */
static void exr_print_filecontents(InputFile *file)
{
const ChannelList &channels = file->header().channels();
@@ -853,7 +853,27 @@ static void exr_print_filecontents(InputFile *file)
printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type);
}
}
-#endif
+
+/* for non-multilayer, map R G B A channel names to something that's in this file */
+static const char *exr_rgba_channelname(InputFile *file, const char *chan)
+{
+ const ChannelList &channels = file->header().channels();
+
+ for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
+ {
+ const Channel &channel = i.channel();
+ const char *str= i.name();
+ int len= strlen(str);
+ if(len) {
+ if(BLI_strcasecmp(chan, str+len-1)==0) {
+ return str;
+ }
+ }
+ }
+ return chan;
+}
+
+
static int exr_has_zbuffer(InputFile *file)
{
@@ -896,7 +916,8 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
//printf("OpenEXR-load: image data window %d %d %d %d\n",
// dw.min.x, dw.min.y, dw.max.x, dw.max.y);
- // exr_print_filecontents(file);
+ if(0) // debug
+ exr_print_filecontents(file);
is_multi= exr_is_renderresult(file);
@@ -935,11 +956,15 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags)
/* but, since we read y-flipped (negative y stride) we move to last scanline */
first+= 4*(height-1)*width;
- frameBuffer.insert ("R", Slice (FLOAT, (char *) first, xstride, ystride));
- frameBuffer.insert ("G", Slice (FLOAT, (char *) (first+1), xstride, ystride));
- frameBuffer.insert ("B", Slice (FLOAT, (char *) (first+2), xstride, ystride));
- /* 1.0 is fill value */
- frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f));
+ frameBuffer.insert ( exr_rgba_channelname(file, "R"),
+ Slice (FLOAT, (char *) first, xstride, ystride));
+ frameBuffer.insert ( exr_rgba_channelname(file, "G"),
+ Slice (FLOAT, (char *) (first+1), xstride, ystride));
+ frameBuffer.insert ( exr_rgba_channelname(file, "B"),
+ Slice (FLOAT, (char *) (first+2), xstride, ystride));
+
+ frameBuffer.insert ( exr_rgba_channelname(file, "A"),
+ Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f)); /* 1.0 is fill value */
if(exr_has_zbuffer(file))
{
diff --git a/source/blender/include/BDR_drawobject.h b/source/blender/include/BDR_drawobject.h
index 3f9a6e438cc..de28db64c3b 100644
--- a/source/blender/include/BDR_drawobject.h
+++ b/source/blender/include/BDR_drawobject.h
@@ -63,6 +63,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/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h
index 15a9218b735..0d96de7be60 100644
--- a/source/blender/include/BSE_sequence.h
+++ b/source/blender/include/BSE_sequence.h
@@ -92,6 +92,8 @@ void update_changed_seq_and_deps(struct Sequence *seq, int len_change, int ibuf_
struct RenderResult;
void do_render_seq(struct RenderResult *rr, int cfra);
+int seq_can_blend(struct Sequence *seq);
+
#define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_HD_SOUND || seq->type==SEQ_RAM_SOUND || seq->type==SEQ_IMAGE)
#endif
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 3cf80a4efa6..a467722e8e1 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -51,8 +51,9 @@ typedef struct bActionActuator {
int sta, end; /* Start & End frames */
char name[32]; /* For property-driven playback */
char frameProp[32]; /* Set this property to the actions current frame */
- int blendin; /* Number of frames of blending */
- short priority; /* Execution priority */
+ short blendin; /* Number of frames of blending */
+ short priority; /* Execution priority */
+ short end_reset; /* Ending the actuator (negative pulse) wont reset the the action to its starting frame */
short strideaxis; /* Displacement axis */
float stridelength; /* Displacement incurred by cycle */
} bActionActuator;
@@ -339,8 +340,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/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index af60f9ca713..bc30a12ff27 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -232,8 +232,9 @@ typedef struct SpaceImage {
short imanr;
short curtile; /* the currently active tile of the image when tile is enabled, is kept in sync with the active faces tile */
int flag;
+ short selectmode;
short imtypenr, lock;
- short pin, pad2;
+ short pin;
float zoom;
char dt_uv; /* UV draw type */
char sticky; /* sticky selection type */
@@ -496,6 +497,12 @@ typedef struct SpaceImaSel {
#define SI_STICKY_DISABLE 1
#define SI_STICKY_VERTEX 2
+/* SpaceImage->selectmode */
+#define SI_SELECT_VERTEX 0
+#define SI_SELECT_EDGE 1 /* not implemented */
+#define SI_SELECT_FACE 2
+#define SI_SELECT_ISLAND 3
+
/* SpaceImage->flag */
#define SI_BE_SQUARE 1<<0
#define SI_EDITTILE 1<<1
@@ -503,7 +510,7 @@ typedef struct SpaceImaSel {
#define SI_DRAWTOOL 1<<3
#define SI_DEPRECATED1 1<<4 /* stick UVs to others in the same location */
#define SI_DRAWSHADOW 1<<5
-#define SI_SELACTFACE 1<<6
+#define SI_SELACTFACE 1<<6 /* deprecated */
#define SI_DEPRECATED2 1<<7
#define SI_DEPRECATED3 1<<8 /* stick UV selection to mesh vertex (UVs wont always be touching) */
#define SI_COORDFLOATS 1<<9
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c
index ff9e2b716ce..e77de3726cb 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_gamma.c
@@ -47,7 +47,7 @@ static void do_gamma(bNode *node, float *out, float *in, float *fac)
int i=0;
for(i=0; i<3; i++) {
/* check for negative to avoid nan's */
- out[i] = (in[0] > 0.0f)? pow(in[i],fac[0]): in[0];
+ out[i] = (in[i] > 0.0f)? pow(in[i],fac[0]): in[i];
}
out[3] = in[3];
}
diff --git a/source/blender/python/api2_2x/sceneSequence.c b/source/blender/python/api2_2x/sceneSequence.c
index 56821980cd2..0d3ad3fcb44 100644
--- a/source/blender/python/api2_2x/sceneSequence.c
+++ b/source/blender/python/api2_2x/sceneSequence.c
@@ -81,6 +81,7 @@ returns None if notfound.\nIf 'name' is not specified, it returns a list of all
static PyObject *Sequence_copy( BPy_Sequence * self );
static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args );
static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args );
+static PyObject *Sequence_rebuildProxy( BPy_Sequence * self );
static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args );
static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args );
@@ -96,6 +97,8 @@ static PyMethodDef BPy_Sequence_methods[] = {
"() - Return a copy of the sequence containing the same objects."},
{"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS,
"() - Return a copy of the sequence containing the same objects."},
+ {"rebuildProxy", ( PyCFunction ) Sequence_rebuildProxy, METH_VARARGS,
+ "() - Rebuild the active strip's Proxy."},
{NULL, NULL, 0, NULL}
};
@@ -309,6 +312,7 @@ static PyObject *Sequence_copy( BPy_Sequence * self )
Py_RETURN_NONE;
}
+
/*****************************************************************************/
/* PythonTypeObject callback function prototypes */
/*****************************************************************************/
@@ -383,8 +387,6 @@ static PyObject *SceneSeq_nextIter( BPy_Sequence * self )
}
-
-
static PyObject *Sequence_getName( BPy_Sequence * self )
{
return PyString_FromString( self->seq->name+2 );
@@ -403,11 +405,13 @@ static int Sequence_setName( BPy_Sequence * self, PyObject * value )
return 0;
}
+
static PyObject *Sequence_getProxyDir( BPy_Sequence * self )
{
return PyString_FromString( self->seq->strip->proxy ? self->seq->strip->proxy->dir : "" );
}
+
static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value )
{
char *name = NULL;
@@ -430,6 +434,14 @@ static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value )
}
+static PyObject *Sequence_rebuildProxy( BPy_Sequence * self )
+{
+ if (self->seq->strip->proxy)
+ seq_proxy_rebuild(self->seq);
+ Py_RETURN_NONE;
+}
+
+
static PyObject *Sequence_getSound( BPy_Sequence * self )
{
if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound)
@@ -622,6 +634,54 @@ static int Sequence_setImages( BPy_Sequence * self, PyObject *value )
return 0;
}
+static PyObject *M_Sequence_BlendModesDict( void )
+{
+ PyObject *M = PyConstant_New( );
+
+ if( M ) {
+ BPy_constant *d = ( BPy_constant * ) M;
+ PyConstant_Insert( d, "CROSS", PyInt_FromLong( SEQ_CROSS ) );
+ PyConstant_Insert( d, "ADD", PyInt_FromLong( SEQ_ADD ) );
+ PyConstant_Insert( d, "SUBTRACT", PyInt_FromLong( SEQ_SUB ) );
+ PyConstant_Insert( d, "ALPHAOVER", PyInt_FromLong( SEQ_ALPHAOVER ) );
+ PyConstant_Insert( d, "ALPHAUNDER", PyInt_FromLong( SEQ_ALPHAUNDER ) );
+ PyConstant_Insert( d, "GAMMACROSS", PyInt_FromLong( SEQ_GAMCROSS ) );
+ PyConstant_Insert( d, "MULTIPLY", PyInt_FromLong( SEQ_MUL ) );
+ PyConstant_Insert( d, "OVERDROP", PyInt_FromLong( SEQ_OVERDROP ) );
+ PyConstant_Insert( d, "PLUGIN", PyInt_FromLong( SEQ_PLUGIN ) );
+ PyConstant_Insert( d, "WIPE", PyInt_FromLong( SEQ_WIPE ) );
+ PyConstant_Insert( d, "GLOW", PyInt_FromLong( SEQ_GLOW ) );
+ PyConstant_Insert( d, "TRANSFORM", PyInt_FromLong( SEQ_TRANSFORM ) );
+ PyConstant_Insert( d, "COLOR", PyInt_FromLong( SEQ_COLOR ) );
+ PyConstant_Insert( d, "SPEED", PyInt_FromLong( SEQ_SPEED ) );
+ }
+ return M;
+}
+
+static PyObject *Sequence_getBlendMode( BPy_Sequence * self )
+{
+ return PyInt_FromLong( self->seq->blend_mode );
+}
+
+static int Sequence_setBlendMode( BPy_Sequence * self, PyObject * value )
+{
+ struct Sequence *seq= self->seq;
+ int number = PyInt_AsLong( value );
+
+ if( number==-1 && PyErr_Occurred() )
+ return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
+
+ if ( !seq_can_blend(seq) )
+ return EXPP_ReturnIntError( PyExc_AttributeError, "this sequence type dosnt support blending" );
+
+ if (number<SEQ_EFFECT || number>SEQ_EFFECT_MAX)
+ return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
+
+ seq->blend_mode=number;
+
+ return 0;
+}
+
/*
* get floating point attributes
*/
@@ -836,7 +896,11 @@ static PyGetSetDef BPy_Sequence_getseters[] = {
(getter)Sequence_getImages, (setter)Sequence_setImages,
"Sequence scene",
NULL},
-
+ {"blendMode",
+ (getter)Sequence_getBlendMode, (setter)Sequence_setBlendMode,
+ "Sequence Blend Mode",
+ NULL},
+
{"type",
(getter)getIntAttr, (setter)NULL,
"",
@@ -1131,6 +1195,7 @@ PyObject *M_Sequence_Get( PyObject * self, PyObject * args )
/*****************************************************************************/
PyObject *Sequence_Init( void )
{
+ PyObject *BlendModesDict = M_Sequence_BlendModesDict( );
PyObject *submodule;
if( PyType_Ready( &Sequence_Type ) < 0 )
return NULL;
@@ -1142,6 +1207,9 @@ PyObject *Sequence_Init( void )
"The Blender Sequence module\n\n\
This module provides access to **Sequence Data** in Blender.\n" );
+ if( BlendModesDict )
+ PyModule_AddObject( submodule, "BlendModes", BlendModesDict );
+
/*Add SUBMODULES to the module*/
/*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
return submodule;
diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c
index e5ef1e9a4a2..68b5fa81f43 100644
--- a/source/blender/radiosity/intern/source/radrender.c
+++ b/source/blender/radiosity/intern/source/radrender.c
@@ -369,9 +369,18 @@ printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch);
if(vlr->mat->mode & MA_RADIO) {
/* during render, vlr->n gets flipped/corrected, we cannot have that */
- if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
- else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
-
+ if (obr->ob->transflag & OB_NEG_SCALE){
+ /* The object has negative scale that will cause the normals to flip.
+ To counter this unwanted normal flip, swap vertex 2 and 4 for a quad
+ or vertex 2 and 3 (see flip_face) for a triangle in the call to CalcNormFloat4
+ in order to flip the normals back to the way they were in the original mesh. */
+ if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v4->co, vlr->v3->co, vlr->v2->co, rf->norm);
+ else CalcNormFloat(vlr->v1->co, vlr->v3->co, vlr->v2->co, rf->norm);
+ }else{
+ if(vlr->v4) CalcNormFloat4(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co, rf->norm);
+ else CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, rf->norm);
+ }
+
rf->totrad[0]= vlr->mat->emit*vlr->mat->r;
rf->totrad[1]= vlr->mat->emit*vlr->mat->g;
rf->totrad[2]= vlr->mat->emit*vlr->mat->b;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index f9ec0e9d843..faa7a68f754 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -204,6 +204,7 @@ void RE_make_stars(Render *re, void (*initfunc)(void),
else stargrid *= 1.0; /* then it draws fewer */
if(re) MTC_Mat4Invert(mat, re->viewmat);
+ else MTC_Mat4One(mat);
/* BOUNDING BOX CALCULATION
* bbox goes from z = loc_near_var | loc_far_var,
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index 1a9e1030688..cc4df06e22d 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -1560,7 +1560,6 @@ static void set_col_actuator(int item, int medium)
static void change_object_actuator(void *act, void *arg)
{
bObjectActuator *oa = act;
- int i;
if (oa->type != oa->otype) {
switch (oa->type) {
@@ -1582,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;
@@ -1679,7 +1690,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
uiDefBut(block, LABEL, 0, "damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
- uiDefButI(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
+ uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
@@ -1758,23 +1769,27 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
#else
str= "Action types %t|Play %x0|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x6";
#endif
- uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, (width-60)/2, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type");
- uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+30 + ((width-60)/2), yco-24, (width-60)/2, 19, &aa->act, "Action name");
+ uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, width/3, 19, &aa->type, 0.0, 0.0, 0.0, 0.0, "Action playback type");
+ uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+10+ (width/3), yco-24, ((width/3)*2) - (20 + 60), 19, &aa->act, "Action name");
+
+ uiDefButBitS(block, TOGN, 1, 0, "Continue", xco+((width/3)*2)+20, yco-24, 60, 19,
+ &aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time");
+
if(aa->type == ACT_ACTION_FROM_PROP)
{
- uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-44, width-60, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position");
+ uiDefBut(block, TEX, 0, "Prop: ",xco+10, yco-44, width-20, 19, aa->name, 0.0, 31.0, 0, 0, "Use this property to define the Action position");
}
else
{
- uiDefButI(block, NUM, 0, "Sta: ",xco+30, yco-44, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame");
- uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-44, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame");
+ uiDefButI(block, NUM, 0, "Sta: ",xco+10, yco-44, (width-20)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame");
+ uiDefButI(block, NUM, 0, "End: ",xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame");
}
- uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-64, (width-60)/2, 19, &aa->blendin, 0.0, MAXFRAMEF, 0.0, 0.0, "Number of frames of motion blending");
- uiDefButS(block, NUM, 0, "Priority: ", xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack");
+ uiDefButS(block, NUM, 0, "Blendin: ", xco+10, yco-64, (width-20)/2, 19, &aa->blendin, 0.0, 32767, 0.0, 0.0, "Number of frames of motion blending");
+ uiDefButS(block, NUM, 0, "Priority: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack");
- uiDefBut(block, TEX, 0, "FrameProp: ",xco+30, yco-84, width-60, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign this property this actions current frame number");
+ uiDefBut(block, TEX, 0, "FrameProp: ",xco+10, yco-84, width-20, 19, aa->frameProp, 0.0, 31.0, 0, 0, "Assign this property this actions current frame number");
#ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
@@ -1800,42 +1815,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");
+ "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");
-
- 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.");
- }
-
+ "End frame, (subtract 1 to match blenders frame numbers)");
}
+ 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;
}
@@ -1967,7 +1989,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
glRects(xco, yco-ysize, xco+width, yco);
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
- uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object (cant be on an visible layer)");
+ uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object and all its children (cant be on an visible layer)");
uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives");
wval= (width-60)/3;
@@ -2248,7 +2270,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, 31.0, 0, 0, "Use this property to define the Group position");
}
else {
- uiDefButI(block, NUM, 0, "Sta", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame");
+ uiDefButI(block, NUM, 0, "State", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame");
uiDefButI(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame");
}
yco-= ysize;
@@ -3171,7 +3193,7 @@ void logic_buts(void)
uiButSetFunc(but, check_object_state, but, &(ob->state));
}
for (stbit=0; stbit<5; stbit++) {
- but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15)));
+ but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset+15)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15)));
uiButSetFunc(but, check_object_state, but, &(ob->state));
}
}
@@ -3255,7 +3277,7 @@ void logic_buts(void)
uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
- uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "Sta", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
+ uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "State", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
uiBlockEndAlign(block);
for(a=0; a<count; a++) {
@@ -3328,7 +3350,7 @@ void logic_buts(void)
uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
- uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "Sta", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
+ uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "State", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
uiBlockEndAlign(block);
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index ba409723784..ebe770c89e7 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -4812,7 +4812,7 @@ static void object_panel_particle_system(Object *ob)
uiDefBut(block, LABEL, 0, "Basic:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
uiBlockBeginAlign(block);
- if(part->distr==PART_DISTR_GRID)
+ if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT)
uiDefButI(block, NUM, B_PART_ALLOC, "Resol:", butx,(buty-=buth),butw,buth, &part->grid_res, 1.0, 100.0, 0, 0, "The resolution of the particle grid");
else
uiDefButI(block, NUM, B_PART_ALLOC, "Amount:", butx,(buty-=buth),butw,buth, &part->totpart, 0.0, 100000.0, 0, 0, "The total number of particles");
diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c
index f136599519c..a58d44538a2 100644
--- a/source/blender/src/buttons_scene.c
+++ b/source/blender/src/buttons_scene.c
@@ -499,7 +499,7 @@ static char* seq_panel_blend_modes()
so that would collide also.
*/
- if (!(last_seq->type & SEQ_EFFECT)) {
+ if ( seq_can_blend(last_seq) ) {
int i;
for (i = SEQ_EFFECT; i <= SEQ_EFFECT_MAX; i++) {
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index ca6705b2084..1b580381ca5 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -2900,15 +2900,15 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButS(block, MENU, B_LAMPREDRAW, "Falloff %t|Constant %x0|Inverse Linear %x1|Inverse Square %x2|Custom Curve %x3|Lin/Quad Weighted %x4|",
10,150,100,19, &la->falloff_type, 0,0,0,0, "Lamp falloff - intensity decay with distance");
- uiDefButBitS(block, TOG, LA_SPHERE, REDRAWVIEW3D,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value");
+ uiDefButBitS(block, TOG, LA_SPHERE, B_LAMPPRV,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value");
}
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButBitS(block, TOG, LA_LAYER, 0,"Layer", 10,70,100,19,&la->mode, 0, 0, 0, 0, "Illuminates objects in the same layer as the lamp only");
uiDefButBitS(block, TOG, LA_NEG, B_LAMPPRV,"Negative", 10,50,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light");
- uiDefButBitS(block, TOG, LA_NO_DIFF, 0,"No Diffuse", 10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp");
- uiDefButBitS(block, TOG, LA_NO_SPEC, 0,"No Specular", 10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp");
+ uiDefButBitS(block, TOG, LA_NO_DIFF, B_LAMPPRV,"No Diffuse", 10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp");
+ uiDefButBitS(block, TOG, LA_NO_SPEC, B_LAMPPRV,"No Specular", 10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp");
uiBlockEndAlign(block);
uiBlockSetCol(block, TH_AUTO);
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/drawimage.c b/source/blender/src/drawimage.c
index 547de85e856..14849cdd450 100644
--- a/source/blender/src/drawimage.c
+++ b/source/blender/src/drawimage.c
@@ -422,7 +422,7 @@ int draw_uvs_face_check(void)
return 1;
}
} else {
- if (G.sima->flag & SI_SELACTFACE) {
+ if (G.sima->selectmode == SI_SELECT_FACE) {
return 1;
}
}
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 96ba8c71755..045bf292446 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -4620,7 +4620,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);
}
}
@@ -4741,7 +4741,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;
@@ -4943,7 +4943,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);
}
@@ -5090,7 +5090,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);
break;
default:
drawaxes(1.0, flag, OB_ARROWS);
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 2f1cdb8b951..f595a101f63 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -3097,7 +3097,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);
@@ -3319,7 +3319,7 @@ void drawview3d_render(struct View3D *v3d, int winx, int winy, float winmat[][4]
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/editnla.c b/source/blender/src/editnla.c
index d758f34949a..dbc0deecb2c 100644
--- a/source/blender/src/editnla.c
+++ b/source/blender/src/editnla.c
@@ -501,26 +501,47 @@ static void set_active_strip(Object *ob, bActionStrip *act)
{
bActionStrip *strip;
+ /* make sure all other strips are not active */
for (strip = ob->nlastrips.first; strip; strip=strip->next)
strip->flag &= ~ACTSTRIP_ACTIVE;
- if(act) {
+ /* act is new active strip */
+ if (act) {
+ /* set active flag for this strip */
act->flag |= ACTSTRIP_ACTIVE;
-
- if(ob->action!=act->act) {
- if(ob->action) ob->action->id.us--;
- if(act->act->id.lib) {
+
+ /* check if active action will still be the same one */
+ if (ob->action != act->act) {
+ /* clear object's links with its current action (if present) */
+ if (ob->action) {
+ ob->action->id.us--;
+ }
+
+ /* only set object's action to active strip's action if possible */
+ if (act->act->id.lib) {
ob->action= NULL;
}
else {
ob->action= act->act;
id_us_plus(&ob->action->id);
- }
+ }
+
+ /* request redrawing in relevant spaces */
allqueue(REDRAWIPO, 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
- ob->ctime= -1234567.0f; // eveil!
+
+ /* when only showing action (i.e. nla-override off),
+ * reset pose to restpose for armatures
+ */
+ if ((ob->nlaflag & OB_NLA_OVERRIDE)==0) {
+ if (ob->type == OB_ARMATURE)
+ rest_pose(ob->pose);
+ }
+
+ /* flush depsgraph */
+ ob->ctime= -1234567.0f; // evil!
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
}
}
diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c
index 18a9803dcae..69070d61bf0 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;
+ 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;
@@ -706,7 +706,7 @@ void mouse_select_sima(void)
edgeloop= G.qual & LR_ALTKEY;
shift= G.qual & LR_SHIFTKEY;
-
+
if (G.sima->flag & SI_SYNC_UVSEL) {
/* copy from mesh */
if (G.scene->selectmode == SCE_SELECT_FACE) {
@@ -718,7 +718,8 @@ void mouse_select_sima(void)
}
} else {
/* normal operation */
- actface= G.sima->flag & SI_SELACTFACE;
+ actface= G.sima->selectmode == SI_SELECT_FACE;
+ island= G.sima->selectmode == SI_SELECT_ISLAND;
switch(G.sima->sticky) {
case SI_STICKY_LOC:
@@ -761,6 +762,9 @@ void mouse_select_sima(void)
if (nearestefa->v4) hitv[3]= nearestefa->v4->tmp.l;
else hitv[3]= 0xFFFFFFFF;
}
+ else if (island) {
+
+ }
else {
find_nearest_uv(&nearesttf, &nearestefa, &nearestv, &nearestuv);
if(nearesttf==NULL)
@@ -774,7 +778,11 @@ void mouse_select_sima(void)
}
}
- if(!edgeloop && shift) {
+ if (island) {
+ if(shift) select_linked_tface_uv(1);
+ else select_linked_tface_uv(0);
+ }
+ else if(!edgeloop && shift) {
/* (de)select face */
if(actface) {
if(simaFaceSel_Check(nearestefa, nearesttf)) {
diff --git a/source/blender/src/edittime.c b/source/blender/src/edittime.c
index 5a10ea65738..2c37a0eb20f 100644
--- a/source/blender/src/edittime.c
+++ b/source/blender/src/edittime.c
@@ -803,11 +803,11 @@ static void timeline_force_draw(short val)
if(sa->spacetype==SPACE_VIEW3D) {
if(sa==samin || (val & TIME_ALL_3D_WIN)) dodraw= 1;
}
- else if(ELEM6(sa->spacetype, SPACE_NLA, SPACE_IPO, SPACE_SEQ, SPACE_BUTS, SPACE_ACTION, SPACE_SOUND)) {
+ else if(ELEM5(sa->spacetype, SPACE_NLA, SPACE_IPO, SPACE_SEQ, SPACE_ACTION, SPACE_SOUND)) {
if(val & TIME_ALL_ANIM_WIN) dodraw= 1;
}
else if(sa->spacetype==SPACE_BUTS) {
- if(val & TIME_ALL_BUTS_WIN) dodraw= 1;
+ if(val & TIME_ALL_BUTS_WIN) dodraw= 2;
}
else if(sa->spacetype==SPACE_IMAGE) {
if (val & TIME_ALL_IMAGE_WIN) dodraw = 1;
diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c
index 7ac57cb839b..fac9e3af1af 100644
--- a/source/blender/src/header_image.c
+++ b/source/blender/src/header_image.c
@@ -1214,28 +1214,31 @@ void image_buttons(void)
uiBlockBeginAlign(block);
/* B_SEL_VERT & B_SEL_FACE are not defined here which is a bit bad, BUT it works even if image editor is fullscreen */
- uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode (Ctrl Tab 1)");
- xco+= XIC;
+ uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
+ xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode (Ctrl Tab 1)");
/* no edge */
/*uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Edge select mode (Ctrl Tab 2)");
xco+= XIC; */
- uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, xco,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)");
- xco+= XIC+8;
+ uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
+ xco+=XIC,0,XIC,YIC, &G.scene->selectmode, 1.0, 0.0, 0, 0, "Face select mode (Ctrl Tab 3)");
uiBlockEndAlign(block);
} else {
uiBlockBeginAlign(block);
- uiDefIconButBitI(block, TOGN, SI_SELACTFACE, B_REDR, ICON_VERTEXSEL, xco,0,XIC,YIC, &G.sima->flag, 1.0, 0.0, 0, 0, "UV Vertex select mode");
- xco+= XIC;
- uiDefIconButBitI(block, TOG, SI_SELACTFACE, B_REDR, ICON_FACESEL, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "UV Face select mode");
- xco+= XIC+8;
- uiBlockEndAlign(block);
+ uiDefIconButS(block, ROW, B_REDR, ICON_VERTEXSEL,
+ xco,0,XIC,YIC, &G.sima->selectmode, 0.0, SI_SELECT_VERTEX, 0, 0, "UV vertex select mode");
+ uiDefIconButS(block, ROW, B_REDR, ICON_FACESEL,
+ xco+=XIC,0,XIC,YIC, &G.sima->selectmode, 0.0, SI_SELECT_FACE, 0, 0, "UV Face select mode");
+ uiDefIconButS(block, ROW, B_REDR, ICON_MESH,
+ xco+=XIC,0,XIC,YIC, &G.sima->selectmode, 0.0, SI_SELECT_ISLAND, 0, 0, "UV Island select mode");
+ uiBlockEndAlign(block);
+
/* would use these if const's could go in strings
* SI_STICKY_LOC SI_STICKY_DISABLE SI_STICKY_VERTEX */
ubut = uiDefIconTextButC(block, ICONTEXTROW, B_REDR, ICON_STICKY_UVS_LOC,
"Sticky UV Selection: %t|Disable%x1|Shared Location%x0|Shared Vertex%x2",
- xco,0,XIC+10,YIC, &(G.sima->sticky), 0, 3.0, 0, 0,
+ xco+=XIC+10,0,XIC+10,YIC, &(G.sima->sticky), 0, 3.0, 0, 0,
"Sticky UV Selection (Hotkeys: Shift C, Alt C, Ctrl C)");
}
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index 1ada2729289..0f3a46c8a8c 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/sequence.c b/source/blender/src/sequence.c
index 6851929bbc2..9426548dc38 100644
--- a/source/blender/src/sequence.c
+++ b/source/blender/src/sequence.c
@@ -2380,6 +2380,16 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
return i;
}
+/* check used when we need to change seq->blend_mode but not to effect or audio strips */
+int seq_can_blend(Sequence *seq)
+{
+ if (ELEM4(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
/* threading api */
static ListBase running_threads;
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 4422411b1c5..3b8bb4c3929 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -2189,10 +2189,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();
}
@@ -2200,6 +2204,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:
@@ -4432,7 +4440,10 @@ static void winqreadinfospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
switch(event) {
case UI_BUT_EVENT:
- if(val==REDRAWTIME) allqueue(REDRAWTIME, 0);
+ if(val==REDRAWTIME) {
+ allqueue(REDRAWTIME, 0);
+ addqueue(sa->win, REDRAW, 1);
+ }
else if(val==B_ADD_THEME) {
bTheme *btheme, *new;
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index dcebf6b7557..10e49cdd218 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -3610,6 +3610,7 @@ void special_aftertrans_update(TransInfo *t)
Base *base;
short redrawipo=0, resetslowpar=1;
int cancelled= (t->state == TRANS_CANCEL);
+ short duplicate= (t->undostr && strstr(t->undostr, "Duplicate")) ? 1 : 0;
if (t->spacetype==SPACE_VIEW3D) {
if (G.obedit) {
@@ -3622,7 +3623,7 @@ void special_aftertrans_update(TransInfo *t)
}
}
}
- if (t->spacetype == SPACE_ACTION) {
+ else if (t->spacetype == SPACE_ACTION) {
void *data;
short datatype;
@@ -3644,7 +3645,7 @@ void special_aftertrans_update(TransInfo *t)
/* Do curve cleanups? */
if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 &&
- (cancelled == 0) )
+ ((cancelled == 0) || (duplicate)) )
{
posttrans_action_clean((bAction *)data);
}
@@ -3659,7 +3660,7 @@ void special_aftertrans_update(TransInfo *t)
IpoCurve *icu;
if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 &&
- (cancelled == 0) )
+ ((cancelled == 0) || (duplicate)) )
{
posttrans_ipo_clean(key->ipo);
}
@@ -3685,7 +3686,7 @@ void special_aftertrans_update(TransInfo *t)
/* after transform, remove duplicate keyframes on a frame that resulted from transform */
if ( (G.snla->flag & SNLA_NOTRANSKEYCULL)==0 &&
- (cancelled == 0) )
+ ((cancelled == 0) || (duplicate)) )
{
posttrans_nla_clean(t);
}
diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c
index 2a4672e3052..4aea0df74b9 100644
--- a/source/blender/src/usiblender.c
+++ b/source/blender/src/usiblender.c
@@ -34,6 +34,8 @@
#include <stdio.h>
#include <string.h>
+#include "GL/glew.h"
+
#ifdef WIN32
#include <windows.h> /* need to include windows.h so _WIN32_IE is defined */
#ifndef _WIN32_IE
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index f457f9203ff..12450bee9de 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -1154,7 +1154,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/blender/src/vpaint.c b/source/blender/src/vpaint.c
index 4e883caba55..935c546a235 100644
--- a/source/blender/src/vpaint.c
+++ b/source/blender/src/vpaint.c
@@ -566,9 +566,9 @@ static unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac)
cp= (char *)&col;
cp[0]= 255;
- cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
- cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
- cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
+ cp[1]= (mfac*cp1[1]+fac*cp2[1])/255;
+ cp[2]= (mfac*cp1[2]+fac*cp2[2])/255;
+ cp[3]= (mfac*cp1[3]+fac*cp2[3])/255;
return col;
}
@@ -586,11 +586,11 @@ static unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
cp= (char *)&col;
cp[0]= 255;
- temp= cp1[1] + ((fac*cp2[1])>>8);
+ temp= cp1[1] + ((fac*cp2[1])/255);
if(temp>254) cp[1]= 255; else cp[1]= temp;
- temp= cp1[2] + ((fac*cp2[2])>>8);
+ temp= cp1[2] + ((fac*cp2[2])/255);
if(temp>254) cp[2]= 255; else cp[2]= temp;
- temp= cp1[3] + ((fac*cp2[3])>>8);
+ temp= cp1[3] + ((fac*cp2[3])/255);
if(temp>254) cp[3]= 255; else cp[3]= temp;
return col;
@@ -609,11 +609,11 @@ static unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
cp= (char *)&col;
cp[0]= 255;
- temp= cp1[1] - ((fac*cp2[1])>>8);
+ temp= cp1[1] - ((fac*cp2[1])/255);
if(temp<0) cp[1]= 0; else cp[1]= temp;
- temp= cp1[2] - ((fac*cp2[2])>>8);
+ temp= cp1[2] - ((fac*cp2[2])/255);
if(temp<0) cp[2]= 0; else cp[2]= temp;
- temp= cp1[3] - ((fac*cp2[3])>>8);
+ temp= cp1[3] - ((fac*cp2[3])/255);
if(temp<0) cp[3]= 0; else cp[3]= temp;
return col;
@@ -635,9 +635,9 @@ static unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
/* first mul, then blend the fac */
cp[0]= 255;
- cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])>>8) )>>8;
- cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])>>8) )>>8;
- cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])>>8) )>>8;
+ cp[1]= (mfac*cp1[1] + fac*((cp2[1]*cp1[1])/255) )/255;
+ cp[2]= (mfac*cp1[2] + fac*((cp2[2]*cp1[2])/255) )/255;
+ cp[3]= (mfac*cp1[3] + fac*((cp2[3]*cp1[3])/255) )/255;
return col;
@@ -664,9 +664,9 @@ static unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int fac)
return col1;
cp[0]= 255;
- cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
- cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
- cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
+ cp[1]= (mfac*cp1[1]+fac*cp2[1])/255;
+ cp[2]= (mfac*cp1[2]+fac*cp2[2])/255;
+ cp[3]= (mfac*cp1[3]+fac*cp2[3])/255;
return col;
}
@@ -692,9 +692,9 @@ static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac)
return col1;
cp[0]= 255;
- cp[1]= (mfac*cp1[1]+fac*cp2[1])>>8;
- cp[2]= (mfac*cp1[2]+fac*cp2[2])>>8;
- cp[3]= (mfac*cp1[3]+fac*cp2[3])>>8;
+ cp[1]= (mfac*cp1[1]+fac*cp2[1])/255;
+ cp[2]= (mfac*cp1[2]+fac*cp2[2])/255;
+ cp[3]= (mfac*cp1[3]+fac*cp2[3])/255;
return col;
}
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index 230d6b262c6..ed6ea7c5f6a 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -26,6 +26,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
+#include "GL/glew.h"
#include "KX_BlenderGL.h"
#ifdef HAVE_CONFIG_H
@@ -44,7 +45,6 @@
#include "BMF_Api.h"
-#include "GL/glew.h"
#include "BIF_gl.h"
#include "BL_Material.h" // MAXTEX
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index 44f6ec1af90..5d6dd694765 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -184,6 +184,11 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
if (bNegativeEvent)
{
+ // dont continue where we left off when restarting
+ if (m_end_reset) {
+ m_flag &= ~ACT_FLAG_LOCKINPUT;
+ }
+
if (!(m_flag & ACT_FLAG_ACTIVE))
return false;
m_flag &= ~ACT_FLAG_ACTIVE;
@@ -472,8 +477,10 @@ PyMethodDef BL_ActionActuator::Methods[] = {
{"getFrameProperty", (PyCFunction) BL_ActionActuator::sPyGetFrameProperty, METH_VARARGS, GetFrameProperty_doc},
{"setChannel", (PyCFunction) BL_ActionActuator::sPySetChannel, METH_VARARGS, SetChannel_doc},
// {"getChannel", (PyCFunction) BL_ActionActuator::sPyGetChannel, METH_VARARGS},
- {"getType", (PyCFunction) BL_ActionActuator::sPyGetType, METH_VARARGS, GetType_doc},
+ {"getType", (PyCFunction) BL_ActionActuator::sPyGetType, METH_VARARGS, GetType_doc},
{"setType", (PyCFunction) BL_ActionActuator::sPySetType, METH_VARARGS, SetType_doc},
+ {"getContinue", (PyCFunction) BL_ActionActuator::sPyGetContinue, METH_NOARGS, 0},
+ {"setContinue", (PyCFunction) BL_ActionActuator::sPySetContinue, METH_O, 0},
{NULL,NULL} //Sentinel
};
@@ -978,7 +985,26 @@ PyObject* BL_ActionActuator::PySetType(PyObject* self,
default:
printf("Invalid type for action actuator: %d\n", typeArg); /* error */
}
+ Py_RETURN_NONE;
+}
+
+PyObject* BL_ActionActuator::PyGetContinue(PyObject* self) {
+ return PyInt_FromLong((long)(m_end_reset==0));
+}
+
+PyObject* BL_ActionActuator::PySetContinue(PyObject* self, PyObject* value) {
+ int param = PyObject_IsTrue( value );
- Py_Return;
+ if( param == -1 ) {
+ PyErr_SetString( PyExc_TypeError, "expected True/False or 0/1" );
+ return NULL;
+ }
+
+ if (param) {
+ m_end_reset = 0;
+ } else {
+ m_end_reset = 1;
+ }
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
index 190f727c9c3..a67b6d29b74 100644
--- a/source/gameengine/Converter/BL_ActionActuator.h
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -47,6 +47,7 @@ public:
short playtype,
short blendin,
short priority,
+ short end_reset,
float stride,
PyTypeObject* T=&Type)
: SCA_IActuator(gameobj,T),
@@ -64,6 +65,7 @@ public:
m_stridelength(stride),
m_playtype(playtype),
m_priority(priority),
+ m_end_reset(end_reset),
m_pose(NULL),
m_blendpose(NULL),
m_userpose(NULL),
@@ -101,6 +103,8 @@ public:
// KX_PYMETHOD(BL_ActionActuator,GetChannel);
KX_PYMETHOD_DOC(BL_ActionActuator,GetType);
KX_PYMETHOD_DOC(BL_ActionActuator,SetType);
+ KX_PYMETHOD_NOARGS(BL_ActionActuator,GetContinue);
+ KX_PYMETHOD_O(BL_ActionActuator,SetContinue);
virtual PyObject* _getattr(const STR_String& attr);
@@ -137,6 +141,7 @@ protected:
float m_stridelength;
short m_playtype;
short m_priority;
+ short m_end_reset;
struct bPose* m_pose;
struct bPose* m_blendpose;
struct bPose* m_userpose;
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 665783a1ba5..f3e22cd297a 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -312,11 +312,13 @@ BL_Material* ConvertMaterial(
Mesh* mesh,
Material *mat,
MTFace* tface,
+ const char *tfaceName,
MFace* mface,
MCol* mmcol,
int lightlayer,
Object* blenderobj,
- MTF_localLayer *layers)
+ MTF_localLayer *layers,
+ bool glslmat)
{
//this needs some type of manager
BL_Material *material = new BL_Material();
@@ -335,7 +337,7 @@ BL_Material* ConvertMaterial(
if(validmat) {
// use vertex colors by explicitly setting
- if(mat->mode &MA_VERTEXCOLP)
+ if(mat->mode &MA_VERTEXCOLP || glslmat)
type = 0;
// use lighting?
@@ -558,6 +560,7 @@ BL_Material* ConvertMaterial(
}
else {
int valid = 0;
+
// check for tface tex to fallback on
if( validface ){
@@ -590,6 +593,7 @@ BL_Material* ConvertMaterial(
}
MT_Point2 uv[4];
MT_Point2 uv2[4];
+ const char *uvName = "", *uv2Name = "";
uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f);
uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f);
@@ -616,6 +620,8 @@ BL_Material* ConvertMaterial(
if (mface->v4)
uv[3] = MT_Point2(tface->uv[3]);
+
+ uvName = tfaceName;
}
else {
// nothing at all
@@ -641,39 +647,38 @@ BL_Material* ConvertMaterial(
isFirstSet = false;
else
{
- MT_Point2 uvSet[4];
for (int lay=0; lay<MAX_MTFACE; lay++)
{
MTF_localLayer& layer = layers[lay];
if (layer.face == 0) break;
-
- bool processed = false;
if (strcmp(map.uvCoName.ReadPtr(), layer.name)==0)
{
+ MT_Point2 uvSet[4];
+
uvSet[0] = MT_Point2(layer.face->uv[0]);
uvSet[1] = MT_Point2(layer.face->uv[1]);
uvSet[2] = MT_Point2(layer.face->uv[2]);
if (mface->v4)
uvSet[3] = MT_Point2(layer.face->uv[3]);
+ else
+ uvSet[3] = MT_Point2(0.0f, 0.0f);
- processed = true;
- }
-
- if (!processed) continue;
-
- if (isFirstSet)
- {
- uv[0] = uvSet[0]; uv[1] = uvSet[1];
- uv[2] = uvSet[2]; uv[3] = uvSet[3];
- isFirstSet = false;
- }
- else
- {
- uv2[0] = uvSet[0]; uv2[1] = uvSet[1];
- uv2[2] = uvSet[2]; uv2[3] = uvSet[3];
- map.mapping |= USECUSTOMUV;
+ if (isFirstSet)
+ {
+ uv[0] = uvSet[0]; uv[1] = uvSet[1];
+ uv[2] = uvSet[2]; uv[3] = uvSet[3];
+ isFirstSet = false;
+ uvName = layer.name;
+ }
+ else
+ {
+ uv2[0] = uvSet[0]; uv2[1] = uvSet[1];
+ uv2[2] = uvSet[2]; uv2[3] = uvSet[3];
+ map.mapping |= USECUSTOMUV;
+ uv2Name = layer.name;
+ }
}
}
}
@@ -693,9 +698,8 @@ BL_Material* ConvertMaterial(
}
material->SetConversionRGB(rgb);
- material->SetConversionUV(uv);
- material->SetConversionUV2(uv2);
-
+ material->SetConversionUV(uvName, uv);
+ material->SetConversionUV2(uv2Name, uv2);
material->ras_mode |= (mface->v4==0)?TRIANGLE:0;
if(validmat)
@@ -797,6 +801,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
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);
@@ -832,14 +837,14 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
layers[validLayers].face = (MTFace*)mesh->fdata.layers[i].data;;
layers[validLayers].name = mesh->fdata.layers[i].name;
+ if(tface == layers[validLayers].face)
+ tfaceName = layers[validLayers].name;
validLayers++;
}
}
meshobj->SetName(mesh->id.name);
meshobj->m_xyz_index_to_vertex_index_mapping.resize(mesh->totvert);
- if(skinMesh)
- ((BL_SkinMeshObject*)meshobj)->m_mvert_to_dvert_mapping.resize(mesh->totvert);
for (int f=0;f<mesh->totface;f++,mface++)
{
@@ -898,8 +903,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
else
ma = give_current_material(blenderobj, 1);
- bl_mat = ConvertMaterial(mesh, ma, tface, mface, mmcol, lightlayer, blenderobj, layers);
- bl_mat->glslmat = converter->GetGLSLMaterials();
+ 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;
@@ -1059,35 +1063,25 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
int nverts = mface->v4?4:3;
int vtxarray = meshobj->FindVertexArray(nverts,polymat);
RAS_Polygon* poly = new RAS_Polygon(bucket,polyvisible,nverts,vtxarray);
- if (skinMesh) {
- int d1, d2, d3, d4=0;
- bool flat;
+ 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;
-
- d1=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v1, &mesh->dvert[mface->v1], polymat);
- d2=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v2, &mesh->dvert[mface->v2], polymat);
- d3=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v3, &mesh->dvert[mface->v3], polymat);
- if (nverts==4)
- d4=((BL_SkinMeshObject*)meshobj)->FindOrAddDeform(vtxarray, mface->v4, &mesh->dvert[mface->v4], polymat);
- poly->SetVertex(0,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,d1,flat,polymat,mface->v1));
- poly->SetVertex(1,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,d2,flat,polymat,mface->v2));
- poly->SetVertex(2,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,d3,flat,polymat,mface->v3));
- if (nverts==4)
- poly->SetVertex(3,((BL_SkinMeshObject*)meshobj)->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,d4,flat,polymat,mface->v4));
}
else
- {
- poly->SetVertex(0,meshobj->FindOrAddVertex(vtxarray,pt0,uv0,uv20,tan0,rgb0,no0,false,polymat,mface->v1));
- poly->SetVertex(1,meshobj->FindOrAddVertex(vtxarray,pt1,uv1,uv21,tan1,rgb1,no1,false,polymat,mface->v2));
- poly->SetVertex(2,meshobj->FindOrAddVertex(vtxarray,pt2,uv2,uv22,tan2,rgb2,no2,false,polymat,mface->v3));
- if (nverts==4)
- poly->SetVertex(3,meshobj->FindOrAddVertex(vtxarray,pt3,uv3,uv23,tan3,rgb3,no3,false,polymat,mface->v4));
- }
+ 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())
{
@@ -1125,8 +1119,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
}
}
meshobj->m_xyz_index_to_vertex_index_mapping.clear();
- if(skinMesh)
- ((BL_SkinMeshObject*)meshobj)->m_mvert_to_dvert_mapping.clear();
meshobj->UpdateMaterialList();
// pre calculate texture generation
@@ -1545,7 +1537,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
-static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
+static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int layerflag, KX_Scene *kxscene, RAS_IRenderTools *rendertools, KX_BlenderSceneConverter *converter) {
RAS_LightObject lightobj;
KX_LightObject *gamelight;
@@ -1577,8 +1569,15 @@ static KX_LightObject *gamelight_from_blamp(Lamp *la, unsigned int layerflag, KX
} else {
lightobj.m_type = RAS_LightObject::LIGHT_NORMAL;
}
+
+#ifdef BLENDER_GLSL
+ if(converter->GetGLSLMaterials())
+ GPU_lamp_from_blender(ob, la);
- gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj);
+ gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj, ob->gpulamp);
+#else
+ gamelight = new KX_LightObject(kxscene, KX_Scene::m_callbacks, rendertools, lightobj, NULL);
+#endif
BL_ConvertLampIpos(la, gamelight, converter);
return gamelight;
@@ -1610,7 +1609,7 @@ static KX_GameObject *gameobject_from_blenderobject(
{
case OB_LAMP:
{
- KX_LightObject* gamelight= gamelight_from_blamp(static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
+ KX_LightObject* gamelight= gamelight_from_blamp(ob, static_cast<Lamp*>(ob->data), ob->lay, kxscene, rendertools, converter);
gameobj = gamelight;
gamelight->AddRef();
@@ -1660,7 +1659,7 @@ static KX_GameObject *gameobject_from_blenderobject(
// two options exists for deform: shape keys and armature
// only support relative shape key
bool bHasShapeKey = mesh->key != NULL && mesh->key->type==KEY_RELATIVE;
- bool bHasDvert = mesh->dvert != NULL;
+ bool bHasDvert = mesh->dvert != NULL && ob->defbase.first;
bool bHasArmature = (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && bHasDvert);
if (bHasShapeKey) {
@@ -1671,13 +1670,15 @@ static KX_GameObject *gameobject_from_blenderobject(
if (bHasArmature)
dcont->LoadShapeDrivers(ob->parent);
} else if (bHasArmature) {
- BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj );
+ BL_SkinDeformer *dcont = new BL_SkinDeformer((BL_DeformableGameObject*)gameobj,
+ ob, (BL_SkinMeshObject*)meshobj);
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
} else if (bHasDvert) {
// this case correspond to a mesh that can potentially deform but not with the
// object to which it is attached for the moment. A skin mesh was created in
// BL_ConvertMesh() so must create a deformer too!
- BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj );
+ BL_MeshDeformer *dcont = new BL_MeshDeformer((BL_DeformableGameObject*)gameobj,
+ ob, (BL_SkinMeshObject*)meshobj);
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
}
@@ -2075,7 +2076,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (blenderscene->camera) {
KX_Camera *gamecamera= (KX_Camera*) converter->FindGameObject(blenderscene->camera);
- kxscene->SetActiveCamera(gamecamera);
+ if(gamecamera)
+ kxscene->SetActiveCamera(gamecamera);
}
// Set up armatures
@@ -2331,7 +2333,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/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp
index 212827a660f..39d66a90e92 100644
--- a/source/gameengine/Converter/BL_MeshDeformer.cpp
+++ b/source/gameengine/Converter/BL_MeshDeformer.cpp
@@ -39,6 +39,7 @@
#endif
#include "RAS_IPolygonMaterial.h"
+#include "BL_DeformableGameObject.h"
#include "BL_MeshDeformer.h"
#include "BL_SkinMeshObject.h"
#include "DNA_mesh_types.h"
@@ -47,33 +48,40 @@
#include "GEN_Map.h"
#include "STR_HashedString.h"
-bool BL_MeshDeformer::Apply(RAS_IPolyMaterial *mat)
+bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*)
{
- size_t i, j, index;
- vecVertexArray array;
- vecIndexArrays mvarray;
- vecIndexArrays diarray;
-
- RAS_TexVert *tv;
- MVert *mvert;
-
- // For each material
- array = m_pMeshObject->GetVertexCache(mat);
- mvarray = m_pMeshObject->GetMVertCache(mat);
- diarray = m_pMeshObject->GetDIndexCache(mat);
-
- // For each array
- for (i=0; i<array.size(); i++){
- // For each vertex
- for (j=0; j<array[i]->size(); j++){
- tv = &((*array[i])[j]);
- index = ((*diarray[i])[j]);
-
- mvert = &(m_bmesh->mvert[((*mvarray[i])[index])]);
- tv->SetXYZ(MT_Point3(mvert->co));
+ size_t i, j;
+ float *co;
+
+ // only apply once per frame if the mesh is actually modified
+ if(m_pMeshObject->MeshModified() &&
+ m_lastDeformUpdate != m_gameobj->GetLastFrame()) {
+ // For each material
+ for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial();
+ mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
+ RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial();
+
+ vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat);
+
+ // For each array
+ for (i=0; i<vertexarrays.size(); i++){
+ KX_VertexArray& vertexarray = (*vertexarrays[i]);
+
+ // For each vertex
+ for (j=0; j<vertexarray.size(); j++){
+ RAS_TexVert& v = vertexarray[j];
+ co = m_bmesh->mvert[v.getOrigIndex()].co;
+ v.SetXYZ(MT_Point3(co));
+ }
+ }
}
+
+ m_lastDeformUpdate = m_gameobj->GetLastFrame();
+
+ return true;
}
- return true;
+
+ return false;
}
BL_MeshDeformer::~BL_MeshDeformer()
@@ -92,83 +100,86 @@ void BL_MeshDeformer::RecalcNormals()
/* We don't normalize for performance, not doing it for faces normals
* gives area-weight normals which often look better anyway, and use
* GL_NORMALIZE so we don't have to do per vertex normalization either
- * since the GPU can do it faster
- *
- * There's a lot of indirection here to get to the data, can this work
- * with less arrays/indirection? */
-
- vecIndexArrays indexarrays;
- vecIndexArrays mvarrays;
- vecIndexArrays diarrays;
- vecVertexArray vertexarrays;
+ * since the GPU can do it faster */
size_t i, j;
/* set vertex normals to zero */
- for (i=0; i<(size_t)m_bmesh->totvert; i++)
- m_transnors[i] = MT_Vector3(0.0f, 0.0f, 0.0f);
+ memset(m_transnors, 0, sizeof(float)*3*m_bmesh->totvert);
/* add face normals to vertices. */
for(RAS_MaterialBucket::Set::iterator mit = m_pMeshObject->GetFirstMaterial();
mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial();
- indexarrays = m_pMeshObject->GetIndexCache(mat);
- vertexarrays = m_pMeshObject->GetVertexCache(mat);
- diarrays = m_pMeshObject->GetDIndexCache(mat);
- mvarrays = m_pMeshObject->GetMVertCache(mat);
+ const vecIndexArrays& indexarrays = m_pMeshObject->GetIndexCache(mat);
+ vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat);
for (i=0; i<indexarrays.size(); i++) {
KX_VertexArray& vertexarray = (*vertexarrays[i]);
- const KX_IndexArray& mvarray = (*mvarrays[i]);
- const KX_IndexArray& diarray = (*diarrays[i]);
const KX_IndexArray& indexarray = (*indexarrays[i]);
int nvert = mat->UsesTriangles()? 3: 4;
for(j=0; j<indexarray.size(); j+=nvert) {
- MT_Point3 mv1, mv2, mv3, mv4, fnor;
- int i1 = indexarray[j];
- int i2 = indexarray[j+1];
- int i3 = indexarray[j+2];
- RAS_TexVert& v1 = vertexarray[i1];
- RAS_TexVert& v2 = vertexarray[i2];
- RAS_TexVert& v3 = vertexarray[i3];
-
+ RAS_TexVert& v1 = vertexarray[indexarray[j]];
+ RAS_TexVert& v2 = vertexarray[indexarray[j+1]];
+ RAS_TexVert& v3 = vertexarray[indexarray[j+2]];
+ RAS_TexVert *v4 = NULL;
+
+ const float *co1 = v1.getLocalXYZ();
+ const float *co2 = v2.getLocalXYZ();
+ const float *co3 = v3.getLocalXYZ();
+ const float *co4 = NULL;
+
/* compute face normal */
- mv1 = MT_Point3(v1.getLocalXYZ());
- mv2 = MT_Point3(v2.getLocalXYZ());
- mv3 = MT_Point3(v3.getLocalXYZ());
+ float fnor[3], n1[3], n2[3];
if(nvert == 4) {
- int i4 = indexarray[j+3];
- RAS_TexVert& v4 = vertexarray[i4];
- mv4 = MT_Point3(v4.getLocalXYZ());
+ v4 = &vertexarray[indexarray[j+3]];
+ co4 = v4->getLocalXYZ();
+
+ n1[0]= co1[0]-co3[0];
+ n1[1]= co1[1]-co3[1];
+ n1[2]= co1[2]-co3[2];
- fnor = (((mv2-mv1).cross(mv3-mv2))+((mv4-mv3).cross(mv1-mv4))); //.safe_normalized();
+ n2[0]= co2[0]-co4[0];
+ n2[1]= co2[1]-co4[1];
+ n2[2]= co2[2]-co4[2];
}
- else
- fnor = ((mv2-mv1).cross(mv3-mv2)); //.safe_normalized();
+ else {
+ n1[0]= co1[0]-co2[0];
+ n2[0]= co2[0]-co3[0];
+ n1[1]= co1[1]-co2[1];
+
+ n2[1]= co2[1]-co3[1];
+ n1[2]= co1[2]-co2[2];
+ n2[2]= co2[2]-co3[2];
+ }
+
+ fnor[0]= n1[1]*n2[2] - n1[2]*n2[1];
+ fnor[1]= n1[2]*n2[0] - n1[0]*n2[2];
+ fnor[2]= n1[0]*n2[1] - n1[1]*n2[0];
/* add to vertices for smooth normals */
- m_transnors[mvarray[diarray[i1]]] += fnor;
- m_transnors[mvarray[diarray[i2]]] += fnor;
- m_transnors[mvarray[diarray[i3]]] += fnor;
+ float *vn1 = m_transnors[v1.getOrigIndex()];
+ float *vn2 = m_transnors[v2.getOrigIndex()];
+ float *vn3 = m_transnors[v3.getOrigIndex()];
+
+ vn1[0] += fnor[0]; vn1[1] += fnor[1]; vn1[2] += fnor[2];
+ vn2[0] += fnor[0]; vn2[1] += fnor[1]; vn2[2] += fnor[2];
+ vn3[0] += fnor[0]; vn3[1] += fnor[1]; vn3[2] += fnor[2];
+
+ if(v4) {
+ float *vn4 = m_transnors[v4->getOrigIndex()];
+ vn4[0] += fnor[0]; vn4[1] += fnor[1]; vn4[2] += fnor[2];
+ }
/* in case of flat - just assign, the vertices are split */
if(v1.getFlag() & TV_CALCFACENORMAL) {
v1.SetNormal(fnor);
v2.SetNormal(fnor);
v3.SetNormal(fnor);
- }
-
- if(nvert == 4) {
- int i4 = indexarray[j+3];
- RAS_TexVert& v4 = vertexarray[i4];
-
- /* same as above */
- m_transnors[mvarray[diarray[i4]]] += fnor;
-
- if(v4.getFlag() & TV_CALCFACENORMAL)
- v4.SetNormal(fnor);
+ if(v4)
+ v4->SetNormal(fnor);
}
}
}
@@ -179,18 +190,17 @@ void BL_MeshDeformer::RecalcNormals()
mit != m_pMeshObject->GetLastMaterial(); ++ mit) {
RAS_IPolyMaterial *mat = (*mit)->GetPolyMaterial();
- vertexarrays = m_pMeshObject->GetVertexCache(mat);
- diarrays = m_pMeshObject->GetDIndexCache(mat);
- mvarrays = m_pMeshObject->GetMVertCache(mat);
+ vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat);
for (i=0; i<vertexarrays.size(); i++) {
KX_VertexArray& vertexarray = (*vertexarrays[i]);
- const KX_IndexArray& mvarray = (*mvarrays[i]);
- const KX_IndexArray& diarray = (*diarrays[i]);
- for(j=0; j<vertexarray.size(); j++)
- if(!(vertexarray[j].getFlag() & TV_CALCFACENORMAL))
- vertexarray[j].SetNormal(m_transnors[mvarray[diarray[j]]]); //.safe_normalized()
+ for(j=0; j<vertexarray.size(); j++) {
+ RAS_TexVert& v = vertexarray[j];
+
+ if(!(v.getFlag() & TV_CALCFACENORMAL))
+ v.SetNormal(m_transnors[v.getOrigIndex()]); //.safe_normalized()
+ }
}
}
}
@@ -204,8 +214,8 @@ void BL_MeshDeformer::VerifyStorage()
if (m_transnors)
delete [] m_transnors;
- m_transverts=new float[(sizeof(*m_transverts)*m_bmesh->totvert)][3];
- m_transnors=new MT_Vector3[m_bmesh->totvert];
+ m_transverts=new float[m_bmesh->totvert][3];
+ m_transnors=new float[m_bmesh->totvert][3];
m_tvtot = m_bmesh->totvert;
}
}
diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h
index 8d8b56b1eed..e9f7f0b192f 100644
--- a/source/gameengine/Converter/BL_MeshDeformer.h
+++ b/source/gameengine/Converter/BL_MeshDeformer.h
@@ -40,19 +40,25 @@
#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
#endif //WIN32
+class BL_DeformableGameObject;
+
class BL_MeshDeformer : public RAS_Deformer
{
public:
void VerifyStorage();
void RecalcNormals();
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map){};
- BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj ):
+ BL_MeshDeformer(BL_DeformableGameObject *gameobj,
+ struct Object* obj,
+ class BL_SkinMeshObject *meshobj ):
m_pMeshObject(meshobj),
m_bmesh((struct Mesh*)(obj->data)),
m_transverts(0),
m_transnors(0),
m_objMesh(obj),
- m_tvtot(0)
+ m_tvtot(0),
+ m_gameobj(gameobj),
+ m_lastDeformUpdate(-1)
{};
virtual ~BL_MeshDeformer();
virtual void SetSimulatedTime(double time){};
@@ -68,10 +74,12 @@ protected:
// this is so m_transverts doesn't need to be converted
// before deformation
float (*m_transverts)[3];
- MT_Vector3* m_transnors;
+ float (*m_transnors)[3];
struct Object* m_objMesh;
// --
int m_tvtot;
+ BL_DeformableGameObject* m_gameobj;
+ double m_lastDeformUpdate;
};
#endif
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.h b/source/gameengine/Converter/BL_ShapeDeformer.h
index 9f8361dbaca..5f0188e3a42 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.h
+++ b/source/gameengine/Converter/BL_ShapeDeformer.h
@@ -58,9 +58,8 @@ public:
Object *bmeshobj,
BL_SkinMeshObject *mesh)
:
- BL_SkinDeformer(bmeshobj, mesh),
- m_lastShapeUpdate(-1),
- m_gameobj(gameobj)
+ BL_SkinDeformer(gameobj,bmeshobj, mesh),
+ m_lastShapeUpdate(-1)
{
};
@@ -72,9 +71,8 @@ public:
bool release_object,
BL_ArmatureObject* arma = NULL)
:
- BL_SkinDeformer(bmeshobj_old, bmeshobj_new, mesh, release_object, arma),
- m_lastShapeUpdate(-1),
- m_gameobj(gameobj)
+ BL_SkinDeformer(gameobj, bmeshobj_old, bmeshobj_new, mesh, release_object, arma),
+ m_lastShapeUpdate(-1)
{
};
@@ -94,7 +92,6 @@ public:
protected:
vector<IpoCurve*> m_shapeDrivers;
double m_lastShapeUpdate;
- BL_DeformableGameObject* m_gameobj;
};
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index dd7119b1031..d3442fe5298 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -57,11 +57,12 @@ extern "C"{
#define __NLA_DEFNORMALS
//#undef __NLA_DEFNORMALS
-BL_SkinDeformer::BL_SkinDeformer(struct Object *bmeshobj,
+BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
+ struct Object *bmeshobj,
class BL_SkinMeshObject *mesh,
BL_ArmatureObject* arma)
: //
- BL_MeshDeformer(bmeshobj, mesh),
+ BL_MeshDeformer(gameobj, bmeshobj, mesh),
m_armobj(arma),
m_lastArmaUpdate(-1),
m_defbase(&bmeshobj->defbase),
@@ -71,12 +72,13 @@ BL_SkinDeformer::BL_SkinDeformer(struct Object *bmeshobj,
};
BL_SkinDeformer::BL_SkinDeformer(
+ BL_DeformableGameObject *gameobj,
struct Object *bmeshobj_old, // Blender object that owns the new mesh
struct Object *bmeshobj_new, // Blender object that owns the original mesh
class BL_SkinMeshObject *mesh,
bool release_object,
BL_ArmatureObject* arma) :
- BL_MeshDeformer(bmeshobj_old, mesh),
+ BL_MeshDeformer(gameobj, bmeshobj_old, mesh),
m_armobj(arma),
m_lastArmaUpdate(-1),
m_defbase(&bmeshobj_old->defbase),
@@ -96,35 +98,32 @@ BL_SkinDeformer::~BL_SkinDeformer()
m_armobj->Release();
}
-bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
+bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *)
{
- size_t i, j, index;
- vecVertexArray array;
- vecIndexArrays mvarray;
- vecMDVertArray dvarray;
- vecIndexArrays diarray;
-
- RAS_TexVert *tv;
- MT_Point3 pt;
-// float co[3];
-
- Update();
-
- array = m_pMeshObject->GetVertexCache(mat);
- mvarray = m_pMeshObject->GetMVertCache(mat);
- diarray = m_pMeshObject->GetDIndexCache(mat);
- // For each array
- for (i=0; i<array.size(); i++) {
- // For each vertex
- for (j=0; j<array[i]->size(); j++) {
-
- tv = &((*array[i])[j]);
-
- index = ((*diarray[i])[j]);
-
- // Copy the untransformed data from the original mvert
- // Set the data
- tv->SetXYZ(m_transverts[((*mvarray[i])[index])]);
+ size_t i, j;
+
+ if (!Update())
+ // no need to update the cache
+ return false;
+
+ // 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();
+
+ vecVertexArray& vertexarrays = m_pMeshObject->GetVertexCache(mat);
+
+ // 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()]);
+ }
}
}
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
index c5568c049cb..f35db8273c4 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.h
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -63,12 +63,14 @@ public:
}
void SetArmature (class BL_ArmatureObject *armobj);
- BL_SkinDeformer(struct Object *bmeshobj,
+ BL_SkinDeformer(BL_DeformableGameObject *gameobj,
+ struct Object *bmeshobj,
class BL_SkinMeshObject *mesh,
BL_ArmatureObject* arma = NULL);
/* this second constructor is needed for making a mesh deformable on the fly. */
- BL_SkinDeformer(struct Object *bmeshobj_old,
+ BL_SkinDeformer(BL_DeformableGameObject *gameobj,
+ struct Object *bmeshobj_old,
struct Object *bmeshobj_new,
class BL_SkinMeshObject *mesh,
bool release_object,
diff --git a/source/gameengine/Converter/BL_SkinMeshObject.cpp b/source/gameengine/Converter/BL_SkinMeshObject.cpp
index 49492923c7c..fa215df1e1c 100644
--- a/source/gameengine/Converter/BL_SkinMeshObject.cpp
+++ b/source/gameengine/Converter/BL_SkinMeshObject.cpp
@@ -43,90 +43,6 @@
#include "KX_GameObject.h"
#include "RAS_BucketManager.h"
-void BL_SkinMeshObject::AddPolygon(RAS_Polygon* poly)
-{
- /* We're overriding this so that we can eventually associate faces with verts somehow */
-
- // For vertIndex in poly:
- // find the appropriate normal
-
- RAS_MeshObject::AddPolygon(poly);
-}
-
-int BL_SkinMeshObject::FindOrAddDeform(unsigned int vtxarray, unsigned int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat)
-{
- BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
- int numvert = ao->m_MvertArrayCache1[vtxarray]->size();
-
- /* Check to see if this has already been pushed */
- for (vector<BL_MDVertMap>::iterator it = m_mvert_to_dvert_mapping[mv].begin();
- it != m_mvert_to_dvert_mapping[mv].end();
- it++)
- {
- if(it->mat == mat)
- return it->index;
- }
-
- ao->m_MvertArrayCache1[vtxarray]->push_back(mv);
- ao->m_DvertArrayCache1[vtxarray]->push_back(dv);
-
- BL_MDVertMap mdmap;
- mdmap.mat = mat;
- mdmap.index = numvert;
- m_mvert_to_dvert_mapping[mv].push_back(mdmap);
-
- return numvert;
-};
-
-int BL_SkinMeshObject::FindVertexArray(int numverts,RAS_IPolyMaterial* polymat)
-{
- int array=-1;
-
- BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(polymat);
-
-
- for (size_t i=0;i<ao->m_VertexArrayCache1.size();i++)
- {
- if ( (ao->m_TriangleArrayCount[i] + (numverts-2)) < BUCKET_MAX_TRIANGLES)
- {
- if((ao->m_VertexArrayCache1[i]->size()+numverts < BUCKET_MAX_INDICES))
- {
- array = i;
- ao->m_TriangleArrayCount[array]+=numverts-2;
- break;
- }
- }
- }
-
-
- if (array == -1)
- {
- array = ao->m_VertexArrayCache1.size();
-
- vector<RAS_TexVert>* va = new vector<RAS_TexVert>;
- ao->m_VertexArrayCache1.push_back(va);
-
- KX_IndexArray *ia = new KX_IndexArray();
- ao->m_IndexArrayCache1.push_back(ia);
-
- KX_IndexArray *bva = new KX_IndexArray();
- ao->m_MvertArrayCache1.push_back(bva);
-
- BL_DeformVertArray *dva = new BL_DeformVertArray();
- ao->m_DvertArrayCache1.push_back(dva);
-
- KX_IndexArray *da = new KX_IndexArray();
- ao->m_DIndexArrayCache1.push_back(da);
-
- ao->m_TriangleArrayCount.push_back(numverts-2);
-
- }
-
-
- return array;
-}
-
-
//void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,RAS_BucketManager* bucketmgr)
void BL_SkinMeshObject::Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec)
{
diff --git a/source/gameengine/Converter/BL_SkinMeshObject.h b/source/gameengine/Converter/BL_SkinMeshObject.h
index cc2b8de600e..c21fb64204b 100644
--- a/source/gameengine/Converter/BL_SkinMeshObject.h
+++ b/source/gameengine/Converter/BL_SkinMeshObject.h
@@ -44,78 +44,19 @@
#include "DNA_key_types.h"
#include "DNA_meshdata_types.h"
-typedef vector<struct MVert*> BL_MVertArray;
-typedef vector<struct MDeformVert*> BL_DeformVertArray;
-typedef vector<class BL_TexVert> BL_VertexArray;
-
-
-typedef vector<vector<struct MDeformVert*>*> vecMDVertArray;
-typedef vector<vector<class BL_TexVert>*> vecBVertexArray;
-
-class BL_SkinArrayOptimizer : public KX_ArrayOptimizer
-{
-public:
- BL_SkinArrayOptimizer(int index)
- :KX_ArrayOptimizer (index) {};
- virtual ~BL_SkinArrayOptimizer(){
-
- for (vector<KX_IndexArray*>::iterator itv = m_MvertArrayCache1.begin();
- !(itv == m_MvertArrayCache1.end());itv++)
- {
- delete (*itv);
- }
- for (vector<BL_DeformVertArray*>::iterator itd = m_DvertArrayCache1.begin();
- !(itd == m_DvertArrayCache1.end());itd++)
- {
- delete (*itd);
- }
- for (vector<KX_IndexArray*>::iterator iti = m_DIndexArrayCache1.begin();
- !(iti == m_DIndexArrayCache1.end());iti++)
- {
- delete (*iti);
- }
-
- m_MvertArrayCache1.clear();
- m_DvertArrayCache1.clear();
- m_DIndexArrayCache1.clear();
- };
-
- vector<KX_IndexArray*> m_MvertArrayCache1;
- vector<BL_DeformVertArray*> m_DvertArrayCache1;
- vector<KX_IndexArray*> m_DIndexArrayCache1;
-
-};
-
class BL_SkinMeshObject : public RAS_MeshObject
{
// enum { BUCKET_MAX_INDICES = 16384};//2048};//8192};
// enum { BUCKET_MAX_TRIANGLES = 4096};
- KX_ArrayOptimizer* GetArrayOptimizer(RAS_IPolyMaterial* polymat)
- {
- KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]);
- if (aop)
- return *aop;
- int numelements = m_matVertexArrayS.size();
- m_sortedMaterials.push_back(polymat);
-
- BL_SkinArrayOptimizer* ao = new BL_SkinArrayOptimizer(numelements);
- m_matVertexArrayS.insert(*polymat,ao);
- return ao;
- }
-
protected:
vector<int> m_cacheWeightIndex;
public:
- struct BL_MDVertMap { RAS_IPolyMaterial *mat; int index; };
- vector<vector<BL_MDVertMap> > m_mvert_to_dvert_mapping;
-
void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec);
// void Bucketize(double* oglmatrix,void* clientobj,bool useObjectColor,const MT_Vector4& rgbavec,class RAS_BucketManager* bucketmgr);
- int FindVertexArray(int numverts,RAS_IPolyMaterial* polymat);
BL_SkinMeshObject(Mesh* mesh, int lightlayer) : RAS_MeshObject (mesh, lightlayer)
{
m_class = 1;
@@ -144,42 +85,7 @@ public:
}
}
};
-
- const vecIndexArrays& GetDIndexCache (RAS_IPolyMaterial* mat)
- {
- BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
- return ao->m_DIndexArrayCache1;
- }
- const vecMDVertArray& GetDVertCache (RAS_IPolyMaterial* mat)
- {
- BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
- return ao->m_DvertArrayCache1;
- }
- const vecIndexArrays& GetMVertCache (RAS_IPolyMaterial* mat)
- {
- BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
- return ao->m_MvertArrayCache1;
- }
- void AddPolygon(RAS_Polygon* poly);
- int FindOrAddDeform(unsigned int vtxarray, unsigned int mv, struct MDeformVert *dv, RAS_IPolyMaterial* mat);
- int FindOrAddVertex(int vtxarray,const MT_Point3& xyz,
- const MT_Point2& uv,
- const MT_Point2& uv2,
- const MT_Vector4& tangent,
- const unsigned int rgbacolor,
- const MT_Vector3& normal, int defnr, bool flat, RAS_IPolyMaterial* mat, int origindex)
- {
- BL_SkinArrayOptimizer* ao = (BL_SkinArrayOptimizer*)GetArrayOptimizer(mat);
- int numverts = ao->m_VertexArrayCache1[vtxarray]->size();
- int index = RAS_MeshObject::FindOrAddVertex(vtxarray, xyz, uv, uv2, tangent, rgbacolor, normal, flat, mat, origindex);
-
- /* this means a new vertex was added, so we add the defnr too */
- if(index == numverts)
- ao->m_DIndexArrayCache1[vtxarray]->push_back(defnr);
-
- return index;
- }
// for shape keys,
void CheckWeightCache(struct Object* obj);
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 6e05ea31fe8..1f87e9d9ac7 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -193,6 +193,7 @@ void BL_ConvertActuators(char* maggiename,
actact->type, // + 1, because Blender starts to count at zero,
actact->blendin,
actact->priority,
+ actact->end_reset,
actact->stridelength
// Ketsji at 1, because zero is reserved for "NoDef"
);
@@ -233,7 +234,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 +246,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 9645bfbed4a..e1c8ef87dd1 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/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp
index 06e012123b1..dd45d522b9f 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.cpp
+++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp
@@ -1,9 +1,11 @@
#include "DNA_customdata_types.h"
+#include "DNA_material_types.h"
#include "BL_BlenderShader.h"
+#include "BL_Material.h"
-#if 0
+#ifdef BLENDER_GLSL
#include "GPU_extensions.h"
#include "GPU_material.h"
#endif
@@ -13,29 +15,32 @@
const bool BL_BlenderShader::Ok()const
{
-#if 0
+#ifdef BLENDER_GLSL
return (mGPUMat != 0);
+#else
+ return 0;
#endif
-
- return false;
}
-BL_BlenderShader::BL_BlenderShader(struct Material *ma)
+BL_BlenderShader::BL_BlenderShader(struct Material *ma, int lightlayer)
:
-#if 0
+#ifdef BLENDER_GLSL
mGPUMat(0),
#endif
- mBound(false)
+ mBound(false),
+ mLightLayer(lightlayer)
{
-#if 0
- if(ma)
- mGPUMat = GPU_material_from_blender(ma, GPU_PROFILE_DERIVEDMESH);
+#ifdef BLENDER_GLSL
+ if(ma) {
+ GPU_material_from_blender(ma);
+ mGPUMat = ma->gpumaterial;
+ }
#endif
}
BL_BlenderShader::~BL_BlenderShader()
{
-#if 0
+#ifdef BLENDER_GLSL
if(mGPUMat) {
GPU_material_unbind(mGPUMat);
mGPUMat = 0;
@@ -43,16 +48,12 @@ BL_BlenderShader::~BL_BlenderShader()
#endif
}
-void BL_BlenderShader::ApplyShader()
-{
-}
-
void BL_BlenderShader::SetProg(bool enable)
{
-#if 0
+#ifdef BLENDER_GLSL
if(mGPUMat) {
if(enable) {
- GPU_material_bind(mGPUMat);
+ GPU_material_bind(mGPUMat, mLightLayer);
mBound = true;
}
else {
@@ -65,7 +66,7 @@ void BL_BlenderShader::SetProg(bool enable)
int BL_BlenderShader::GetAttribNum()
{
-#if 0
+#ifdef BLENDER_GLSL
GPUVertexAttribs attribs;
int i, enabled = 0;
@@ -82,17 +83,19 @@ int BL_BlenderShader::GetAttribNum()
enabled = BL_MAX_ATTRIB;
return enabled;
-#endif
-
+#else
return 0;
+#endif
}
-void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras)
+void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
{
-#if 0
+#ifdef BLENDER_GLSL
GPUVertexAttribs attribs;
int i, attrib_num;
+ ras->SetAttribNum(0);
+
if(!mGPUMat)
return;
@@ -109,14 +112,24 @@ void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras)
if(attribs.layer[i].glindex > attrib_num)
continue;
- if(attribs.layer[i].type == CD_MTFACE)
- ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
+ if(attribs.layer[i].type == CD_MTFACE) {
+ if(!mat->uvName.IsEmpty() && strcmp(mat->uvName.ReadPtr(), attribs.layer[i].name) == 0)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
+ else if(!mat->uv2Name.IsEmpty() && strcmp(mat->uv2Name.ReadPtr(), attribs.layer[i].name) == 0)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV2, attribs.layer[i].glindex);
+ else
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_UV1, attribs.layer[i].glindex);
+ }
else if(attribs.layer[i].type == CD_TANGENT)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, attribs.layer[i].glindex);
else if(attribs.layer[i].type == CD_ORCO)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_ORCO, attribs.layer[i].glindex);
else if(attribs.layer[i].type == CD_NORMAL)
ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_NORM, attribs.layer[i].glindex);
+ else if(attribs.layer[i].type == CD_MCOL)
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_VCOL, attribs.layer[i].glindex);
+ else
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, attribs.layer[i].glindex);
}
ras->EnableTextures(true);
@@ -128,8 +141,8 @@ void BL_BlenderShader::SetTexCoords(RAS_IRasterizer* ras)
void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
{
-#if 0
- float obmat[4][4], viewmat[4][4];
+#ifdef BLENDER_GLSL
+ float obmat[4][4], viewmat[4][4], viewinvmat[4][4];
if(!mGPUMat || !mBound)
return;
@@ -142,7 +155,20 @@ void BL_BlenderShader::Update( const KX_MeshSlot & ms, RAS_IRasterizer* rasty )
model.getValue((float*)obmat);
view.getValue((float*)viewmat);
- GPU_material_bind_uniforms(mGPUMat, obmat, viewmat);
+ view.invert();
+ view.getValue((float*)viewinvmat);
+
+ GPU_material_bind_uniforms(mGPUMat, obmat, viewmat, viewinvmat);
+#endif
+}
+
+bool BL_BlenderShader::Equals(BL_BlenderShader *blshader)
+{
+#ifdef BLENDER_GLSL
+ /* to avoid unneeded state switches */
+ return (blshader && mGPUMat == blshader->mGPUMat && mLightLayer == blshader->mLightLayer);
+#else
+ return true;
#endif
}
diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h
index 4cab0e644c3..b758d1a9cba 100644
--- a/source/gameengine/Ketsji/BL_BlenderShader.h
+++ b/source/gameengine/Ketsji/BL_BlenderShader.h
@@ -2,7 +2,7 @@
#ifndef __BL_GPUSHADER_H__
#define __BL_GPUSHADER_H__
-#if 0
+#ifdef BLENDER_GLSL
#include "GPU_material.h"
#endif
@@ -12,7 +12,10 @@
#include "MT_Tuple3.h"
#include "MT_Tuple4.h"
+#include "RAS_IPolygonMaterial.h"
+
struct Material;
+class BL_Material;
#define BL_MAX_ATTRIB 16
@@ -23,22 +26,24 @@ struct Material;
class BL_BlenderShader
{
private:
-#if 0
+#ifdef BLENDER_GLSL
GPUMaterial *mGPUMat;
#endif
bool mBound;
+ int mLightLayer;
public:
- BL_BlenderShader(struct Material *ma);
+ BL_BlenderShader(struct Material *ma, int lightlayer);
virtual ~BL_BlenderShader();
const bool Ok()const;
void SetProg(bool enable);
- void ApplyShader();
- void SetTexCoords(class RAS_IRasterizer* ras);
int GetAttribNum();
+ void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);
void Update(const class KX_MeshSlot & ms, class RAS_IRasterizer* rasty);
+
+ bool Equals(BL_BlenderShader *blshader);
};
#endif//__BL_GPUSHADER_H__
diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp
index f5312ccd023..7e3d6984f19 100644
--- a/source/gameengine/Ketsji/BL_Material.cpp
+++ b/source/gameengine/Ketsji/BL_Material.cpp
@@ -105,7 +105,8 @@ void BL_Material::GetConversionRGB(unsigned int *nrgb) {
*nrgb = rgb[3];
}
-void BL_Material::SetConversionUV(MT_Point2 *nuv) {
+void BL_Material::SetConversionUV(const STR_String& name, MT_Point2 *nuv) {
+ uvName = name;
uv[0] = *nuv++;
uv[1] = *nuv++;
uv[2] = *nuv++;
@@ -118,7 +119,8 @@ void BL_Material::GetConversionUV(MT_Point2 *nuv){
*nuv++ = uv[2];
*nuv = uv[3];
}
-void BL_Material::SetConversionUV2(MT_Point2 *nuv) {
+void BL_Material::SetConversionUV2(const STR_String& name, MT_Point2 *nuv) {
+ uv2Name = name;
uv2[0] = *nuv++;
uv2[1] = *nuv++;
uv2[2] = *nuv++;
diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h
index ddb6662830a..568f7e171de 100644
--- a/source/gameengine/Ketsji/BL_Material.h
+++ b/source/gameengine/Ketsji/BL_Material.h
@@ -83,13 +83,16 @@ public:
MT_Point2 uv[4];
MT_Point2 uv2[4];
+ STR_String uvName;
+ STR_String uv2Name;
+
void SetConversionRGB(unsigned int *rgb);
void GetConversionRGB(unsigned int *rgb);
- void SetConversionUV(MT_Point2 *uv);
+ void SetConversionUV(const STR_String& name, MT_Point2 *uv);
void GetConversionUV(MT_Point2 *uv);
- void SetConversionUV2(MT_Point2 *uv);
+ void SetConversionUV2(const STR_String& name, MT_Point2 *uv);
void GetConversionUV2(MT_Point2 *uv);
void SetSharedMaterial(bool v);
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index 02b1ffd432a..0f445a9f32e 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -38,6 +38,8 @@ extern "C" {
// ------------------------------------
#define spit(x) std::cout << x << std::endl;
+BL_BlenderShader *KX_BlenderMaterial::mLastBlenderShader = NULL;
+
//static PyObject *gTextureDict = 0;
KX_BlenderMaterial::KX_BlenderMaterial(
@@ -126,32 +128,31 @@ void KX_BlenderMaterial::OnConstruction()
// when material are reused between objects
return;
- if(mMaterial->glslmat) {
+ if(mMaterial->glslmat)
SetBlenderGLSLShader();
- }
- else {
- // for each unique material...
- int i;
- for(i=0; i<mMaterial->num_enabled; i++) {
- if( mMaterial->mapping[i].mapping & USEENV ) {
- if(!GLEW_ARB_texture_cube_map) {
- spit("CubeMap textures not supported");
- continue;
- }
- if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) )
+
+ // for each unique material...
+ int i;
+ for(i=0; i<mMaterial->num_enabled; i++) {
+ if( mMaterial->mapping[i].mapping & USEENV ) {
+ if(!GLEW_ARB_texture_cube_map) {
+ spit("CubeMap textures not supported");
+ continue;
+ }
+ if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) )
+ spit("unable to initialize image("<<i<<") in "<<
+ mMaterial->matname<< ", image will not be available");
+ }
+
+ else {
+ if( mMaterial->img[i] ) {
+ if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
spit("unable to initialize image("<<i<<") in "<<
- mMaterial->matname<< ", image will not be available");
- }
-
- else {
- if( mMaterial->img[i] ) {
- if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
- spit("unable to initialize image("<<i<<") in "<<
- mMaterial->matname<< ", image will not be available");
- }
+ mMaterial->matname<< ", image will not be available");
}
}
}
+
mBlendFunc[0] =0;
mBlendFunc[1] =0;
mConstructed = true;
@@ -168,7 +169,11 @@ void KX_BlenderMaterial::OnExit()
}
if( mBlenderShader ) {
- mBlenderShader->SetProg(false);
+ if(mBlenderShader == mLastBlenderShader) {
+ mBlenderShader->SetProg(false);
+ mLastBlenderShader = NULL;
+ }
+
delete mBlenderShader;
mBlenderShader = 0;
}
@@ -225,14 +230,23 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras
{
if( !enable || !mBlenderShader->Ok() ) {
// frame cleanup.
- mBlenderShader->SetProg(false);
+ if(mLastBlenderShader) {
+ mLastBlenderShader->SetProg(false);
+ mLastBlenderShader= NULL;
+ }
BL_Texture::DisableAllTextures();
return;
}
- BL_Texture::DisableAllTextures();
- mBlenderShader->SetProg(true);
- mBlenderShader->ApplyShader();
+ if(!mBlenderShader->Equals(mLastBlenderShader)) {
+ BL_Texture::DisableAllTextures();
+
+ if(mLastBlenderShader)
+ mLastBlenderShader->SetProg(false);
+
+ mBlenderShader->SetProg(true);
+ mLastBlenderShader= mBlenderShader;
+ }
}
void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras)
@@ -298,7 +312,12 @@ KX_BlenderMaterial::ActivatShaders(
// reset...
if(tmp->mMaterial->IsShared())
cachingInfo =0;
-
+
+ if(mLastBlenderShader) {
+ mLastBlenderShader->SetProg(false);
+ mLastBlenderShader= NULL;
+ }
+
if (GetCachingInfo() != cachingInfo) {
if (!cachingInfo)
@@ -372,7 +391,7 @@ KX_BlenderMaterial::ActivateBlenderShaders(
}
ActivatGLMaterials(rasty);
- mBlenderShader->SetTexCoords(rasty);
+ mBlenderShader->SetAttribs(rasty, mMaterial);
}
void
@@ -382,6 +401,12 @@ KX_BlenderMaterial::ActivateMat(
)const
{
KX_BlenderMaterial *tmp = const_cast<KX_BlenderMaterial*>(this);
+
+ if(mLastBlenderShader) {
+ mLastBlenderShader->SetProg(false);
+ mLastBlenderShader= NULL;
+ }
+
if (GetCachingInfo() != cachingInfo) {
if (!cachingInfo)
tmp->setTexData( false,rasty );
@@ -460,17 +485,29 @@ KX_BlenderMaterial::Activate(
return dopass;
}
+bool KX_BlenderMaterial::UsesLighting(RAS_IRasterizer *rasty) const
+{
+ if(!RAS_IPolyMaterial::UsesLighting(rasty))
+ return false;
+
+ if(mShader && mShader->Ok());
+ else if(mBlenderShader && mBlenderShader->Ok())
+ return false;
+
+ return true;
+}
+
void KX_BlenderMaterial::ActivateMeshSlot(const KX_MeshSlot & ms, RAS_IRasterizer* rasty) const
{
if(mShader && GLEW_ARB_shader_objects)
mShader->Update(ms, rasty);
- if(mBlenderShader && GLEW_ARB_shader_objects)
+ else if(mBlenderShader && GLEW_ARB_shader_objects)
mBlenderShader->Update(ms, rasty);
}
void KX_BlenderMaterial::ActivatGLMaterials( RAS_IRasterizer* rasty )const
{
- if(!mBlenderShader) {
+ if(mShader || !mBlenderShader) {
rasty->SetSpecularity(
mMaterial->speccolor[0]*mMaterial->spec_f,
mMaterial->speccolor[1]*mMaterial->spec_f,
@@ -506,6 +543,7 @@ void KX_BlenderMaterial::ActivateTexGen(RAS_IRasterizer *ras) const
ras->SetAttribNum(0);
if(mShader && GLEW_ARB_shader_objects) {
if(mShader->GetAttribute() == BL_Shader::SHD_TANGENT) {
+ ras->SetAttrib(RAS_IRasterizer::RAS_TEXCO_DISABLE, 0);
ras->SetAttrib(RAS_IRasterizer::RAS_TEXTANGENT, 1);
ras->SetAttribNum(2);
}
@@ -793,7 +831,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
void KX_BlenderMaterial::SetBlenderGLSLShader(void)
{
if(!mBlenderShader)
- mBlenderShader = new BL_BlenderShader(mMaterial->material);
+ mBlenderShader = new BL_BlenderShader(mMaterial->material, m_lightlayer);
if(!mBlenderShader->Ok()) {
delete mBlenderShader;
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 62e96b71937..bf6d2095e7c 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -94,6 +94,7 @@ 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;
@@ -106,6 +107,7 @@ private:
void ActivatGLMaterials( RAS_IRasterizer* rasty )const;
void ActivateTexGen( RAS_IRasterizer *ras ) const;
+ bool UsesLighting(RAS_IRasterizer *rasty) const;
// message centers
void setTexData( bool enable,RAS_IRasterizer *ras);
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index bde5e2cd0a2..2ac4f909077 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();
@@ -581,7 +572,7 @@ void KX_GameObject::SetObjectColor(const MT_Vector4& rgbavec)
m_objectColor = rgbavec;
}
-void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis)
+void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
{
MT_Matrix3x3 orimat;
MT_Vector3 vect,ori,z,x,y;
@@ -594,6 +585,11 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis)
cout << "alignAxisToVect() Error: Null vector!\n";
return;
}
+
+ if (fac<=0.0) {
+ return;
+ }
+
// normalize
vect /= len;
orimat = GetSGNode()->GetWorldOrientation();
@@ -603,7 +599,14 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis)
ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis
if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) //is the vector paralell to the pivot?
ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot!
- x = vect;
+ if (fac == 1.0) {
+ x = vect;
+ } else {
+ x = (vect * fac) + ((orimat * MT_Vector3(1.0, 0.0, 0.0)) * (1-fac));
+ len = x.length();
+ if (MT_fuzzyZero(len)) x = vect;
+ else x /= len;
+ }
y = ori.cross(x);
z = x.cross(y);
break;
@@ -611,7 +614,14 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis)
ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]);
if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON)
ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]);
- y = vect;
+ if (fac == 1.0) {
+ y = vect;
+ } else {
+ y = (vect * fac) + ((orimat * MT_Vector3(0.0, 1.0, 0.0)) * (1-fac));
+ len = y.length();
+ if (MT_fuzzyZero(len)) y = vect;
+ else y /= len;
+ }
z = ori.cross(y);
x = y.cross(z);
break;
@@ -619,7 +629,14 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis)
ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]);
if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON)
ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]);
- z = vect;
+ if (fac == 1.0) {
+ z = vect;
+ } else {
+ z = (vect * fac) + ((orimat * MT_Vector3(0.0, 0.0, 1.0)) * (1-fac));
+ len = z.length();
+ if (MT_fuzzyZero(len)) z = vect;
+ else z /= len;
+ }
x = ori.cross(z);
y = z.cross(x);
break;
@@ -1289,7 +1306,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self,
return meshproxy;
}
}
- return NULL;
+ Py_RETURN_NONE;
}
@@ -1395,13 +1412,14 @@ PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self,
{
PyObject* pyvect;
int axis = 2; //z axis is the default
+ float fac = 1.0;
- if (PyArg_ParseTuple(args,"O|i",&pyvect,&axis))
+ if (PyArg_ParseTuple(args,"O|if",&pyvect,&axis, &fac))
{
MT_Vector3 vect;
if (PyVecTo(pyvect, vect))
{
- AlignAxisToVect(vect,axis);
+ AlignAxisToVect(vect,axis,fac);
Py_RETURN_NONE;
}
}
@@ -1590,14 +1608,18 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
other = static_cast<KX_GameObject*>(pyfrom);
fromPoint = other->NodeGetWorldPosition();
}
-
- if (dist != 0.0f)
- {
+
+ if (dist != 0.0f) {
MT_Vector3 toDir = toPoint-fromPoint;
+ if (MT_fuzzyZero(toDir.length2())) {
+ return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
+ }
toDir.normalize();
toPoint = fromPoint + (dist) * toDir;
+ } else if (MT_fuzzyZero((toPoint-fromPoint).length2())) {
+ return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
}
-
+
MT_Point3 resultPoint;
MT_Vector3 resultNormal;
PHY_IPhysicsEnvironment* pe = GetPhysicsEnvironment();
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 5e44a36515d..ddbf863aa1a 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -278,7 +278,8 @@ public:
void
AlignAxisToVect(
const MT_Vector3& vect,
- int axis = 2
+ int axis = 2,
+ float fac = 1.0
);
/**
@@ -490,14 +491,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_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 56a06786679..20187a193ba 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -55,6 +55,7 @@
#include "KX_Scene.h"
#include "MT_CmMatrix4x4.h"
#include "KX_Camera.h"
+#include "KX_Light.h"
#include "KX_PythonInit.h"
#include "KX_PyConstraintBinding.h"
#include "PHY_IPhysicsEnvironment.h"
@@ -614,6 +615,9 @@ void KX_KetsjiEngine::Render()
// pass the scene's worldsettings to the rasterizer
SetWorldSettings(scene->GetWorldInfo());
+ // shadow buffers
+ RenderShadowBuffers(scene);
+
// Avoid drawing the scene with the active camera twice when it's viewport is enabled
if(cam && !cam->GetViewport())
{
@@ -885,8 +889,48 @@ void KX_KetsjiEngine::SetupRenderFrame(KX_Scene *scene, KX_Camera* cam)
viewport.GetTop()
);
-}
+}
+
+void KX_KetsjiEngine::RenderShadowBuffers(KX_Scene *scene)
+{
+ CListValue *lightlist = scene->GetLightList();
+ int i, drawmode;
+ for(i=0; i<lightlist->GetCount(); i++) {
+ KX_LightObject *light = (KX_LightObject*)lightlist->GetValue(i);
+
+ light->Update();
+
+ if(m_drawingmode == RAS_IRasterizer::KX_TEXTURED && light->HasShadowBuffer()) {
+ /* make temporary camera */
+ RAS_CameraData camdata = RAS_CameraData();
+ KX_Camera *cam = new KX_Camera(scene, scene->m_callbacks, camdata, false);
+ cam->SetName("__shadow__cam__");
+
+ MT_Transform camtrans;
+
+ /* switch drawmode for speed */
+ drawmode = m_rasterizer->GetDrawingMode();
+ m_rasterizer->SetDrawingMode(RAS_IRasterizer::KX_SHADOW);
+
+ /* binds framebuffer object, sets up camera .. */
+ light->BindShadowBuffer(m_rasterizer, cam, camtrans);
+
+ /* update scene */
+ scene->UpdateMeshTransformations();
+ scene->CalculateVisibleMeshes(m_rasterizer, cam, light->GetShadowLayer());
+
+ /* render */
+ m_rasterizer->ClearDepthBuffer();
+ scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+
+ /* unbind framebuffer object, restore drawmode, free camera */
+ light->UnbindShadowBuffer(m_rasterizer);
+ m_rasterizer->SetDrawingMode(drawmode);
+ cam->Release();
+ }
+ }
+}
// update graphics
void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h
index 4c09bc3fcd5..77b69ec2d9e 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.h
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h
@@ -179,6 +179,7 @@ private:
void RenderFrame(KX_Scene* scene, KX_Camera* cam);
void PostRenderFrame();
void RenderDebugProperties();
+ void RenderShadowBuffers(KX_Scene *scene);
void SetBackGround(KX_WorldInfo* worldinfo);
void SetWorldSettings(KX_WorldInfo* worldinfo);
void DoSound(KX_Scene* scene);
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index 7decc5bc769..4e3d6180d22 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -36,14 +36,20 @@
#endif
#include "KX_Light.h"
+#include "KX_Camera.h"
+#include "RAS_IRasterizer.h"
#include "RAS_IRenderTools.h"
#include "KX_PyMath.h"
+#ifdef BLENDER_GLSL
+#include "GPU_material.h"
+#endif
KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
class RAS_IRenderTools* rendertools,
const RAS_LightObject& lightobj,
+ struct GPULamp *gpulamp,
PyTypeObject* T
)
:
@@ -53,12 +59,12 @@ KX_LightObject::KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,
m_lightobj = lightobj;
m_lightobj.m_worldmatrix = GetOpenGLMatrixPtr();
m_rendertools->AddLight(&m_lightobj);
+ m_gpulamp = gpulamp;
};
KX_LightObject::~KX_LightObject()
{
-
m_rendertools->RemoveLight(&m_lightobj);
}
@@ -78,6 +84,78 @@ CValue* KX_LightObject::GetReplica()
return replica;
}
+void KX_LightObject::Update()
+{
+#ifdef BLENDER_GLSL
+ if(m_gpulamp) {
+ float obmat[4][4];
+ double *dobmat = GetOpenGLMatrixPtr()->getPointer();
+
+ for(int i=0; i<4; i++)
+ for(int j=0; j<4; j++, dobmat++)
+ obmat[i][j] = (float)*dobmat;
+
+ GPU_lamp_update(m_gpulamp, obmat);
+ }
+#endif
+}
+
+bool KX_LightObject::HasShadowBuffer()
+{
+#ifdef BLENDER_GLSL
+ return (m_gpulamp && GPU_lamp_has_shadow_buffer(m_gpulamp));
+#else
+ return false;
+#endif
+}
+
+int KX_LightObject::GetShadowLayer()
+{
+#ifdef BLENDER_GLSL
+ if(m_gpulamp)
+ return GPU_lamp_shadow_layer(m_gpulamp);
+ else
+#endif
+ return 0;
+}
+
+void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_Transform& camtrans)
+{
+#ifdef BLENDER_GLSL
+ float viewmat[4][4], winmat[4][4];
+ int winsize;
+
+ /* bind framebuffer */
+ GPU_lamp_shadow_buffer_bind(m_gpulamp, viewmat, &winsize, winmat);
+
+ /* setup camera transformation */
+ MT_Matrix4x4 modelviewmat((float*)viewmat);
+ MT_Matrix4x4 projectionmat((float*)winmat);
+
+ MT_Transform trans = MT_Transform((float*)viewmat);
+ camtrans.invert(trans);
+
+ cam->SetModelviewMatrix(modelviewmat);
+ cam->SetProjectionMatrix(projectionmat);
+
+ cam->NodeSetLocalPosition(camtrans.getOrigin());
+ cam->NodeSetLocalOrientation(camtrans.getBasis());
+ cam->NodeUpdateGS(0,true);
+
+ /* setup rasterizer transformations */
+ ras->SetProjectionMatrix(projectionmat);
+ ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldPosition(),
+ cam->GetCameraLocation(), cam->GetCameraOrientation());
+#endif
+}
+
+void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
+{
+#ifdef BLENDER_GLSL
+ GPU_lamp_shadow_buffer_unbind(m_gpulamp);
+#endif
+}
+
PyObject* KX_LightObject::_getattr(const STR_String& attr)
{
if (attr == "layer")
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index 236d3e4e12e..62eb26c61a8 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -32,19 +32,33 @@
#include "RAS_LightObject.h"
#include "KX_GameObject.h"
+struct GPULamp;
+class KX_Camera;
+class RAS_IRasterizer;
+class RAS_IRenderTools;
+class MT_Transform;
+
class KX_LightObject : public KX_GameObject
{
Py_Header;
protected:
RAS_LightObject m_lightobj;
class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj
+ struct GPULamp *m_gpulamp;
static char doc[];
public:
- KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, PyTypeObject *T = &Type);
+ KX_LightObject(void* sgReplicationInfo,SG_Callbacks callbacks,class RAS_IRenderTools* rendertools,const struct RAS_LightObject& lightobj, struct GPULamp *gpulamp, PyTypeObject *T = &Type);
virtual ~KX_LightObject();
virtual CValue* GetReplica();
RAS_LightObject* GetLightData() { return &m_lightobj;}
+
+ /* GLSL shadow */
+ bool HasShadowBuffer();
+ int GetShadowLayer();
+ void BindShadowBuffer(class RAS_IRasterizer *ras, class KX_Camera *cam, class MT_Transform& camtrans);
+ void UnbindShadowBuffer(class RAS_IRasterizer *ras);
+ void Update();
virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */
virtual int _setattr(const STR_String& attr, PyObject *pyvalue);
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 337b1af6df7..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();
}
@@ -886,6 +888,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
else if (bHasArmature)
{
BL_SkinDeformer* skinDeformer = new BL_SkinDeformer(
+ newobj,
oldblendobj, blendobj,
static_cast<BL_SkinMeshObject*>(mesh),
true,
@@ -897,7 +900,7 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
else if (bHasDvert)
{
BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(
- oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
+ newobj, oldblendobj, static_cast<BL_SkinMeshObject*>(mesh)
);
newobj->m_pDeformer = meshdeformer;
}
@@ -1002,12 +1005,13 @@ void KX_Scene::UpdateMeshTransformations()
}
}
-void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam)
+void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam, int layer)
{
int intersect = KX_Camera::INTERSECT;
KX_GameObject *gameobj = node->Client()?(KX_GameObject*) node->Client()->GetSGClientObject():NULL;
- bool dotest = (gameobj && gameobj->GetVisible()) || node->Left() || node->Right();
-
+ bool visible = (gameobj && gameobj->GetVisible() && (!layer || (gameobj->GetLayer() & layer)));
+ bool dotest = visible || node->Left() || node->Right();
+
/* If the camera is inside the box, assume intersect. */
if (dotest && !node->inside( cam->NodeGetWorldPosition()))
{
@@ -1031,19 +1035,19 @@ void KX_Scene::MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera* cam
break;
case KX_Camera::INTERSECT:
if (gameobj)
- MarkVisible(rasty, gameobj,cam);
+ MarkVisible(rasty, gameobj, cam, layer);
if (node->Left())
- MarkVisible(node->Left(), rasty,cam);
+ MarkVisible(node->Left(), rasty, cam, layer);
if (node->Right())
- MarkVisible(node->Right(), rasty,cam);
+ MarkVisible(node->Right(), rasty, cam, layer);
break;
case KX_Camera::INSIDE:
- MarkSubTreeVisible(node, rasty, true,cam);
+ MarkSubTreeVisible(node, rasty, true, cam, layer);
break;
}
}
-void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible,KX_Camera* cam)
+void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera* cam, int layer)
{
if (node->Client())
{
@@ -1066,16 +1070,23 @@ void KX_Scene::MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool vi
}
}
if (node->Left())
- MarkSubTreeVisible(node->Left(), rasty, visible,cam);
+ MarkSubTreeVisible(node->Left(), rasty, visible, cam, layer);
if (node->Right())
- MarkSubTreeVisible(node->Right(), rasty, visible,cam);
+ MarkSubTreeVisible(node->Right(), rasty, visible, cam, layer);
}
-void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam)
+void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Camera* cam,int layer)
{
// User (Python/Actuator) has forced object invisible...
if (!gameobj->GetVisible())
return;
+
+ // Shadow lamp layers
+ if(layer && !(gameobj->GetLayer() & layer)) {
+ gameobj->MarkVisible(false);
+ return;
+ }
+
// If Frustum culling is off, the object is always visible.
bool vis = !cam->GetFrustumCulling();
@@ -1125,20 +1136,20 @@ void KX_Scene::MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj,KX_Cam
}
}
-void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam)
+void KX_Scene::CalculateVisibleMeshes(RAS_IRasterizer* rasty,KX_Camera* cam, int layer)
{
// FIXME: When tree is operational
#if 1
// do this incrementally in the future
for (int i = 0; i < m_objectlist->GetCount(); i++)
{
- MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam);
+ MarkVisible(rasty, static_cast<KX_GameObject*>(m_objectlist->GetValue(i)), cam, layer);
}
#else
if (cam->GetFrustumCulling())
- MarkVisible(m_objecttree, rasty, cam);
+ MarkVisible(m_objecttree, rasty, cam, layer);
else
- MarkSubTreeVisible(m_objecttree, rasty, true, cam);
+ MarkSubTreeVisible(m_objecttree, rasty, true, cam, layer);
#endif
}
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 733df2f69a1..28dee1b5893 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -260,9 +260,9 @@ protected:
/**
* Visibility testing functions.
*/
- void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam);
- void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam);
- void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam);
+ void MarkVisible(SG_Tree *node, RAS_IRasterizer* rasty, KX_Camera*cam,int layer=0);
+ void MarkSubTreeVisible(SG_Tree *node, RAS_IRasterizer* rasty, bool visible, KX_Camera*cam,int layer=0);
+ void MarkVisible(RAS_IRasterizer* rasty, KX_GameObject* gameobj, KX_Camera*cam, int layer=0);
double m_suspendedtime;
double m_suspendeddelta;
@@ -483,7 +483,7 @@ public:
void SetNetworkScene(NG_NetworkScene *newScene);
void SetWorldInfo(class KX_WorldInfo* wi);
KX_WorldInfo* GetWorldInfo();
- void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam);
+ void CalculateVisibleMeshes(RAS_IRasterizer* rasty, KX_Camera *cam, int layer=0);
void UpdateMeshTransformations();
KX_Camera* GetpCamera();
SND_Scene* GetSoundScene();
diff --git a/source/gameengine/Ketsji/KX_TouchEventManager.cpp b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
index 80ee15a9475..423543eef5c 100644
--- a/source/gameengine/Ketsji/KX_TouchEventManager.cpp
+++ b/source/gameengine/Ketsji/KX_TouchEventManager.cpp
@@ -137,14 +137,18 @@ void KX_TouchEventManager::NextFrame()
// KX_GameObject* gameOb1 = ctrl1->getClientInfo();
KX_ClientObjectInfo *client_info = static_cast<KX_ClientObjectInfo *>(ctrl1->getNewClientInfo());
-
list<SCA_ISensor*>::iterator sit;
- for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit)
- static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL);
-
+ if (client_info) {
+ for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) {
+ static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).first, (*cit).second, NULL);
+ }
+ }
client_info = static_cast<KX_ClientObjectInfo *>((*cit).second->getNewClientInfo());
- for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit)
- static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL);
+ if (client_info) {
+ for ( sit = client_info->m_sensors.begin(); sit != client_info->m_sensors.end(); ++sit) {
+ static_cast<KX_TouchSensor*>(*sit)->NewHandleCollision((*cit).second, (*cit).first, NULL);
+ }
+ }
}
m_newCollisions.clear();
diff --git a/source/gameengine/PyDoc/BL_ActionActuator.py b/source/gameengine/PyDoc/BL_ActionActuator.py
index 41f41080c31..d56888cde80 100644
--- a/source/gameengine/PyDoc/BL_ActionActuator.py
+++ b/source/gameengine/PyDoc/BL_ActionActuator.py
@@ -86,6 +86,14 @@ class BL_ActionActuator(SCA_IActuator):
@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():
"""
@@ -94,6 +102,13 @@ class BL_ActionActuator(SCA_IActuator):
@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():
"""
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
index 50df1a1e2ea..b4492ca03a9 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -109,7 +109,7 @@ void RAS_BucketManager::RenderAlphaBuckets(
// it is needed for compatibility.
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED);
- int drawingmode;
+ RAS_IRasterizer::DrawMode drawingmode;
std::multiset< alphamesh, backtofront>::iterator msit = alphameshset.begin();
for (; msit != alphameshset.end(); ++msit)
{
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index bff98abe058..cb10ba6bf37 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -27,6 +27,7 @@
*/
#include "RAS_IPolygonMaterial.h"
+#include "RAS_IRasterizer.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -148,4 +149,19 @@ const unsigned int RAS_IPolyMaterial::GetFlag() const
return m_flag;
}
+bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const
+{
+ bool dolights = false;
+
+ if(m_flag & RAS_BLENDERMAT)
+ dolights = (m_flag &RAS_MULTILIGHT)!=0;
+ else if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID);
+ else if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW);
+ else
+ dolights = (m_drawingmode & 16)!=0;
+
+ return dolights;
+}
+
unsigned int RAS_IPolyMaterial::m_newpolymatid = 0;
+
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 09824f6975c..d2d1dba99d9 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -140,6 +140,8 @@ public:
const STR_String& GetMaterialName() const;
const STR_String& GetTextureName() const;
const unsigned int GetFlag() const;
+
+ virtual bool UsesLighting(RAS_IRasterizer *rasty) const;
/*
* PreCalculate texture gen
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index dbedc492afa..d4a9177a85d 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -33,12 +33,23 @@
#pragma warning (disable:4786)
#endif
+#include "STR_HashedString.h"
+
#include "MT_CmMatrix4x4.h"
#include "MT_Matrix4x4.h"
+#include "RAS_TexVert.h"
+
+#include <vector>
+using namespace std;
+
class RAS_ICanvas;
class RAS_IPolyMaterial;
-#include "RAS_MaterialBucket.h"
+
+typedef vector<unsigned short> KX_IndexArray;
+typedef vector<RAS_TexVert> KX_VertexArray;
+typedef vector< KX_VertexArray* > vecVertexArray;
+typedef vector< KX_IndexArray* > vecIndexArrays;
/**
* 3D rendering device context interface.
@@ -62,7 +73,18 @@ public:
KX_WIREFRAME,
KX_SOLID,
KX_SHADED,
- KX_TEXTURED
+ KX_TEXTURED,
+ KX_SHADOW
+ };
+
+ /**
+ * Drawing modes
+ */
+
+ enum DrawMode {
+ KX_MODE_LINES = 1,
+ KX_MODE_TRIANGLES,
+ KX_MODE_QUADS
};
/**
@@ -111,6 +133,7 @@ public:
RAS_TEXCO_NORM, //< Normal coordinates
RAS_TEXTANGENT, //<
RAS_TEXCO_UV2, //<
+ RAS_TEXCO_VCOL, //< Vertex Color
RAS_TEXCO_DISABLE //< Disable this texture unit (cached)
};
@@ -197,45 +220,37 @@ public:
* IndexPrimitives: Renders primitives.
* @param vertexarrays is an array of vertex arrays
* @param indexarrays is an array of index arrays
- * @param mode determines the type of primitive stored in the vertex/index arrays:
- * 0 triangles
- * 1 lines (default)
- * 2 quads
- * @param polymat (reserved)
+ * @param mode determines the type of primitive stored in the vertex/index arrays
* @param useObjectColor will render the object using @param rgbacolor instead of
* vertex colors.
*/
- virtual void IndexPrimitives( const vecVertexArray& vertexarrays,
+ virtual void IndexPrimitives( const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot)=0;
+ virtual void IndexPrimitivesMulti(
+ const vecVertexArray& vertexarrays,
+ const vecIndexArrays & indexarrays,
+ DrawMode mode,
+ bool useObjectColor,
+ const MT_Vector4& rgbacolor,
+ class KX_ListSlot** slot)=0;
+
/**
* IndexPrimitives_3DText will render text into the polygons.
* The text to be rendered is from @param rendertools client object's text property.
*/
virtual void IndexPrimitives_3DText( const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
+ DrawMode mode,
class RAS_IPolyMaterial* polymat,
class RAS_IRenderTools* rendertools,
bool useObjectColor,
const MT_Vector4& rgbacolor)=0;
- virtual void IndexPrimitivesMulti(
- const vecVertexArray& vertexarrays,
- const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
- bool useObjectColor,
- const MT_Vector4& rgbacolor,
- class KX_ListSlot** slot)=0;
-
virtual void SetProjectionMatrix(MT_CmMatrix4x4 & mat)=0;
/* This one should become our final version, methinks. */
/**
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index 1beade7acf7..e295d69e48e 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -167,38 +167,30 @@ RAS_MaterialBucket::T_MeshSlotList::iterator RAS_MaterialBucket::msEnd()
}
bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
- RAS_IRenderTools *rendertools, int &drawmode)
+ RAS_IRenderTools *rendertools, RAS_IRasterizer::DrawMode &drawmode)
{
rendertools->SetViewMat(cameratrans);
if (!rasty->SetMaterial(*m_material))
return false;
- bool dolights = false;
- const unsigned int flag = m_material->GetFlag();
-
- if( flag & RAS_BLENDERMAT)
- dolights = (flag &RAS_MULTILIGHT)!=0;
+ if (m_material->UsesLighting(rasty))
+ rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER/*m_material->GetLightLayer()*/);
else
- dolights = (m_material->GetDrawingMode()&16)!=0;
-
- if ((rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID) || !dolights)
- {
rendertools->ProcessLighting(-1);
- }
- else
- {
- rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER/*m_material->GetLightLayer()*/);
- }
- drawmode = (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID ?
- 1: (m_material->UsesTriangles() ? 0 : 2));
+ if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID)
+ drawmode = RAS_IRasterizer::KX_MODE_LINES;
+ else if(m_material->UsesTriangles())
+ drawmode = RAS_IRasterizer::KX_MODE_TRIANGLES;
+ else
+ drawmode = RAS_IRasterizer::KX_MODE_QUADS;
return true;
}
void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
- RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode)
+ RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, RAS_IRasterizer::DrawMode drawmode)
{
if (!ms.m_bVisible)
return;
@@ -225,6 +217,17 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
ms.m_DisplayList->SetModified(ms.m_mesh->MeshModified());
}
+ // verify if we can use display list, not for deformed object, and
+ // also don't create a new display list when drawing shadow buffers,
+ // then it won't have texture coordinates for actual drawing
+ KX_ListSlot **displaylist;
+ if(ms.m_pDeformer)
+ displaylist = 0;
+ else if(!ms.m_DisplayList && rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW)
+ displaylist = 0;
+ else
+ displaylist = &ms.m_DisplayList;
+
// Use the text-specific IndexPrimitives for text faces
if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT)
{
@@ -245,12 +248,9 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
ms.m_mesh->GetVertexCache(m_material),
ms.m_mesh->GetIndexCache(m_material),
drawmode,
- m_material,
- rendertools,
ms.m_bObjectColor,
ms.m_RGBAcolor,
- (ms.m_pDeformer)? 0: &ms.m_DisplayList
- );
+ displaylist);
}
// Use the normal IndexPrimitives
@@ -260,12 +260,9 @@ void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRa
ms.m_mesh->GetVertexCache(m_material),
ms.m_mesh->GetIndexCache(m_material),
drawmode,
- m_material,
- rendertools, // needed for textprinting on polys
ms.m_bObjectColor,
ms.m_RGBAcolor,
- (ms.m_pDeformer)? 0: &ms.m_DisplayList
- );
+ displaylist);
}
if(rasty->QueryLists()) {
@@ -287,7 +284,7 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans,
//rasty->SetMaterial(*m_material);
- int drawmode;
+ RAS_IRasterizer::DrawMode drawmode;
for (T_MeshSlotList::const_iterator it = m_meshSlots.begin();
! (it == m_meshSlots.end()); ++it)
{
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
index 5ad0c173a56..13d8a53714a 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
@@ -35,17 +35,13 @@
#include "MT_Transform.h"
#include "RAS_IPolygonMaterial.h"
+#include "RAS_IRasterizer.h"
#include "RAS_Deformer.h" // __NLA
#include <vector>
#include <map>
#include <set>
using namespace std;
-typedef vector<unsigned short> KX_IndexArray;
-typedef vector<RAS_TexVert> KX_VertexArray;
-typedef vector< KX_VertexArray* > vecVertexArray;
-typedef vector< KX_IndexArray* > vecIndexArrays;
-
/**
* KX_VertexIndex
*/
@@ -146,9 +142,9 @@ public:
const MT_Vector4& rgbavec);
void RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
- RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode);
+ RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, RAS_IRasterizer::DrawMode drawmode);
bool ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
- RAS_IRenderTools *rendertools, int &drawmode);
+ RAS_IRenderTools *rendertools, RAS_IRasterizer::DrawMode& drawmode);
unsigned int NumMeshSlots();
T_MeshSlotList::iterator msBegin();
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index d7ab88a6b06..4420f16c56d 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -68,8 +68,8 @@ RAS_MeshObject::RAS_MeshObject(Mesh* mesh, int lightlayer)
m_lightlayer(lightlayer),
m_zsort(false),
m_MeshMod(true),
- m_class(0),
- m_mesh(mesh)
+ m_mesh(mesh),
+ m_class(0)
{
}
@@ -259,18 +259,18 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray,
const MT_Vector3& normal,
bool flat,
RAS_IPolyMaterial* mat,
- int orgindex)
+ int origindex)
{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
int numverts = ao->m_VertexArrayCache1[vtxarray]->size();//m_VertexArrayCount[vtxarray];
- RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0);
+ RAS_TexVert newvert(xyz,uv,uv2,tangent,rgbacolor,normal, flat? TV_CALCFACENORMAL: 0,origindex);
#define KX_FIND_SHARED_VERTICES
#ifdef KX_FIND_SHARED_VERTICES
if(!flat) {
- for (std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[orgindex].begin();
- it != m_xyz_index_to_vertex_index_mapping[orgindex].end();
+ for (std::vector<RAS_MatArrayIndex>::iterator it = m_xyz_index_to_vertex_index_mapping[origindex].begin();
+ it != m_xyz_index_to_vertex_index_mapping[origindex].end();
it++)
{
if ((*it).m_arrayindex1 == ao->m_index1 &&
@@ -293,22 +293,18 @@ int RAS_MeshObject::FindOrAddVertex(int vtxarray,
idx.m_array = vtxarray;
idx.m_index = numverts;
idx.m_matid = mat;
- m_xyz_index_to_vertex_index_mapping[orgindex].push_back(idx);
+ m_xyz_index_to_vertex_index_mapping[origindex].push_back(idx);
return numverts;
}
-
-
-const vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat)
+vecVertexArray& RAS_MeshObject::GetVertexCache (RAS_IPolyMaterial* mat)
{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
return ao->m_VertexArrayCache1;
}
-
-
int RAS_MeshObject::GetVertexArrayLength(RAS_IPolyMaterial* mat)
{
int len = 0;
@@ -362,7 +358,7 @@ RAS_TexVert* RAS_MeshObject::GetVertex(unsigned int matid,
const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat)
{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);//*(m_matVertexArrays[*mat]);
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
return ao->m_IndexArrayCache1;
}
@@ -371,16 +367,27 @@ const vecIndexArrays& RAS_MeshObject::GetIndexCache (RAS_IPolyMaterial* mat)
KX_ArrayOptimizer* RAS_MeshObject::GetArrayOptimizer(RAS_IPolyMaterial* polymat)
{
- KX_ArrayOptimizer** aop = (m_matVertexArrayS[*polymat]);
+ KX_ArrayOptimizer** aop = m_matVertexArrayS[polymat];
- if (aop)
+ if(aop)
return *aop;
+ // didn't find array, but an array might already exist
+ // for a material equal to this one
+ for(int i=0;i<m_matVertexArrayS.size();i++) {
+ RAS_IPolyMaterial *mat = (RAS_IPolyMaterial*)(m_matVertexArrayS.getKey(i)->getValue());
+ if(*mat == *polymat) {
+ m_matVertexArrayS.insert(polymat, *m_matVertexArrayS.at(i));
+ return *m_matVertexArrayS.at(i);
+ }
+ }
+
+ // create new array
int numelements = m_matVertexArrayS.size();
m_sortedMaterials.push_back(polymat);
-
+
KX_ArrayOptimizer* ao = new KX_ArrayOptimizer(numelements);
- m_matVertexArrayS.insert(*polymat,ao);
+ m_matVertexArrayS.insert(polymat, ao);
return ao;
}
@@ -463,7 +470,7 @@ RAS_TexVert* RAS_MeshObject::GetVertex(short array,
unsigned int index,
RAS_IPolyMaterial* polymat)
{
- KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);//*(m_matVertexArrays[*polymat]);
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(polymat);
return &((*(ao->m_VertexArrayCache1)[array])[index]);
}
@@ -471,13 +478,19 @@ RAS_TexVert* RAS_MeshObject::GetVertex(short array,
void RAS_MeshObject::ClearArrayData()
{
- for (int i=0;i<m_matVertexArrayS.size();i++)
- {
+ for (int i=0;i<m_matVertexArrayS.size();i++) {
KX_ArrayOptimizer** ao = m_matVertexArrayS.at(i);
+
+ // we have duplicate entries, only free once
+ for(int j=i+1;j<m_matVertexArrayS.size();j++) {
+ if(ao == m_matVertexArrayS.at(j)) {
+ ao = NULL;
+ break;
+ }
+ }
+
if (ao)
- {
delete *ao;
- }
}
}
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index d9aa133efb2..0d06748f91f 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -142,7 +142,7 @@ protected:
enum { BUCKET_MAX_INDICES = 65535 };//2048};//8192};
enum { BUCKET_MAX_TRIANGLES = 65535 };
- GEN_Map<class RAS_IPolyMaterial,KX_ArrayOptimizer*> m_matVertexArrayS;
+ GEN_Map<GEN_HashedPtr,KX_ArrayOptimizer*> m_matVertexArrayS;
RAS_MaterialBucket::Set m_materials;
Mesh* m_mesh;
@@ -242,10 +242,10 @@ public:
const MT_Vector3& normal,
bool flat,
RAS_IPolyMaterial* mat,
- int orgindex
+ int origindex
);
- const vecVertexArray& GetVertexCache (RAS_IPolyMaterial* mat);
+ vecVertexArray& GetVertexCache (RAS_IPolyMaterial* mat);
int GetVertexArrayLength(RAS_IPolyMaterial* mat);
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
index 39080b80492..c2687319717 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.cpp
@@ -161,9 +161,7 @@ void RAS_ListRasterizer::ReleaseAlloc()
void RAS_ListRasterizer::IndexPrimitives(
const vecVertexArray & vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot)
@@ -185,15 +183,13 @@ void RAS_ListRasterizer::IndexPrimitives(
if (mUseVertexArrays) {
RAS_VAOpenGLRasterizer::IndexPrimitives(
vertexarrays, indexarrays,
- mode, polymat,
- rendertools, useObjectColor,
+ mode, useObjectColor,
rgbacolor,slot
);
} else {
RAS_OpenGLRasterizer::IndexPrimitives(
vertexarrays, indexarrays,
- mode, polymat,
- rendertools, useObjectColor,
+ mode, useObjectColor,
rgbacolor,slot
);
}
@@ -208,9 +204,7 @@ void RAS_ListRasterizer::IndexPrimitives(
void RAS_ListRasterizer::IndexPrimitivesMulti(
const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot)
@@ -230,18 +224,19 @@ void RAS_ListRasterizer::IndexPrimitivesMulti(
}
}
- if (mUseVertexArrays) {
+ // workaround: note how we do not use vertex arrays for making display
+ // lists, since glVertexAttribPointerARB doesn't seem to work correct
+ // in display lists on ATI? either a bug in the driver or in Blender ..
+ if (mUseVertexArrays && !localSlot) {
RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(
vertexarrays, indexarrays,
- mode, polymat,
- rendertools, useObjectColor,
+ mode, useObjectColor,
rgbacolor,slot
);
} else {
RAS_OpenGLRasterizer::IndexPrimitivesMulti(
vertexarrays, indexarrays,
- mode, polymat,
- rendertools, useObjectColor,
+ mode, useObjectColor,
rgbacolor,slot
);
}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
index 4b3304d7396..b1b19144c12 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_ListRasterizer.h
@@ -52,9 +52,7 @@ public:
virtual void IndexPrimitives(
const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot
@@ -63,9 +61,7 @@ public:
virtual void IndexPrimitivesMulti(
const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 18147b53f4c..dcc36bf5a39 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -368,23 +368,11 @@ void RAS_OpenGLRasterizer::SetDrawingMode(int drawingmode)
switch (m_drawingmode)
{
- case KX_BOUNDINGBOX:
- {
- }
case KX_WIREFRAME:
{
glDisable (GL_CULL_FACE);
break;
}
- case KX_TEXTURED:
- {
- }
- case KX_SHADED:
- {
- }
- case KX_SOLID:
- {
- }
default:
{
}
@@ -603,33 +591,14 @@ void RAS_OpenGLRasterizer::GetViewMatrix(MT_Matrix4x4 &mat) const
void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot
)
{
- GLenum drawmode;
- switch (mode)
- {
- case 0:
- drawmode = GL_TRIANGLES;
- break;
- case 1:
- drawmode = GL_LINES;
- break;
- case 2:
- drawmode = GL_QUADS;
- break;
- default:
- drawmode = GL_LINES;
- break;
- }
-
- const RAS_TexVert* vertexarray ;
- unsigned int numindices,vt;
+ const RAS_TexVert* vertexarray;
+ unsigned int numindices, vt;
for (vt=0;vt<vertexarrays.size();vt++)
{
@@ -643,7 +612,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
int vindex=0;
switch (mode)
{
- case 1:
+ case KX_MODE_LINES:
{
glBegin(GL_LINES);
vindex=0;
@@ -655,7 +624,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
glEnd();
}
break;
- case 2:
+ case KX_MODE_QUADS:
{
glBegin(GL_QUADS);
vindex=0;
@@ -723,7 +692,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
glEnd();
break;
}
- case 0:
+ case KX_MODE_TRIANGLES:
{
glBegin(GL_TRIANGLES);
vindex=0;
@@ -788,32 +757,14 @@ void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
+ DrawMode mode,
class RAS_IPolyMaterial* polymat,
class RAS_IRenderTools* rendertools,
bool useObjectColor,
const MT_Vector4& rgbacolor
)
{
- GLenum drawmode;
- switch (mode)
- {
- case 0:
- drawmode = GL_TRIANGLES;
- break;
- case 1:
- drawmode = GL_LINES;
- break;
- case 2:
- drawmode = GL_QUADS;
- break;
- default:
- drawmode = GL_LINES;
- break;
- }
-
- const RAS_TexVert* vertexarray ;
-
+ const RAS_TexVert* vertexarray;
unsigned int numindices, vt;
if (useObjectColor)
@@ -838,7 +789,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa
int vindex=0;
switch (mode)
{
- case 1:
+ case KX_MODE_LINES:
{
glBegin(GL_LINES);
vindex=0;
@@ -850,7 +801,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa
glEnd();
}
break;
- case 2:
+ case KX_MODE_QUADS:
{
vindex=0;
for (unsigned int i=0;i<numindices;i+=4)
@@ -883,7 +834,7 @@ void RAS_OpenGLRasterizer::IndexPrimitives_3DText(const vecVertexArray & vertexa
}
break;
}
- case 0:
+ case KX_MODE_TRIANGLES:
{
glBegin(GL_TRIANGLES);
vindex=0;
@@ -999,6 +950,9 @@ void RAS_OpenGLRasterizer::TexCoord(const RAS_TexVert &tv)
case RAS_TEXCO_UV2:
glVertexAttrib2fvARB(unit, tv.getUV2());
break;
+ case RAS_TEXCO_VCOL:
+ glVertexAttrib4ubvARB(unit, tv.getRGBA());
+ break;
default:
break;
}
@@ -1037,32 +991,14 @@ void RAS_OpenGLRasterizer::Tangent( const RAS_TexVert& v1,
void RAS_OpenGLRasterizer::IndexPrimitivesMulti(
const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot
)
{
- GLenum drawmode;
- switch (mode)
- {
- case 0:
- drawmode = GL_TRIANGLES;
- break;
- case 1:
- drawmode = GL_LINES;
- break;
- case 2:
- drawmode = GL_QUADS;
- break;
- default:
- drawmode = GL_LINES;
- break;
- }
- const RAS_TexVert* vertexarray ;
+ const RAS_TexVert* vertexarray;
unsigned int numindices,vt;
for (vt=0;vt<vertexarrays.size();vt++)
@@ -1077,7 +1013,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti(
int vindex=0;
switch (mode)
{
- case 1:
+ case KX_MODE_LINES:
{
glBegin(GL_LINES);
vindex=0;
@@ -1089,7 +1025,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti(
glEnd();
}
break;
- case 2:
+ case KX_MODE_QUADS:
{
glBegin(GL_QUADS);
vindex=0;
@@ -1166,7 +1102,7 @@ void RAS_OpenGLRasterizer::IndexPrimitivesMulti(
glEnd();
break;
}
- case 0:
+ case KX_MODE_TRIANGLES:
{
glBegin(GL_TRIANGLES);
vindex=0;
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index 1f0709e081a..0d54552db05 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -148,9 +148,7 @@ public:
virtual void IndexPrimitives(
const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot
@@ -159,7 +157,7 @@ public:
virtual void IndexPrimitives_3DText(
const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
+ DrawMode mode,
class RAS_IPolyMaterial* polymat,
class RAS_IRenderTools* rendertools,
bool useObjectColor,
@@ -169,9 +167,7 @@ public:
virtual void IndexPrimitivesMulti(
const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot);
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
index c4702fe5a74..c78a97ad7be 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp
@@ -59,9 +59,9 @@ bool RAS_VAOpenGLRasterizer::Init(void)
if (result)
{
glEnableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
@@ -77,13 +77,16 @@ void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
{
case KX_BOUNDINGBOX:
case KX_WIREFRAME:
- glDisable (GL_CULL_FACE);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisable(GL_CULL_FACE);
+ break;
+ case KX_SOLID:
+ glDisableClientState(GL_COLOR_ARRAY);
break;
case KX_TEXTURED:
case KX_SHADED:
+ case KX_SHADOW:
glEnableClientState(GL_COLOR_ARRAY);
- case KX_SOLID:
- break;
default:
break;
}
@@ -102,30 +105,23 @@ void RAS_VAOpenGLRasterizer::Exit()
void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot)
{
static const GLsizei vtxstride = sizeof(RAS_TexVert);
GLenum drawmode;
- switch (mode)
- {
- case 0:
- drawmode = GL_TRIANGLES;
- break;
- case 2:
- drawmode = GL_QUADS;
- break;
- case 1: //lines
- default:
- drawmode = GL_LINES;
- break;
- }
+ if(mode == KX_MODE_TRIANGLES)
+ drawmode = GL_TRIANGLES;
+ else if(mode == KX_MODE_QUADS)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
const RAS_TexVert* vertexarray;
unsigned int numindices, vt;
+
if (drawmode != GL_LINES)
{
if (useObjectColor)
@@ -157,9 +153,10 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays
continue;
glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ());
- glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1());
- glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA());
glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal());
+ glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1());
+ if(glIsEnabled(GL_COLOR_ARRAY))
+ glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA());
//if(m_Lock)
// local->Begin(vertexarrays[vt]->size());
@@ -169,8 +166,6 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays
//if(m_Lock)
// local->End();
-
-
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -178,28 +173,21 @@ void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays
void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot)
{
static const GLsizei vtxstride = sizeof(RAS_TexVert);
+
GLenum drawmode;
- switch (mode)
- {
- case 0:
- drawmode = GL_TRIANGLES;
- break;
- case 2:
- drawmode = GL_QUADS;
- break;
- case 1: //lines
- default:
- drawmode = GL_LINES;
- break;
- }
+ if(mode == KX_MODE_TRIANGLES)
+ drawmode = GL_TRIANGLES;
+ else if(mode == KX_MODE_QUADS)
+ drawmode = GL_QUADS;
+ else
+ drawmode = GL_LINES;
+
const RAS_TexVert* vertexarray;
unsigned int numindices, vt;
@@ -232,10 +220,10 @@ void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexa
continue;
glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ());
- TexCoordPtr(vertexarray);
-
- glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA());
glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal());
+ TexCoordPtr(vertexarray);
+ if(glIsEnabled(GL_COLOR_ARRAY))
+ glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA());
//if(m_Lock)
// local->Begin(vertexarrays[vt]->size());
@@ -296,19 +284,22 @@ void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv)
switch(m_attrib[unit]) {
case RAS_TEXCO_ORCO:
case RAS_TEXCO_GLOB:
- glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getLocalXYZ());
+ glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getLocalXYZ());
break;
case RAS_TEXCO_UV1:
- glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1());
+ glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1());
break;
case RAS_TEXCO_NORM:
- glVertexAttribPointer(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
+ glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal());
break;
case RAS_TEXTANGENT:
- glVertexAttribPointer(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
+ glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent());
break;
case RAS_TEXCO_UV2:
- glVertexAttribPointer(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2());
+ glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2());
+ break;
+ case RAS_TEXCO_VCOL:
+ glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA());
break;
default:
break;
@@ -386,11 +377,12 @@ void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
case RAS_TEXCO_NORM:
case RAS_TEXTANGENT:
case RAS_TEXCO_UV2:
- if(enable) glEnableVertexAttribArray(unit);
- else glDisableVertexAttribArray(unit);
+ case RAS_TEXCO_VCOL:
+ if(enable) glEnableVertexAttribArrayARB(unit);
+ else glDisableVertexAttribArrayARB(unit);
break;
default:
- glDisableVertexAttribArray(unit);
+ glDisableVertexAttribArrayARB(unit);
break;
}
}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
index ea08887028f..e4cc4ace0e8 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.h
@@ -52,9 +52,7 @@ public:
virtual void IndexPrimitives( const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot);
@@ -62,9 +60,7 @@ public:
virtual void IndexPrimitivesMulti(
const vecVertexArray& vertexarrays,
const vecIndexArrays & indexarrays,
- int mode,
- class RAS_IPolyMaterial* polymat,
- class RAS_IRenderTools* rendertools,
+ DrawMode mode,
bool useObjectColor,
const MT_Vector4& rgbacolor,
class KX_ListSlot** slot);
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp
index 61ac456b2bc..935633dc636 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.cpp
+++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp
@@ -40,7 +40,8 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
- const short flag)
+ const short flag,
+ const unsigned int origindex)
{
xyz.getValue(m_localxyz);
uv.getValue(m_uv1);
@@ -49,6 +50,7 @@ RAS_TexVert::RAS_TexVert(const MT_Point3& xyz,
SetNormal(normal);
tangent.getValue(m_tangent);
m_flag = flag;
+ m_origindex = origindex;
m_unit = 2;
}
@@ -107,44 +109,6 @@ void RAS_TexVert::SetNormal(const MT_Vector3& normal)
normal.getValue(m_normal);
}
-#ifndef RAS_TexVert_INLINE
-
-// leave multiline for debugging
-const float* RAS_TexVert::getUV1 () const
-{
- return m_uv1;
-}
-
-const float* RAS_TexVert::getUV2 () const
-{
- return m_uv2;
-}
-
-
-
-const float* RAS_TexVert::getNormal() const
-{
- return m_normal;
-}
-
-const float* RAS_TexVert::getTangent() const
-{
- return m_tangent;
-}
-
-
-const float* RAS_TexVert::getLocalXYZ() const
-{
- return m_localxyz;
-}
-
-const unsigned char* RAS_TexVert::getRGBA() const
-{
- return (unsigned char*) &m_rgba;
-}
-
-#endif
-
// compare two vertices, and return TRUE if both are almost identical (they can be shared)
bool RAS_TexVert::closeTo(const RAS_TexVert* other)
{
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h
index 84135db918f..bf092b4b230 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.h
+++ b/source/gameengine/Rasterizer/RAS_TexVert.h
@@ -42,8 +42,6 @@ static MT_Point2 g_pt2;
#define TV_MAX 3//match Def in BL_Material.h
-#define RAS_TexVert_INLINE 1
-
class RAS_TexVert
{
@@ -55,9 +53,10 @@ class RAS_TexVert
float m_normal[3]; // 3*2 = 6
short m_flag; // 2
unsigned int m_unit; // 4
+ unsigned int m_origindex; // 4
//---------
- // 52
- //32 bytes total size, fits nice = 52 = not fit nice.
+ // 56
+ // 32 bytes total size, fits nice = 56 = not fit nice.
// We'll go for 64 bytes total size - 24 bytes left.
public:
short getFlag() const;
@@ -71,11 +70,10 @@ public:
const MT_Vector4& tangent,
const unsigned int rgba,
const MT_Vector3& normal,
- const short flag);
+ const short flag,
+ const unsigned int origindex);
~RAS_TexVert() {};
- // leave multiline for debugging
-#ifdef RAS_TexVert_INLINE
const float* getUV1 () const {
return m_uv1;
};
@@ -99,13 +97,11 @@ public:
const unsigned char* getRGBA() const {
return (unsigned char *) &m_rgba;
}
-#else
- const float* getUV1 () const;
- const float* getUV2 () const;
- const float* getNormal() const;
- const float* getLocalXYZ() const;
- const unsigned char* getRGBA() const;
-#endif
+
+ const unsigned int getOrigIndex() const {
+ return m_origindex;
+ }
+
void SetXYZ(const MT_Point3& xyz);
void SetUV(const MT_Point2& uv);
void SetUV2(const MT_Point2& uv);
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,
diff --git a/source/kernel/gen_system/GEN_HashedPtr.h b/source/kernel/gen_system/GEN_HashedPtr.h
index 777ec76e067..13faa5f227b 100644
--- a/source/kernel/gen_system/GEN_HashedPtr.h
+++ b/source/kernel/gen_system/GEN_HashedPtr.h
@@ -39,6 +39,7 @@ public:
GEN_HashedPtr(void* val) : m_valptr(val) {};
unsigned int hash() const { return GEN_Hash(m_valptr);};
inline friend bool operator ==(const GEN_HashedPtr & rhs, const GEN_HashedPtr & lhs) { return rhs.m_valptr == lhs.m_valptr;};
+ void *getValue() const { return m_valptr; }
};
#endif //__GEN_HASHEDPTR
diff --git a/source/kernel/gen_system/GEN_Map.h b/source/kernel/gen_system/GEN_Map.h
index f9c14800499..37c75d8293a 100644
--- a/source/kernel/gen_system/GEN_Map.h
+++ b/source/kernel/gen_system/GEN_Map.h
@@ -82,6 +82,24 @@ public:
}
return 0;
}
+
+ Key* getKey(int index) {
+ int count=0;
+ for (int i=0;i<m_num_buckets;i++)
+ {
+ Entry* bucket = m_buckets[i];
+ while(bucket)
+ {
+ if (count==index)
+ {
+ return &bucket->m_key;
+ }
+ bucket = bucket->m_next;
+ count++;
+ }
+ }
+ return 0;
+ }
void clear() {
for (int i = 0; i < m_num_buckets; ++i) {