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:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2008-07-13 17:21:01 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2008-07-13 17:21:01 +0400
commit70730c722679653d6accbb0ce36840ed84baf739 (patch)
treee857975f39f0c7365da1993407d954f49f3aaf80 /source
parent7d6e004153e356101bb37be4fb6867791eb7b251 (diff)
svn merge -r 15392:15551 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_bmesh.h21
-rw-r--r--source/blender/blenkernel/BKE_bmeshCustomData.h4
-rw-r--r--source/blender/blenkernel/BKE_cloth.h2
-rw-r--r--source/blender/blenkernel/BKE_customdata.h29
-rw-r--r--source/blender/blenkernel/intern/BME_Customdata.c9
-rw-r--r--source/blender/blenkernel/intern/BME_conversions.c286
-rw-r--r--source/blender/blenkernel/intern/BME_eulers.c14
-rw-r--r--source/blender/blenkernel/intern/BME_mesh.c80
-rw-r--r--source/blender/blenkernel/intern/BME_structure.c135
-rw-r--r--source/blender/blenkernel/intern/BME_tools.c105
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/bmesh_private.h6
-rw-r--r--source/blender/blenkernel/intern/cloth.c4
-rw-r--r--source/blender/blenkernel/intern/collision.c467
-rw-r--r--source/blender/blenkernel/intern/customdata.c384
-rw-r--r--source/blender/blenkernel/intern/image.c14
-rw-r--r--source/blender/blenkernel/intern/implicit.c13
-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/object.c11
-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/blenkernel/intern/sca.c3
-rw-r--r--source/blender/blenlib/BLI_arithb.h6
-rw-r--r--source/blender/blenlib/BLI_winstuff.h3
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c2
-rw-r--r--source/blender/blenlib/intern/arithb.c60
-rw-r--r--source/blender/blenlib/intern/util.c1
-rw-r--r--source/blender/blenloader/intern/readfile.c17
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-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_editaction.h2
-rw-r--r--source/blender/include/BIF_editarmature.h2
-rw-r--r--source/blender/include/BIF_resources.h3
-rw-r--r--source/blender/include/BSE_sequence.h2
-rw-r--r--source/blender/include/blendef.h6
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h52
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h10
-rw-r--r--source/blender/makesdna/DNA_lamp_types.h19
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h15
-rw-r--r--source/blender/makesdna/DNA_sensor_types.h7
-rw-r--r--source/blender/makesdna/DNA_space_types.h11
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h1
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_gamma.c2
-rw-r--r--source/blender/python/BPY_interface.c25
-rw-r--r--source/blender/python/api2_2x/matrix.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/include/pixelshading.h1
-rw-r--r--source/blender/render/intern/include/render_types.h4
-rw-r--r--source/blender/render/intern/source/convertblender.c27
-rw-r--r--source/blender/render/intern/source/pixelshading.c78
-rw-r--r--source/blender/render/intern/source/rendercore.c91
-rw-r--r--source/blender/src/buttons_editing.c50
-rw-r--r--source/blender/src/buttons_logic.c517
-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.c47
-rw-r--r--source/blender/src/drawaction.c107
-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/editaction.c108
-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/editseq.c17
-rw-r--r--source/blender/src/editsima.c16
-rw-r--r--source/blender/src/editsound.c2
-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/headerbuttons.c1
-rw-r--r--source/blender/src/interface_draw.c8
-rw-r--r--source/blender/src/poselib.c18
-rw-r--r--source/blender/src/resources.c28
-rw-r--r--source/blender/src/sequence.c10
-rw-r--r--source/blender/src/space.c25
-rw-r--r--source/blender/src/transform_conversions.c9
-rw-r--r--source/blender/src/transform_snap.c2
-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/BlenderRoutines/KX_BlenderRenderTools.cpp4
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h2
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp63
-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_ShapeActionActuator.cpp24
-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.cpp142
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp14
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h57
-rw-r--r--source/gameengine/Expressions/Value.cpp15
-rw-r--r--source/gameengine/Expressions/Value.h1
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp12
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h6
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_EventManager.h4
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h1
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp12
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h4
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp42
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h15
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp3
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h5
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp17
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp12
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp79
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.h21
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp4
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.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/BL_Shader.cpp2
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp14
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp3
-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_Camera.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp576
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.h59
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp485
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h84
-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_MeshProxy.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp363
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h19
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp63
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp48
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp39
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h10
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp46
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h8
-rw-r--r--source/gameengine/Ketsji/KX_TouchEventManager.cpp16
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp35
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp33
-rw-r--r--source/gameengine/PyDoc/BL_ActionActuator.py15
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py33
-rw-r--r--source/gameengine/Rasterizer/CMakeLists.txt2
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp186
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.h24
-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_IRenderTools.h2
-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/Rasterizer/SConscript3
-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
192 files changed, 5426 insertions, 2596 deletions
diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h
index 51a5d29dbb7..8ec7144faf6 100644
--- a/source/blender/blenkernel/BKE_bmesh.h
+++ b/source/blender/blenkernel/BKE_bmesh.h
@@ -39,12 +39,12 @@
#include "DNA_listBase.h"
#include "BLI_ghash.h"
+#include "BLI_mempool.h"
#include "BLI_memarena.h"
#include "DNA_image_types.h"
#include "BLI_editVert.h"
#include "BKE_DerivedMesh.h"
#include "transform.h"
-#include "BKE_bmeshCustomData.h"
/*forward declerations*/
struct BME_Vert;
@@ -53,13 +53,6 @@ struct BME_Poly;
struct BME_Loop;
-/*structure for fast memory allocation/frees*/
-typedef struct BME_mempool{
- struct ListBase chunks;
- int esize, csize, pchunk; /*size of elements and chunks in bytes and number of elements per chunk*/
- struct BME_freenode *free; /*free element list. Interleaved into chunk datas.*/
-}BME_mempool;
-
/*Notes on further structure Cleanup:
-Remove the tflags, they belong in custom data layers
-Remove the eflags completely, they are mostly not used
@@ -78,10 +71,10 @@ typedef struct BME_Mesh
{
ListBase verts, edges, polys;
/*memory pools used for storing mesh elements*/
- struct BME_mempool *vpool;
- struct BME_mempool *epool;
- struct BME_mempool *ppool;
- struct BME_mempool *lpool;
+ struct BLI_mempool *vpool;
+ struct BLI_mempool *epool;
+ struct BLI_mempool *ppool;
+ struct BLI_mempool *lpool;
/*some scratch arrays used by eulers*/
struct BME_Vert **vtar;
struct BME_Edge **edar;
@@ -90,7 +83,7 @@ typedef struct BME_Mesh
int vtarlen, edarlen, lparlen, plarlen;
int totvert, totedge, totpoly, totloop; /*record keeping*/
int nextv, nexte, nextp, nextl; /*Next element ID for verts/edges/faces/loops. Never reused*/
- struct BME_CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/
+ struct CustomData vdata, edata, pdata, ldata; /*Custom Data Layer information*/
} BME_Mesh;
typedef struct BME_Vert
@@ -169,7 +162,7 @@ int BME_radial_find_face(struct BME_Edge *e,struct BME_Poly *f);
struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v);
/*MESH CREATION/DESTRUCTION*/
-struct BME_Mesh *BME_make_mesh(int allocsize[4], struct BME_CustomDataInit init[4]);
+struct BME_Mesh *BME_make_mesh(int allocsize[4]);
void BME_free_mesh(struct BME_Mesh *bm);
/*FULL MESH VALIDATION*/
int BME_validate_mesh(struct BME_Mesh *bm, int halt);
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_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 2e5da236a89..f3c13d3d820 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -208,7 +208,7 @@ typedef enum
////////////////////////////////////////////////
// needed for implicit.c
-int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt );
+int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt );
////////////////////////////////////////////////
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index d0535f1752e..e84c7d30956 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -40,6 +40,8 @@ extern const CustomDataMask CD_MASK_BAREMESH;
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
@@ -134,6 +136,9 @@ void CustomData_copy_data(const struct CustomData *source,
void CustomData_em_copy_data(const struct CustomData *source,
struct CustomData *dest, void *src_block,
void **dest_block);
+void CustomData_bmesh_copy_data(const struct CustomData *source,
+ struct CustomData *dest,void *src_block,
+ void **dest_block);
/* frees data in a CustomData object
* return 1 on success, 0 on failure
@@ -160,6 +165,10 @@ void CustomData_interp(const struct CustomData *source, struct CustomData *dest,
void CustomData_em_interp(struct CustomData *data, void **src_blocks,
float *weights, float *sub_weights, int count,
void *dest_block);
+void CustomData_bmesh_interp(struct CustomData *data, void **src_blocks,
+ float *weights, float *sub_weights, int count,
+ void *dest_block);
+
/* swaps the data in the element corners, to new corners with indices as
specified in corner_indices. for edges this is an array of length 2, for
@@ -172,6 +181,8 @@ void CustomData_swap(struct CustomData *data, int index, int *corner_indices);
void *CustomData_get(const struct CustomData *data, int index, int type);
void *CustomData_em_get(const struct CustomData *data, void *block, int type);
void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n);
+void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type);
+void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n);
/* gets a pointer to the active or first layer of type
* returns NULL if there is no layer of type
@@ -199,6 +210,12 @@ void CustomData_em_set(struct CustomData *data, void *block, int type,
void CustomData_em_set_n(struct CustomData *data, void *block, int type, int n,
void *source);
+void CustomData_bmesh_set(const struct CustomData *data, void *block, int type,
+ void *source);
+
+void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n,
+ void *source);
+
/* set the pointer of to the first layer of type. the old data is not freed.
* returns the value of ptr if the layer is found, NULL otherwise
*/
@@ -220,12 +237,20 @@ void CustomData_set_layer_flag(struct CustomData *data, int type, int flag);
void CustomData_em_set_default(struct CustomData *data, void **block);
void CustomData_em_free_block(struct CustomData *data, void **block);
+void CustomData_bmesh_set_default(struct CustomData *data, void **block);
+void CustomData_bmesh_free_block(struct CustomData *data, void **block);
+
/* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
blocks of data. the CustomData's must not be compatible */
void CustomData_to_em_block(const struct CustomData *source,
struct CustomData *dest, int index, void **block);
void CustomData_from_em_block(const struct CustomData *source,
struct CustomData *dest, void *block, int index);
+void CustomData_to_bmesh_block(const struct CustomData *source,
+ struct CustomData *dest, int src_index, void **dest_block);
+void CustomData_from_bmesh_block(const struct CustomData *source,
+ struct CustomData *dest, void *src_block, int dest_index);
+
/* query info over types */
void CustomData_file_write_info(int type, char **structname, int *structnum);
@@ -241,4 +266,8 @@ void CustomData_set_layer_unique_name(struct CustomData *data, int index);
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 08483711c45..daf0de5b748 100644
--- a/source/blender/blenkernel/intern/BME_conversions.c
+++ b/source/blender/blenkernel/intern/BME_conversions.c
@@ -33,6 +33,7 @@
*/
#include "MEM_guardedalloc.h"
+#include "BKE_customdata.h"
#include "DNA_listBase.h"
#include "DNA_meshdata_types.h"
@@ -55,10 +56,199 @@
#include "BSE_edit.h"
+/*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};
- BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init");
+ int allocsize[4] = {512,512,2048,512}, numTex, numCol;
BME_Vert *v1, *v2;
BME_Edge *e, *edar[4];
BME_Poly *f;
@@ -68,9 +258,25 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
EditFace *efa;
int len;
- bm = BME_make_mesh(allocsize,init);
+ bm = BME_make_mesh(allocsize);
+
+ /*copy custom data layout*/
+ CustomData_copy(&em->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 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*/
eve= em->verts.first;
while(eve) {
@@ -79,9 +285,8 @@ BME_Mesh *BME_editmesh_to_bmesh(EditMesh *em) {
v1->flag = eve->f;
v1->h = eve->h;
v1->bweight = eve->bweight;
-
- /* link the verts for edge and face construction;
- * kind of a dangerous thing - remember to cast back to BME_Vert before using! */
+ /*Copy Custom Data*/
+ CustomData_bmesh_copy_data(&em->vdata, &bm->vdata, eve->data, &v1->data);
eve->tmp.v = (EditVert*)v1;
eve = eve->next;
}
@@ -99,13 +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! */
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) {
@@ -134,13 +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);
- MEM_freeN(init);
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) {
@@ -155,12 +357,21 @@ 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;
if (em == NULL) return NULL;
+
+ 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));
@@ -176,6 +387,7 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
eve1->f = (unsigned char)v1->flag;
eve1->h = (unsigned char)v1->h;
eve1->bweight = v1->bweight;
+ CustomData_em_copy_data(&bm->vdata, &em->vdata, v1->data, &eve1->data);
}
/* make edges */
@@ -191,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);
}
}
@@ -217,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);
}
}
@@ -234,18 +450,33 @@ BME_Mesh *BME_derivedmesh_to_bmesh(DerivedMesh *dm)
BME_Mesh *bm;
int allocsize[4] = {512,512,2048,512};
- BME_CustomDataInit *init = MEM_callocN(sizeof(BME_CustomDataInit) * 4, "Bmesh custom data init");
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;
EdgeHash *edge_hash = BLI_edgehash_new();
- bm = BME_make_mesh(allocsize,init);
+ 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);
@@ -262,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++){
@@ -272,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++){
@@ -295,12 +528,13 @@ 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);
BLI_edgehash_free(edge_hash, NULL);
MEM_freeN(vert_array);
- MEM_freeN(init);
return bm;
}
@@ -309,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;
@@ -345,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;
@@ -368,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++;
}
@@ -389,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_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c
index 184ef2b8a0e..ad46a7c1eb7 100644
--- a/source/blender/blenkernel/intern/BME_mesh.c
+++ b/source/blender/blenkernel/intern/BME_mesh.c
@@ -32,64 +32,33 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include "MEM_guardedalloc.h"
+#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
-
+#include "BLI_blenlib.h"
#include "BKE_utildefines.h"
#include "BKE_bmesh.h"
-#include "BKE_global.h"
-#include "BKE_depsgraph.h"
-#include "BLI_blenlib.h"
-#include "BLI_editVert.h"
-#include "BIF_editmesh.h"
-#include "BIF_space.h"
-#include "editmesh.h"
#include "bmesh_private.h"
-#include "mydevice.h"
-
-#include "BSE_edit.h"
/*
* BME MAKE MESH
*
* Allocates a new BME_Mesh structure.
- * The arguments are two arrays, one of type int
- * and another of type BME_CustomDataInit. The first array
- * contains the allocation size for each element pool in
- * the mesh. For instance allocsize[0] contains the number
- * of vertices to allocate at a time for the vertex pool.
- *
- * The second array contains structures describing the layout
- * of custom data for each element type in the mesh. So init[0]
- * contains the custom data layout information for vertices, init[1]
- * the layout information for edges and so on.
- *
* Returns -
* Pointer to a Bmesh
*
*/
-BME_Mesh *BME_make_mesh(int allocsize[4], BME_CustomDataInit init[4])
+BME_Mesh *BME_make_mesh(int allocsize[4])
{
/*allocate the structure*/
BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
/*allocate the memory pools for the mesh elements*/
- bm->vpool = BME_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]);
- bm->epool = BME_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]);
- bm->lpool = BME_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]);
- bm->ppool = BME_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]);
- /*Setup custom data layers*/
- BME_CD_Create(&bm->vdata, &init[0], allocsize[0]);
- BME_CD_Create(&bm->edata, &init[1], allocsize[1]);
- BME_CD_Create(&bm->ldata, &init[2], allocsize[2]);
- BME_CD_Create(&bm->pdata, &init[3], allocsize[3]);
+ bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0]);
+ bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1]);
+ bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2]);
+ bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3]);
return bm;
}
/*
@@ -105,26 +74,35 @@ void BME_free_mesh(BME_Mesh *bm)
BME_Loop *l;
BME_Poly *f;
- for(v=bm->verts.first; v; v=v->next) BME_CD_free_block(&bm->vdata, &v->data);
- for(e=bm->edges.first; e; e=e->next) BME_CD_free_block(&bm->edata, &e->data);
+ for(v=bm->verts.first; v; v=v->next) CustomData_bmesh_free_block(&bm->vdata, &v->data);
+ for(e=bm->edges.first; e; e=e->next) CustomData_bmesh_free_block(&bm->edata, &e->data);
for(f=bm->polys.first; f; f=f->next){
- BME_CD_free_block(&bm->pdata, &f->data);
+ CustomData_bmesh_free_block(&bm->pdata, &f->data);
l = f->loopbase;
do{
- BME_CD_free_block(&bm->ldata, &l->data);
+ CustomData_bmesh_free_block(&bm->ldata, &l->data);
l = l->next;
}while(l!=f->loopbase);
}
+
+ /*Free custom data pools, This should probably go in CustomData_free?*/
+ if(bm->vdata.totlayer) BLI_mempool_destroy(bm->vdata.pool);
+ if(bm->edata.totlayer) BLI_mempool_destroy(bm->edata.pool);
+ if(bm->ldata.totlayer) BLI_mempool_destroy(bm->ldata.pool);
+ if(bm->pdata.totlayer) BLI_mempool_destroy(bm->pdata.pool);
+
+ /*free custom data*/
+ CustomData_free(&bm->vdata,0);
+ CustomData_free(&bm->edata,0);
+ CustomData_free(&bm->ldata,0);
+ CustomData_free(&bm->pdata,0);
+
/*destroy element pools*/
- BME_mempool_destroy(bm->vpool);
- BME_mempool_destroy(bm->epool);
- BME_mempool_destroy(bm->ppool);
- BME_mempool_destroy(bm->lpool);
- /*free custom data pools*/
- BME_CD_Free(&bm->vdata);
- BME_CD_Free(&bm->edata);
- BME_CD_Free(&bm->ldata);
- BME_CD_Free(&bm->pdata);
+ BLI_mempool_destroy(bm->vpool);
+ BLI_mempool_destroy(bm->epool);
+ BLI_mempool_destroy(bm->ppool);
+ BLI_mempool_destroy(bm->lpool);
+
MEM_freeN(bm);
}
diff --git a/source/blender/blenkernel/intern/BME_structure.c b/source/blender/blenkernel/intern/BME_structure.c
index cbf780c6467..ca27f5efd10 100644
--- a/source/blender/blenkernel/intern/BME_structure.c
+++ b/source/blender/blenkernel/intern/BME_structure.c
@@ -41,101 +41,6 @@
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_ghash.h"
-
-#include "BKE_customdata.h"
-
-/*
- Simple, fast memory allocator for allocating many elements of the same size.
-*/
-typedef struct BME_mempool_chunk{
- struct BME_mempool_chunk *next, *prev;
- void *data;
-}BME_mempool_chunk;
-
-/*this is just to make things prettier*/
-typedef struct BME_freenode{
- struct BME_freenode *next;
-}BME_freenode;
-
-BME_mempool *BME_mempool_create(int esize, int tote, int pchunk)
-{ BME_mempool *pool = NULL;
- BME_freenode *lasttail = NULL, *curnode = NULL;
- int i,j, maxchunks;
- char *addr;
-
- /*allocate the pool structure*/
- pool = MEM_mallocN(sizeof(BME_mempool),"memory pool");
- pool->esize = esize;
- pool->pchunk = pchunk;
- pool->csize = esize * pchunk;
- pool->chunks.first = pool->chunks.last = NULL;
-
- maxchunks = tote / pchunk;
-
- /*allocate the actual chunks*/
- for(i=0; i < maxchunks; i++){
- BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk");
- mpchunk->next = mpchunk->prev = NULL;
- mpchunk->data = MEM_mallocN(pool->csize, "BME Mempool Chunk Data");
- BLI_addtail(&(pool->chunks), mpchunk);
-
- if(i==0) pool->free = mpchunk->data; /*start of the list*/
- /*loop through the allocated data, building the pointer structures*/
- for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
- curnode = ((BME_freenode*)addr);
- addr += pool->esize;
- curnode->next = (BME_freenode*)addr;
- }
- /*final pointer in the previously allocated chunk is wrong.*/
- if(lasttail) lasttail->next = mpchunk->data;
- /*set the end of this chunks memory to the new tail for next iteration*/
- lasttail = curnode;
- }
- /*terminate the list*/
- curnode->next = NULL;
- return pool;
-}
-
-void *BME_mempool_alloc(BME_mempool *pool){
- void *retval=NULL;
- BME_freenode *curnode=NULL;
- char *addr=NULL;
- int j;
-
- if(!(pool->free)){
- /*need to allocate a new chunk*/
- BME_mempool_chunk *mpchunk = MEM_mallocN(sizeof(BME_mempool_chunk), "BME_Mempool Chunk");
- mpchunk->next = mpchunk->prev = NULL;
- mpchunk->data = MEM_mallocN(pool->csize, "BME_Mempool Chunk Data");
- BLI_addtail(&(pool->chunks), mpchunk);
-
- pool->free = mpchunk->data; /*start of the list*/
- for(addr = mpchunk->data, j=0; j < pool->pchunk; j++){
- curnode = ((BME_freenode*)addr);
- addr += pool->esize;
- curnode->next = (BME_freenode*)addr;
- }
- curnode->next = NULL; /*terminate the list*/
- }
-
- retval = pool->free;
- pool->free = pool->free->next;
- //memset(retval, 0, pool->esize);
- return retval;
-}
-
-void BME_mempool_free(BME_mempool *pool, void *addr){ //doesnt protect against double frees, dont be stupid!
- BME_freenode *newhead = addr;
- newhead->next = pool->free;
- pool->free = newhead;
-}
-void BME_mempool_destroy(BME_mempool *pool)
-{
- BME_mempool_chunk *mpchunk=NULL;
- for(mpchunk = pool->chunks.first; mpchunk; mpchunk = mpchunk->next) MEM_freeN(mpchunk->data);
- BLI_freelistN(&(pool->chunks));
- MEM_freeN(pool);
-}
/**
* MISC utility functions.
*
@@ -179,7 +84,7 @@ int BME_edge_swapverts(BME_Edge *e, BME_Vert *orig, BME_Vert *new){
BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){
BME_Vert *v=NULL;
- v = BME_mempool_alloc(bm->vpool);
+ v = BLI_mempool_alloc(bm->vpool);
v->next = v->prev = NULL;
v->EID = bm->nextv;
v->co[0] = v->co[1] = v->co[2] = 0.0f;
@@ -195,16 +100,16 @@ BME_Vert *BME_addvertlist(BME_Mesh *bm, BME_Vert *example){
if(example){
VECCOPY(v->co,example->co);
- BME_CD_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data);
+ CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->data, &v->data);
}
else
- BME_CD_set_default(&bm->vdata, &v->data);
+ CustomData_bmesh_set_default(&bm->vdata, &v->data);
return v;
}
BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *example){
BME_Edge *e=NULL;
- e = BME_mempool_alloc(bm->epool);
+ e = BLI_mempool_alloc(bm->epool);
e->next = e->prev = NULL;
e->EID = bm->nexte;
e->v1 = v1;
@@ -222,16 +127,16 @@ BME_Edge *BME_addedgelist(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge *ex
BLI_addtail(&(bm->edges), e);
if(example)
- BME_CD_copy_data(&bm->edata, &bm->edata, example->data, &e->data);
+ CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->data, &e->data);
else
- BME_CD_set_default(&bm->edata, &e->data);
+ CustomData_bmesh_set_default(&bm->edata, &e->data);
return e;
}
BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, BME_Loop *example){
BME_Loop *l=NULL;
- l = BME_mempool_alloc(bm->lpool);
+ l = BLI_mempool_alloc(bm->lpool);
l->next = l->prev = NULL;
l->EID = bm->nextl;
l->radial.next = l->radial.prev = NULL;
@@ -246,16 +151,16 @@ BME_Loop *BME_create_loop(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Poly *f, B
bm->totloop++;
if(example)
- BME_CD_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data);
+ CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->data, &l->data);
else
- BME_CD_set_default(&bm->ldata, &l->data);
+ CustomData_bmesh_set_default(&bm->ldata, &l->data);
return l;
}
BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){
BME_Poly *f = NULL;
- f = BME_mempool_alloc(bm->ppool);
+ f = BLI_mempool_alloc(bm->ppool);
f->next = f->prev = NULL;
f->EID = bm->nextp;
f->loopbase = NULL;
@@ -268,9 +173,9 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){
bm->totpoly++;
if(example)
- BME_CD_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data);
+ CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, example->data, &f->data);
else
- BME_CD_set_default(&bm->pdata, &f->data);
+ CustomData_bmesh_set_default(&bm->pdata, &f->data);
return f;
@@ -281,23 +186,23 @@ BME_Poly *BME_addpolylist(BME_Mesh *bm, BME_Poly *example){
*/
void BME_free_vert(BME_Mesh *bm, BME_Vert *v){
bm->totvert--;
- BME_CD_free_block(&bm->vdata, &v->data);
- BME_mempool_free(bm->vpool, v);
+ CustomData_bmesh_free_block(&bm->vdata, &v->data);
+ BLI_mempool_free(bm->vpool, v);
}
void BME_free_edge(BME_Mesh *bm, BME_Edge *e){
bm->totedge--;
- BME_CD_free_block(&bm->edata, &e->data);
- BME_mempool_free(bm->epool, e);
+ CustomData_bmesh_free_block(&bm->edata, &e->data);
+ BLI_mempool_free(bm->epool, e);
}
void BME_free_poly(BME_Mesh *bm, BME_Poly *f){
bm->totpoly--;
- BME_CD_free_block(&bm->pdata, &f->data);
- BME_mempool_free(bm->ppool, f);
+ CustomData_bmesh_free_block(&bm->pdata, &f->data);
+ BLI_mempool_free(bm->ppool, f);
}
void BME_free_loop(BME_Mesh *bm, BME_Loop *l){
bm->totloop--;
- BME_CD_free_block(&bm->ldata, &l->data);
- BME_mempool_free(bm->lpool, l);
+ CustomData_bmesh_free_block(&bm->ldata, &l->data);
+ BLI_mempool_free(bm->lpool, l);
}
/**
* BMESH CYCLES
diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c
index 7ce967d1d22..90259031e5c 100644
--- a/source/blender/blenkernel/intern/BME_tools.c
+++ b/source/blender/blenkernel/intern/BME_tools.c
@@ -205,7 +205,53 @@ static BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Ver
return nf;
}
-/* a wrapper for BME_SEMV that transfers element flags */
+
+static void BME_data_interp_from_verts(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, float fac)
+{
+ void *src[2];
+ float w[2];
+ if (v1->data && v2->data) {
+ src[0]= v1->data;
+ src[1]= v2->data;
+ w[0] = 1.0f-fac;
+ w[1] = fac;
+ 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;
float len;
@@ -224,10 +270,39 @@ 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) {
/* look for verts that have already been added to the edge when
* beveling other polys; this can be determined by testing the
@@ -315,7 +390,7 @@ static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int
* Finally, return the split vert. */
static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) {
BME_TransData *vtd, *vtd1, *vtd2;
- BME_Vert *sv, *v2, *v3;
+ BME_Vert *sv, *v2, *v3, *ov;
BME_Loop *lv1, *lv2;
BME_Edge *ne, *e1, *e2;
float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3];
@@ -349,7 +424,11 @@ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, B
else {
e1 = e2;
}
+ 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 */
@@ -388,7 +467,11 @@ static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, B
}
else {
is_split_vert = 0;
+ 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 */
@@ -567,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;
}
@@ -601,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);
}
}
@@ -1073,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/bmesh_private.h b/source/blender/blenkernel/intern/bmesh_private.h
index 4aa2a85b8b1..f34ef0090f3 100644
--- a/source/blender/blenkernel/intern/bmesh_private.h
+++ b/source/blender/blenkernel/intern/bmesh_private.h
@@ -39,11 +39,6 @@
#include "BKE_bmesh.h"
-struct BME_mempool *BME_mempool_create(int esize, int tote, int pchunk);
-void BME_mempool_destroy(struct BME_mempool *pool);
-void *BME_mempool_alloc(struct BME_mempool *pool);
-void BME_mempool_free(struct BME_mempool *pool, void *address);
-
/*ALLOCATION/DEALLOCATION*/
struct BME_Vert *BME_addvertlist(struct BME_Mesh *bm, struct BME_Vert *example);
struct BME_Edge *BME_addedgelist(struct BME_Mesh *bm, struct BME_Vert *v1, struct BME_Vert *v2, struct BME_Edge *example);
@@ -54,7 +49,6 @@ void BME_free_vert(struct BME_Mesh *bm, struct BME_Vert *v);
void BME_free_edge(struct BME_Mesh *bm, struct BME_Edge *e);
void BME_free_poly(struct BME_Mesh *bm, struct BME_Poly *f);
void BME_free_loop(struct BME_Mesh *bm, struct BME_Loop *l);
-//void BME_delete_loop(struct BME_Mesh *bm, struct BME_Loop *l);
/*DOUBLE CIRCULAR LINKED LIST FUNCTIONS*/
void BME_cycle_append(void *h, void *nt);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 6034b85e20f..c7817b017ef 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -132,7 +132,7 @@ void cloth_init ( ClothModifierData *clmd )
clmd->coll_parms->self_friction = 5.0;
clmd->coll_parms->friction = 5.0;
- clmd->coll_parms->loop_count = 3;
+ clmd->coll_parms->loop_count = 2;
clmd->coll_parms->epsilon = 0.015f;
clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED;
clmd->coll_parms->collision_list = NULL;
@@ -471,7 +471,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
tend();
- /* printf ( "Cloth simulation time: %f\n", ( float ) tval() ); */
+ // printf ( "%f\n", ( float ) tval() );
return ret;
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 7f41ca033d3..26c5d186d87 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -541,7 +541,7 @@ int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifier
{
Normalize ( vrel_t_pre );
- impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 );
+ impulse = magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3 ); // 2.0 *
VECADDMUL ( cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse );
VECADDMUL ( cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse );
VECADDMUL ( cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse );
@@ -1291,52 +1291,223 @@ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *col
return 1;
}
-int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt )
-{
+int cloth_do_selfcollisions(ClothModifierData * clmd)
+{
+ int ret2 = 0, l;
Cloth *cloth = clmd->clothObject;
- BVHTree *cloth_bvh= ( BVHTree * ) cloth->bvhtree;
- long i=0, j = 0, numfaces = 0, numverts = 0;
- ClothVertex *verts = NULL;
- CollPair *collisions = NULL, *collisions_index = NULL;
- int ret = 0;
- int result = 0;
- float tnull[3] = {0,0,0};
- BVHTreeOverlap *overlap = NULL;
-
-
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
-
- verts = cloth->verts;
+
+ if ( clmd->clothObject->bvhselftree )
+ {
+ for(l = 0; l < clmd->coll_parms->self_loop_count; l++)
+ {
+ BVHTreeOverlap *overlap = NULL;
+ ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
+ int k;
+ int ret = 0, result = 0;
+
+ // search for overlapping collision pairs
+ overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
+
+// #pragma omp parallel for private(k, i, j) schedule(static)
+ for ( k = 0; k < result; k++ )
+ {
+ float temp[3];
+ float length = 0;
+ float mindistance;
+ int i, j;
+
+ i = overlap[k].indexA;
+ j = overlap[k].indexB;
+
+ mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
+
+ if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
+ {
+ if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
+ && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
+ {
+ continue;
+ }
+ }
+
+ VECSUB ( temp, verts[i].tx, verts[j].tx );
+
+ if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
+
+ // check for adjacent points (i must be smaller j)
+ if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
+ {
+ continue;
+ }
+
+ length = Normalize ( temp );
+
+ if ( length < mindistance )
+ {
+ float correction = mindistance - length;
+
+ if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
+ {
+ VecMulf ( temp, -correction );
+ VECADD ( verts[j].tx, verts[j].tx, temp );
+ }
+ else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
+ {
+ VecMulf ( temp, correction );
+ VECADD ( verts[i].tx, verts[i].tx, temp );
+ }
+ else
+ {
+ VecMulf ( temp, -correction*0.5 );
+ VECADD ( verts[j].tx, verts[j].tx, temp );
+
+ VECSUB ( verts[i].tx, verts[i].tx, temp );
+ }
+ ret = 1;
+ ret2 += ret;
+ }
+ else
+ {
+ // check for approximated time collisions
+ }
+ }
+
+ if ( overlap )
+ MEM_freeN ( overlap );
+
+ if(!ret)
+ break;
+
+ }
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
+ // SELFCOLLISIONS: update velocities
+ ////////////////////////////////////////////////////////////
+ if ( ret2 )
+ {
+ int i;
+ ClothVertex *verts = clmd->clothObject->verts; // needed for openMP
+
+ for ( i = 0; i < cloth->numverts; i++ )
+ {
+ if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
+ {
+ VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
+ }
+ }
+ }
+ ////////////////////////////////////////////////////////////
+ }
+ return ret2;
+}
- if ( collmd->bvhtree )
+// return all collision objects in scene
+// collision object will exclude self
+CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
+{
+ Base *base=NULL;
+ CollisionModifierData **objs = NULL;
+ Object *coll_ob = NULL;
+ CollisionModifierData *collmd = NULL;
+ int numobj = 0, maxobj = 100;
+
+ objs = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ // check all collision objects
+ for ( base = G.scene->base.first; base; base = base->next )
{
- /* get pointer to bounding volume hierarchy */
- BVHTree *coll_bvh = collmd->bvhtree;
+ coll_ob = base->object;
+ collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
+
+ if ( !collmd )
+ {
+ if ( coll_ob->dup_group )
+ {
+ GroupObject *go;
+ Group *group = coll_ob->dup_group;
- /* move object to position (step) in time */
- collision_move_object ( collmd, step + dt, step );
+ for ( go= group->gobject.first; go; go= go->next )
+ {
+ coll_ob = go->ob;
- /* search for overlapping collision pairs */
- overlap = BLI_bvhtree_overlap ( cloth_bvh, coll_bvh, &result );
+ collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
- collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * result*4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
- collisions_index = collisions;
+ if ( !collmd )
+ continue;
- for ( i = 0; i < result; i++ )
- {
- collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, collisions_index );
- }
+ if(coll_ob == self)
+ continue;
- if ( overlap )
- MEM_freeN ( overlap );
+ if(numobj >= maxobj)
+ {
+ // realloc
+ int oldmax = maxobj;
+ CollisionModifierData **tmp;
+ maxobj *= 2;
+ tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+ MEM_freeN(objs);
+ objs = tmp;
+ }
+
+ objs[numobj] = collmd;
+ numobj++;
+ }
+ }
+ }
+ else
+ {
+ if(coll_ob == self)
+ continue;
+
+ if(numobj >= maxobj)
+ {
+ // realloc
+ int oldmax = maxobj;
+ CollisionModifierData **tmp;
+ maxobj *= 2;
+ tmp = MEM_callocN(sizeof(CollisionModifierData *)*maxobj, "CollisionObjectsArray");
+ memcpy(tmp, objs, sizeof(CollisionModifierData *)*oldmax);
+ MEM_freeN(objs);
+ objs = tmp;
+
+ }
+
+ objs[numobj] = collmd;
+ numobj++;
+ }
}
- else
+ *numcollobj = numobj;
+ return objs;
+}
+
+void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
+{
+ int i;
+
+ *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
+ *collisions_index = *collisions;
+
+ for ( i = 0; i < numresult; i++ )
{
- if ( G.rt > 0 )
- printf ( "cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n" );
+ *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, *collisions_index );
}
+}
+int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
+{
+ Cloth *cloth = clmd->clothObject;
+ int i=0, j = 0, numfaces = 0, numverts = 0;
+ ClothVertex *verts = NULL;
+ int ret = 0;
+ int result = 0;
+ float tnull[3] = {0,0,0};
+
+ numfaces = clmd->clothObject->numfaces;
+ numverts = clmd->clothObject->numverts;
+
+ verts = cloth->verts;
+
// process all collisions (calculate impulses, TODO: also repulses if distance too short)
result = 1;
for ( j = 0; j < 5; j++ ) // 5 is just a value that ensures convergence
@@ -1363,48 +1534,22 @@ int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData
}
}
}
-/*
- result += cloth_collision_moving ( clmd, collmd, collisions, collisions_index );
-
- // apply impulses in parallel
- if ( result )
- {
- for ( i = 0; i < numverts; i++ )
- {
- // calculate "velocities" (just xnew = xold + v; no dt in v)
- if ( verts[i].impulse_count )
- {
- VECADDMUL ( verts[i].tv, verts[i].impulse, 1.0f / verts[i].impulse_count );
- VECCOPY ( verts[i].impulse, tnull );
- verts[i].impulse_count = 0;
-
- ret++;
- }
- }
- }
-*/
}
}
-
- if ( collisions ) MEM_freeN ( collisions );
-
return ret;
}
// cloth - object collisions
-int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt )
+int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, float dt )
{
- Base *base=NULL;
- CollisionModifierData *collmd=NULL;
Cloth *cloth=NULL;
- Object *coll_ob=NULL;
BVHTree *cloth_bvh=NULL;
- long i=0, j = 0, k = 0, l = 0, numfaces = 0, numverts = 0;
- int result = 0, rounds = 0; // result counts applied collisions; ic is for debug output;
+ long i=0, numfaces = 0, numverts = 0;
+ int rounds = 0; // result counts applied collisions; ic is for debug output;
ClothVertex *verts = NULL;
int ret = 0, ret2 = 0;
- ClothModifierData *tclmd;
- int collisions = 0;
+ CollisionModifierData **collobjs = NULL;
+ int numcollobj = 0;
if ( ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ ) || ! ( ( ( Cloth * ) clmd->clothObject )->bvhtree ) )
{
@@ -1424,54 +1569,61 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt )
// update cloth bvh
bvhtree_update_from_cloth ( clmd, 1 ); // 0 means STATIC, 1 means MOVING (see later in this function)
bvhselftree_update_from_cloth ( clmd, 0 ); // 0 means STATIC, 1 means MOVING (see later in this function)
+
+ collobjs = get_collisionobjects(ob, &numcollobj);
+
+ if(!collobjs)
+ return 0;
do
{
- result = 0;
+ CollPair **collisions, **collisions_index;
+
ret2 = 0;
+ collisions = MEM_callocN(sizeof(CollPair *) *numcollobj , "CollPair");
+ collisions_index = MEM_callocN(sizeof(CollPair *) *numcollobj , "CollPair");
+
// check all collision objects
- for ( base = G.scene->base.first; base; base = base->next )
+ for(i = 0; i < numcollobj; i++)
{
- coll_ob = base->object;
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
-
- if ( !collmd )
- {
- if ( coll_ob->dup_group )
- {
- GroupObject *go;
- Group *group = coll_ob->dup_group;
-
- for ( go= group->gobject.first; go; go= go->next )
- {
- coll_ob = go->ob;
-
- collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
-
- if ( !collmd )
- continue;
-
- tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth );
- if ( tclmd == clmd )
- continue;
-
- ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt );
- ret2 += ret;
- }
- }
- }
- else
+ CollisionModifierData *collmd = collobjs[i];
+ BVHTreeOverlap *overlap = NULL;
+ int result = 0;
+
+ /* move object to position (step) in time */
+ collision_move_object ( collmd, step + dt, step );
+
+ /* search for overlapping collision pairs */
+ overlap = BLI_bvhtree_overlap ( cloth_bvh, collmd->bvhtree, &result );
+
+ // go to next object if no overlap is there
+ if(!result || !overlap)
{
- tclmd = ( ClothModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Cloth );
- if ( tclmd == clmd )
- continue;
-
- ret += cloth_bvh_objcollisions_do ( clmd, collmd, step, dt );
- ret2 += ret;
+ if ( overlap )
+ MEM_freeN ( overlap );
+ continue;
}
+
+ /* check if collisions really happen (costly near check) */
+ cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
+
+ // resolve nearby collisions
+ ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]);
+ ret2 += ret;
+
+ if ( overlap )
+ MEM_freeN ( overlap );
}
rounds++;
+
+ for(i = 0; i < numcollobj; i++)
+ {
+ if ( collisions[i] ) MEM_freeN ( collisions[i] );
+ }
+
+ MEM_freeN(collisions);
+ MEM_freeN(collisions_index);
////////////////////////////////////////////////////////////
// update positions
@@ -1493,117 +1645,20 @@ int cloth_bvh_objcollision ( ClothModifierData * clmd, float step, float dt )
}
////////////////////////////////////////////////////////////
-
+
////////////////////////////////////////////////////////////
// Test on *simple* selfcollisions
////////////////////////////////////////////////////////////
if ( clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF )
{
- for(l = 0; l < clmd->coll_parms->self_loop_count; l++)
- {
- // TODO: add coll quality rounds again
- BVHTreeOverlap *overlap = NULL;
-
- collisions = 1;
- verts = cloth->verts; // needed for openMP
-
- numfaces = clmd->clothObject->numfaces;
- numverts = clmd->clothObject->numverts;
-
- verts = cloth->verts;
-
- if ( cloth->bvhselftree )
- {
- // search for overlapping collision pairs
- overlap = BLI_bvhtree_overlap ( cloth->bvhselftree, cloth->bvhselftree, &result );
-
- // #pragma omp parallel for private(k, i, j) schedule(static)
- for ( k = 0; k < result; k++ )
- {
- float temp[3];
- float length = 0;
- float mindistance;
-
- i = overlap[k].indexA;
- j = overlap[k].indexB;
-
- mindistance = clmd->coll_parms->selfepsilon* ( cloth->verts[i].avg_spring_len + cloth->verts[j].avg_spring_len );
-
- if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
- {
- if ( ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
- && ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED ) )
- {
- continue;
- }
- }
-
- VECSUB ( temp, verts[i].tx, verts[j].tx );
-
- if ( ( ABS ( temp[0] ) > mindistance ) || ( ABS ( temp[1] ) > mindistance ) || ( ABS ( temp[2] ) > mindistance ) ) continue;
-
- // check for adjacent points (i must be smaller j)
- if ( BLI_edgehash_haskey ( cloth->edgehash, MIN2(i, j), MAX2(i, j) ) )
- {
- continue;
- }
-
- length = Normalize ( temp );
-
- if ( length < mindistance )
- {
- float correction = mindistance - length;
-
- if ( cloth->verts [i].flags & CLOTH_VERT_FLAG_PINNED )
- {
- VecMulf ( temp, -correction );
- VECADD ( verts[j].tx, verts[j].tx, temp );
- }
- else if ( cloth->verts [j].flags & CLOTH_VERT_FLAG_PINNED )
- {
- VecMulf ( temp, correction );
- VECADD ( verts[i].tx, verts[i].tx, temp );
- }
- else
- {
- VecMulf ( temp, -correction*0.5 );
- VECADD ( verts[j].tx, verts[j].tx, temp );
-
- VECSUB ( verts[i].tx, verts[i].tx, temp );
- }
- ret = 1;
- ret2 += ret;
- }
- else
- {
- // check for approximated time collisions
- }
- }
-
- if ( overlap )
- MEM_freeN ( overlap );
-
- }
- }
- ////////////////////////////////////////////////////////////
-
- ////////////////////////////////////////////////////////////
- // SELFCOLLISIONS: update velocities
- ////////////////////////////////////////////////////////////
- if ( ret2 )
- {
- for ( i = 0; i < cloth->numverts; i++ )
- {
- if ( ! ( verts [i].flags & CLOTH_VERT_FLAG_PINNED ) )
- {
- VECSUB ( verts[i].tv, verts[i].tx, verts[i].txold );
- }
- }
- }
- ////////////////////////////////////////////////////////////
+ ret2 += cloth_do_selfcollisions(clmd);
}
+ ////////////////////////////////////////////////////////////
}
while ( ret2 && ( clmd->coll_parms->loop_count>rounds ) );
+
+ if(collobjs)
+ + MEM_freeN(collobjs);
return MIN2 ( ret, 1 );
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 77068d8ed66..501293ecd81 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -36,6 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
+#include "BLI_mempool.h"
#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
@@ -359,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)
@@ -432,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,
@@ -454,13 +529,16 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
{sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
- {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
+ {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, layerInterp_mloopuv, NULL, NULL},
+ {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
- "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco"};
+ "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"};
const CustomDataMask CD_MASK_BAREMESH =
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
@@ -475,6 +553,12 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
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_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)
{
@@ -1449,6 +1533,302 @@ 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;
+ int i;
+
+ if(!*block) return;
+ for(i = 0; i < data->totlayer; ++i) {
+ if(!(data->layers[i].flag & CD_FLAG_NOFREE)) {
+ typeInfo = layerType_getInfo(data->layers[i].type);
+
+ if(typeInfo->free) {
+ int offset = data->layers[i].offset;
+ typeInfo->free((char*)*block + offset, 1, typeInfo->size);
+ }
+ }
+ }
+
+ BLI_mempool_free(data->pool, *block);
+ *block = NULL;
+}
+
+static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
+{
+
+ if (*block)
+ CustomData_bmesh_free_block(data, block);
+
+ if (data->totsize > 0)
+ *block = BLI_mempool_calloc(data->pool);
+ else
+ *block = NULL;
+}
+
+void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest,
+ void *src_block, void **dest_block)
+{
+ const LayerTypeInfo *typeInfo;
+ int dest_i, src_i;
+
+ if (!*dest_block)
+ CustomData_bmesh_alloc_block(dest, dest_block);
+
+ /* copies a layer at a time */
+ dest_i = 0;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+
+ /* find the first dest layer with type >= the source type
+ * (this should work because layers are ordered by type)
+ */
+ while(dest_i < dest->totlayer
+ && dest->layers[dest_i].type < source->layers[src_i].type)
+ ++dest_i;
+
+ /* if there are no more dest layers, we're done */
+ if(dest_i >= dest->totlayer) return;
+
+ /* if we found a matching layer, copy the data */
+ if(dest->layers[dest_i].type == source->layers[src_i].type &&
+ strcmp(dest->layers[dest_i].name, source->layers[src_i].name) == 0) {
+ char *src_data = (char*)src_block + source->layers[src_i].offset;
+ char *dest_data = (char*)*dest_block + dest->layers[dest_i].offset;
+
+ typeInfo = layerType_getInfo(source->layers[src_i].type);
+
+ if(typeInfo->copy)
+ typeInfo->copy(src_data, dest_data, 1);
+ else
+ memcpy(dest_data, src_data, typeInfo->size);
+
+ /* if there are multiple source & dest layers of the same type,
+ * we don't want to copy all source layers to the same dest, so
+ * increment dest_i
+ */
+ ++dest_i;
+ }
+ }
+}
+
+/*Bmesh Custom Data Functions. Should replace editmesh ones with these as well, due to more effecient memory alloc*/
+void *CustomData_bmesh_get(const CustomData *data, void *block, int type)
+{
+ int layer_index;
+
+ /* get the layer index of the first layer of type */
+ layer_index = CustomData_get_active_layer_index(data, type);
+ if(layer_index < 0) return NULL;
+
+ return (char *)block + data->layers[layer_index].offset;
+}
+
+void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int n)
+{
+ int layer_index;
+
+ /* get the layer index of the first layer of type */
+ layer_index = CustomData_get_layer_index(data, type);
+ if(layer_index < 0) return NULL;
+
+ return (char *)block + data->layers[layer_index+n].offset;
+}
+
+void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
+{
+ void *dest = CustomData_bmesh_get(data, block, type);
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if(!dest) return;
+
+ if(typeInfo->copy)
+ typeInfo->copy(source, dest, 1);
+ else
+ memcpy(dest, source, typeInfo->size);
+}
+
+void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void *source)
+{
+ void *dest = CustomData_bmesh_get_n(data, block, type, n);
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+
+ if(!dest) return;
+
+ if(typeInfo->copy)
+ typeInfo->copy(source, dest, 1);
+ else
+ memcpy(dest, source, typeInfo->size);
+}
+
+void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
+ float *sub_weights, int count, void *dest_block)
+{
+ int i, j;
+ void *source_buf[SOURCE_BUF_SIZE];
+ void **sources = source_buf;
+
+ /* slow fallback in case we're interpolating a ridiculous number of
+ * elements
+ */
+ if(count > SOURCE_BUF_SIZE)
+ sources = MEM_callocN(sizeof(*sources) * count,
+ "CustomData_interp sources");
+
+ /* interpolates a layer at a time */
+ 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;
+
+ typeInfo->interp(sources, weights, sub_weights, count,
+ (char *)dest_block + layer->offset);
+ }
+ }
+
+ if(count > SOURCE_BUF_SIZE) MEM_freeN(sources);
+}
+
+void CustomData_bmesh_set_default(CustomData *data, void **block)
+{
+ const LayerTypeInfo *typeInfo;
+ int i;
+
+ if (!*block)
+ CustomData_bmesh_alloc_block(data, block);
+
+ for(i = 0; i < data->totlayer; ++i) {
+ int offset = data->layers[i].offset;
+
+ typeInfo = layerType_getInfo(data->layers[i].type);
+
+ if(typeInfo->set_default)
+ typeInfo->set_default((char*)*block + offset, 1);
+ }
+}
+
+void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest,
+ int src_index, void **dest_block)
+{
+ const LayerTypeInfo *typeInfo;
+ int dest_i, src_i, src_offset;
+
+ if (!*dest_block)
+ CustomData_bmesh_alloc_block(dest, dest_block);
+
+ /* copies a layer at a time */
+ dest_i = 0;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+
+ /* find the first dest layer with type >= the source type
+ * (this should work because layers are ordered by type)
+ */
+ while(dest_i < dest->totlayer
+ && dest->layers[dest_i].type < source->layers[src_i].type)
+ ++dest_i;
+
+ /* if there are no more dest layers, we're done */
+ if(dest_i >= dest->totlayer) return;
+
+ /* if we found a matching layer, copy the data */
+ if(dest->layers[dest_i].type == source->layers[src_i].type) {
+ int offset = dest->layers[dest_i].offset;
+ char *src_data = source->layers[src_i].data;
+ char *dest_data = (char*)*dest_block + offset;
+
+ typeInfo = layerType_getInfo(dest->layers[dest_i].type);
+ src_offset = src_index * typeInfo->size;
+
+ if(typeInfo->copy)
+ typeInfo->copy(src_data + src_offset, dest_data, 1);
+ else
+ memcpy(dest_data, src_data + src_offset, typeInfo->size);
+
+ /* if there are multiple source & dest layers of the same type,
+ * we don't want to copy all source layers to the same dest, so
+ * increment dest_i
+ */
+ ++dest_i;
+ }
+ }
+}
+
+void CustomData_from_bmesh_block(const CustomData *source, CustomData *dest,
+ void *src_block, int dest_index)
+{
+ const LayerTypeInfo *typeInfo;
+ int dest_i, src_i, dest_offset;
+
+ /* copies a layer at a time */
+ dest_i = 0;
+ for(src_i = 0; src_i < source->totlayer; ++src_i) {
+
+ /* find the first dest layer with type >= the source type
+ * (this should work because layers are ordered by type)
+ */
+ while(dest_i < dest->totlayer
+ && dest->layers[dest_i].type < source->layers[src_i].type)
+ ++dest_i;
+
+ /* if there are no more dest layers, we're done */
+ if(dest_i >= dest->totlayer) return;
+
+ /* if we found a matching layer, copy the data */
+ if(dest->layers[dest_i].type == source->layers[src_i].type) {
+ int offset = source->layers[src_i].offset;
+ char *src_data = (char*)src_block + offset;
+ char *dest_data = dest->layers[dest_i].data;
+
+ typeInfo = layerType_getInfo(dest->layers[dest_i].type);
+ dest_offset = dest_index * typeInfo->size;
+
+ if(typeInfo->copy)
+ typeInfo->copy(src_data, dest_data + dest_offset, 1);
+ else
+ memcpy(dest_data + dest_offset, src_data, typeInfo->size);
+
+ /* if there are multiple source & dest layers of the same type,
+ * we don't want to copy all source layers to the same dest, so
+ * increment dest_i
+ */
+ ++dest_i;
+ }
+ }
+
+}
+
void CustomData_file_write_info(int type, char **structname, int *structnum)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index c73279746fb..b6c8ad59e08 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -848,10 +848,6 @@ void BKE_add_image_extension(char *string, int imtype)
if(!BLI_testextensie(string, ".tga"))
extension= ".tga";
}
- else if(ELEM5(imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
- if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
- extension= ".jpg";
- }
else if(imtype==R_BMP) {
if(!BLI_testextensie(string, ".bmp"))
extension= ".bmp";
@@ -874,10 +870,14 @@ void BKE_add_image_extension(char *string, int imtype)
if (!BLI_testextensie(string, ".dpx"))
extension= ".dpx";
}
- else { /* targa default */
+ else if(imtype==R_TARGA) {
if(!BLI_testextensie(string, ".tga"))
extension= ".tga";
}
+ else { // R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90, R_QUICKTIME etc
+ if(!( BLI_testextensie(string, ".jpg") || BLI_testextensie(string, ".jpeg")))
+ extension= ".jpg";
+ }
strcat(string, extension);
}
@@ -1512,6 +1512,10 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
image_initialize_after_load(ima, ibuf);
image_assign_ibuf(ima, ibuf, 0, frame);
#endif
+
+ if(ima->flag & IMA_DO_PREMUL)
+ converttopremul(ibuf);
+
}
else
ima->ok= 0;
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 808984aaa3c..297ac0b1530 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1588,10 +1588,17 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
VECSUB(verts[i].tv, verts[i].tx, verts[i].txold);
VECCOPY(verts[i].v, verts[i].tv);
}
-
+
// call collision function
- result = cloth_bvh_objcollision(clmd, step + dt, dt);
-
+ // TODO: check if "step" or "step+dt" is correct - dg
+ result = cloth_bvh_objcollision(ob, clmd, step, dt);
+
+ // correct velocity again, just to be sure we had to change it due to adaptive collisions
+ for(i = 0; i < numverts; i++)
+ {
+ VECSUB(verts[i].tv, verts[i].tx, id->X[i]);
+ }
+
// copy corrected positions back to simulation
for(i = 0; i < numverts; i++)
{
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 6779b18154f..124474ca09c 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -4923,7 +4923,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/object.c b/source/blender/blenkernel/intern/object.c
index b72d9a0b044..7b36e46d45e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -732,6 +732,17 @@ void *add_lamp(char *name)
la->preview=NULL;
la->falloff_type = LA_FALLOFF_INVLINEAR;
la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
+ la->sun_effect_type = 0;
+ la->horizon_brightness = 1.0;
+ la->spread = 1.0;
+ la->sun_brightness = 1.0;
+ la->sun_size = 1.0;
+ la->backscattered_light = 1.0;
+ la->atm_turbidity = 2.0;
+ la->atm_inscattering_factor = 1.0;
+ la->atm_extinction_factor = 1.0;
+ la->atm_distance_factor = 1.0;
+ la->sun_intensity = 1.0;
curvemapping_initialize(la->curfalloff);
return la;
}
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/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 16ca5d7542d..fcf1c7ce311 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -150,6 +150,9 @@ void init_sensor(bSensor *sens)
case SENS_PROPERTY:
sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens");
break;
+ case SENS_ACTUATOR:
+ sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
+ break;
case SENS_MOUSE:
ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
ms->type= LEFTMOUSE;
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index 4fa880c36d1..c22b6f79e08 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -50,6 +50,9 @@ extern "C" {
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440
#endif
+#ifndef M_1_PI
+#define M_1_PI 0.318309886183790671538
+#endif
#ifdef WIN32
#ifndef FREE_WINDOWS
@@ -323,6 +326,9 @@ void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb);
void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr);
void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
+void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b);
+int constrain_rgb(float *r, float *g, float *b);
+void gamma_correct_rgb(float *r, float *g, float *b);
unsigned int hsv_to_cpack(float h, float s, float v);
unsigned int rgb_to_cpack(float r, float g, float b);
void cpack_to_rgb(unsigned int col, float *r, float *g, float *b);
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index 9c192ba8b09..11150075bac 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -73,6 +73,9 @@
#ifndef M_SQRT1_2
#define M_SQRT1_2 0.70710678118654752440
#endif
+#ifndef M_1_PI
+#define M_1_PI 0.318309886183790671538
+#endif
#define MAXPATHLEN MAX_PATH
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index e7b5ccd4d54..d84a9d09d4b 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -551,6 +551,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;
@@ -597,6 +598,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/arithb.c b/source/blender/blenlib/intern/arithb.c
index a366862d064..dd9c76d9172 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -3413,6 +3413,66 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv)
*lv = v;
}
+/*http://brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
+ * SMPTE-C XYZ to RGB matrix*/
+void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b)
+{
+ *r = (3.50570 * xc) + (-1.73964 * yc) + (-0.544011 * zc);
+ *g = (-1.06906 * xc) + (1.97781 * yc) + (0.0351720 * zc);
+ *b = (0.0563117 * xc) + (-0.196994 * yc) + (1.05005 * zc);
+}
+
+/*If the requested RGB shade contains a negative weight for
+ one of the primaries, it lies outside the colour gamut
+ accessible from the given triple of primaries. Desaturate
+ it by adding white, equal quantities of R, G, and B, enough
+ to make RGB all positive. The function returns 1 if the
+ components were modified, zero otherwise.*/
+int constrain_rgb(float *r, float *g, float *b)
+{
+ float w;
+
+ /* Amount of white needed is w = - min(0, *r, *g, *b) */
+
+ w = (0 < *r) ? 0 : *r;
+ w = (w < *g) ? w : *g;
+ w = (w < *b) ? w : *b;
+ w = -w;
+
+ /* Add just enough white to make r, g, b all positive. */
+
+ if (w > 0) {
+ *r += w; *g += w; *b += w;
+ return 1; /* Colour modified to fit RGB gamut */
+ }
+
+ return 0; /* Colour within RGB gamut */
+}
+
+/*Transform linear RGB values to nonlinear RGB values. Rec.
+ 709 is ITU-R Recommendation BT. 709 (1990) ``Basic
+ Parameter Values for the HDTV Standard for the Studio and
+ for International Programme Exchange'', formerly CCIR Rec.
+ 709.*/
+void gamma_correct(float *c)
+{
+ /* Rec. 709 gamma correction. */
+ float cc = 0.018;
+
+ if (*c < cc) {
+ *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc;
+ } else {
+ *c = (1.099 * pow(*c, 0.45)) - 0.099;
+ }
+}
+
+void gamma_correct_rgb(float *r, float *g, float *b)
+{
+ gamma_correct(r);
+ gamma_correct(g);
+ gamma_correct(b);
+}
+
/* we define a 'cpack' here as a (3 byte color code) number that can be expressed like 0xFFAA66 or so.
for that reason it is sensitive for endianness... with this function it works correctly
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/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9cfce5e34fa..3c629818b2d 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -7646,6 +7646,23 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+ /* sun/sky */
+ if ((main->versionfile < 246) ){
+ Lamp *la;
+ for(la=main->lamp.first; la; la= la->id.next) {
+ la->sun_effect_type = 0;
+ la->horizon_brightness = 1.0;
+ la->spread = 1.0;
+ la->sun_brightness = 1.0;
+ la->sun_size = 1.0;
+ la->backscattered_light = 1.0;
+ la->atm_turbidity = 2.0;
+ la->atm_inscattering_factor = 1.0;
+ la->atm_extinction_factor = 1.0;
+ la->atm_distance_factor = 1.0;
+ la->sun_intensity = 1.0;
+ }
+ }
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 9f28e13ff7b..ca91f1dc346 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -603,6 +603,9 @@ static void write_sensors(WriteData *wd, ListBase *lb)
case SENS_PROPERTY:
writestruct(wd, DATA, "bPropertySensor", 1, sens->data);
break;
+ case SENS_ACTUATOR:
+ writestruct(wd, DATA, "bActuatorSensor", 1, sens->data);
+ break;
case SENS_COLLISION:
writestruct(wd, DATA, "bCollisionSensor", 1, sens->data);
break;
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_editaction.h b/source/blender/include/BIF_editaction.h
index 2d751f56fc5..7e0f703681b 100644
--- a/source/blender/include/BIF_editaction.h
+++ b/source/blender/include/BIF_editaction.h
@@ -141,6 +141,7 @@ void paste_actdata(void);
/* Group/Channel Operations */
struct bActionGroup *get_active_actiongroup(struct bAction *act);
void set_active_actiongroup(struct bAction *act, struct bActionGroup *agrp, short select);
+void actionbone_group_copycolors(struct bActionGroup *grp, short init_new);
void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]);
void sync_pchan2achan_grouping(void);
void action_groups_group(short add_group);
@@ -166,6 +167,7 @@ void deselect_action_channels(short mode);
void deselect_actionchannels(struct bAction *act, short mode);
int select_channel(struct bAction *act, struct bActionChannel *achan, int selectmode);
void select_actionchannel_by_name(struct bAction *act, char *name, int select);
+void select_action_group_channels(struct bAction *act, struct bActionGroup *agrp);
void selectkeys_leftright (short leftright, short select_mode);
/* Action Markers */
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/BIF_resources.h b/source/blender/include/BIF_resources.h
index e6cbe7bb69a..df514190270 100644
--- a/source/blender/include/BIF_resources.h
+++ b/source/blender/include/BIF_resources.h
@@ -591,6 +591,9 @@ void BIF_load_ui_colors (void);
char *BIF_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid);
char *BIF_ThemeColorsPup(int spacetype);
+/* only for Bone Color sets */
+char *BIF_ThemeColorSetsPup(short inc_custom);
+
void BIF_def_color (BIFColorID colorid, unsigned char r, unsigned char g, unsigned char b);
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/include/blendef.h b/source/blender/include/blendef.h
index a798224b35b..6f8b94d7cd1 100644
--- a/source/blender/include/blendef.h
+++ b/source/blender/include/blendef.h
@@ -409,6 +409,12 @@
#define B_ACTCOPYKEYS 710
#define B_ACTPASTEKEYS 711
+#define B_ACTCUSTCOLORS 712
+#define B_ACTCOLSSELECTOR 713
+#define B_ACTGRP_SELALL 714
+#define B_ACTGRP_ADDTOSELF 715
+#define B_ACTGRP_UNGROUP 716
+
/* TIME: 751 - 800 */
#define B_TL_REW 751
#define B_TL_PLAY 752
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 51f03a676e4..ac9761f165d 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;
@@ -98,8 +99,8 @@ typedef struct bPropertyActuator {
} bPropertyActuator;
typedef struct bObjectActuator {
- short flag, type;
- int damping;
+ short flag, type, otype;
+ short damping;
float forceloc[3], forcerot[3];
float loc[3], rot[3];
float dloc[3], drot[3];
@@ -124,10 +125,13 @@ typedef struct bCameraActuator {
} bCameraActuator ;
typedef struct bConstraintActuator {
+ short type, mode;
short flag, damp;
- float slow;
+ short time, rotdamp;
+ int pad;
float minloc[3], maxloc[3];
float minrot[3], maxrot[3];
+ char matprop[32];
} bConstraintActuator;
typedef struct bGroupActuator {
@@ -192,9 +196,7 @@ typedef struct bVisibilityActuator {
} bVisibilityActuator;
typedef struct bTwoDFilterActuator{
- char pad[2];
- /* bitwise flag for enabling or disabling depth(bit 0) and luminance(bit 1) */
- short texture_flag;
+ char pad[4];
/* Tells what type of 2D Filter */
short type;
/* (flag == 0) means 2D filter is activate and
@@ -249,20 +251,19 @@ typedef struct FreeCamera {
/* objectactuator->flag */
#define ACT_FORCE_LOCAL 1
#define ACT_TORQUE_LOCAL 2
+#define ACT_SERVO_LIMIT_X 2
#define ACT_DLOC_LOCAL 4
+#define ACT_SERVO_LIMIT_Y 4
#define ACT_DROT_LOCAL 8
+#define ACT_SERVO_LIMIT_Z 8
#define ACT_LIN_VEL_LOCAL 16
#define ACT_ANG_VEL_LOCAL 32
//#define ACT_ADD_LIN_VEL_LOCAL 64
#define ACT_ADD_LIN_VEL 64
-#define ACT_CLAMP_VEL 128
-#define ACT_OBJECT_FORCE 0
-#define ACT_OBJECT_TORQUE 1
-#define ACT_OBJECT_DLOC 2
-#define ACT_OBJECT_DROT 3
-#define ACT_OBJECT_LINV 4
-#define ACT_OBJECT_ANGV 5
+/* objectactuator->type */
+#define ACT_OBJECT_NORMAL 0
+#define ACT_OBJECT_SERVO 1
/* actuator->type */
#define ACT_OBJECT 0
@@ -337,8 +338,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
@@ -358,6 +360,22 @@ typedef struct FreeCamera {
#define ACT_CONST_ROTX 8
#define ACT_CONST_ROTY 16
#define ACT_CONST_ROTZ 32
+#define ACT_CONST_NORMAL 64
+#define ACT_CONST_MATERIAL 128
+#define ACT_CONST_PERMANENT 256
+#define ACT_CONST_DISTANCE 512
+/* constraint mode */
+#define ACT_CONST_DIRPX 1
+#define ACT_CONST_DIRPY 2
+#define ACT_CONST_DIRPZ 4
+#define ACT_CONST_DIRMX 8
+#define ACT_CONST_DIRMY 16
+#define ACT_CONST_DIRMZ 32
+
+/* constraint type */
+#define ACT_CONST_TYPE_LOC 0
+#define ACT_CONST_TYPE_DIST 1
+#define ACT_CONST_TYPE_ORI 2
/* editObjectActuator->type */
#define ACT_EDOB_ADD_OBJECT 0
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 73a39abac55..72557145270 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -26,6 +26,7 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
+
#ifndef DNA_CUSTOMDATA_TYPES_H
#define DNA_CUSTOMDATA_TYPES_H
@@ -48,6 +49,7 @@ typedef struct CustomData {
CustomDataLayer *layers; /* CustomDataLayers, ordered by type */
int totlayer, maxlayer; /* number of layers, size of layers array */
int totsize, pad; /* in editmode, total size of all data layers */
+ void *pool; /* for Bmesh: Memory pool for allocation of blocks*/
} CustomData;
/* CustomData.type */
@@ -66,7 +68,10 @@ typedef struct CustomData {
#define CD_PROP_STR 12
#define CD_ORIGSPACE 13 /* for modifier stack face location mapping */
#define CD_ORCO 14
-#define CD_NUMTYPES 15
+#define CD_MTEXPOLY 15
+#define CD_MLOOPUV 16
+#define CD_MLOOPCOL 17
+#define CD_NUMTYPES 18
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)
@@ -84,6 +89,9 @@ typedef struct CustomData {
#define CD_MASK_PROP_STR (1 << CD_PROP_STR)
#define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE)
#define CD_MASK_ORCO (1 << CD_ORCO)
+#define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY)
+#define CD_MASK_MLOOPUV (1 << CD_MLOOPUV)
+#define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL)
/* CustomData.flag */
diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h
index 2afe78289c1..c00dae08eb4 100644
--- a/source/blender/makesdna/DNA_lamp_types.h
+++ b/source/blender/makesdna/DNA_lamp_types.h
@@ -76,6 +76,21 @@ typedef struct Lamp {
/* texact is for buttons */
short texact, shadhalostep;
+ /* sun/sky */
+ short sun_effect_type;
+ short atm_pad[3];
+ float horizon_brightness;
+ float spread;
+ float sun_brightness;
+ float sun_size;
+ float backscattered_light;
+ float sun_intensity;
+ float atm_turbidity;
+ float atm_inscattering_factor;
+ float atm_extinction_factor;
+ float atm_distance_factor;
+
+
/* yafray: photonlight params */
int YF_numphotons, YF_numsearch;
short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
@@ -123,6 +138,10 @@ typedef struct Lamp {
/* Since it is used with LOCAL lamp, can't use LA_SHAD */
#define LA_YF_SOFT 16384
+/* sun effect type*/
+#define LA_SUN_EFFECT_SKY 1
+#define LA_SUN_EFFECT_AP 2
+
/* falloff_type */
#define LA_FALLOFF_CONSTANT 0
#define LA_FALLOFF_INVLINEAR 1
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index a717df640f1..6d025839ac8 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -69,6 +69,21 @@ typedef struct MCol {
char a, r, g, b;
} MCol;
+/*bmesh custom data stuff*/
+typedef struct MTexPoly{
+ struct Image *tpage;
+ char flag, transp;
+ short mode,tile,unwrap;
+}MTexPoly;
+
+typedef struct MLoopUV{
+ float uv[2];
+}MLoopUV;
+
+typedef struct MLoopCol{
+ char a, r, g, b;
+}MLoopCol;
+
typedef struct MSticky {
float co[2];
} MSticky;
diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h
index ae7b92bb06c..c0306f43730 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -82,6 +82,12 @@ typedef struct bPropertySensor {
char maxvalue[32];
} bPropertySensor;
+typedef struct bActuatorSensor {
+ int type;
+ int pad;
+ char name[32];
+} bActuatorSensor;
+
typedef struct bCollisionSensor {
char name[32]; /* property name */
char materialName[32]; /* material */
@@ -197,6 +203,7 @@ typedef struct bJoystickSensor {
#define SENS_RAY 9
#define SENS_MESSAGE 10
#define SENS_JOYSTICK 11
+#define SENS_ACTUATOR 12
/* sensor->flag */
#define SENS_SHOW 1
#define SENS_DEL 2
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/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 3de5b0ff5ba..cd1c047dac9 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -116,6 +116,7 @@ typedef struct ThemeWireColor {
/* flags for ThemeWireColor */
#define TH_WIRECOLOR_CONSTCOLS (1<<0)
+#define TH_WIRECOLOR_TEXTCOLS (1<<1)
/* A theme */
typedef struct bTheme {
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/BPY_interface.c b/source/blender/python/BPY_interface.c
index 2f94e0eeebc..226657655fa 100644
--- a/source/blender/python/BPY_interface.c
+++ b/source/blender/python/BPY_interface.c
@@ -229,13 +229,6 @@ void BPY_start_python( int argc, char **argv )
/* Initialize thread support (also acquires lock) */
PyEval_InitThreads();
- /* Don't allow the Python Interpreter to release the GIL on
- * its own, to guarantee PyNodes work properly. For Blender this
- * is currently the best default behavior.
- * The following code in C is equivalent in Python to:
- * "import sys; sys.setcheckinterval(sys.maxint)" */
- _Py_CheckInterval = PyInt_GetMax();
-
//Overrides __import__
init_ourImport( );
init_ourReload( );
@@ -2188,6 +2181,18 @@ void BPY_do_all_scripts( short event )
BPY_do_pyscript( &( G.scene->id ), event );
+ /* Don't allow the Python Interpreter to release the GIL on
+ * its own, to guarantee PyNodes work properly. For Blender this
+ * is currently the best default behavior.
+ * The following code in C is equivalent in Python to:
+ * "import sys; sys.setcheckinterval(sys.maxint)" */
+ if (event == SCRIPT_RENDER) {
+ _Py_CheckInterval = PyInt_GetMax();
+ }
+ else if (event == SCRIPT_POSTRENDER) {
+ _Py_CheckInterval = 100; /* Python default */
+ }
+
return;
}
@@ -2270,9 +2275,9 @@ void BPY_do_pyscript( ID * id, short event )
return;
}
- /* tell we're running a scriptlink. The sum also tells if this script
- * is running nested inside another. Blender.Load needs this info to
- * avoid trouble with invalid slink pointers. */
+ /* tell we're running a scriptlink. The sum also tells if this
+ * script is running nested inside another. Blender.Load needs
+ * this info to avoid trouble with invalid slink pointers. */
during_slink++;
disable_where_scriptlink( (short)during_slink );
diff --git a/source/blender/python/api2_2x/matrix.c b/source/blender/python/api2_2x/matrix.c
index d81e56ec3dc..9f5e49e8d88 100644
--- a/source/blender/python/api2_2x/matrix.c
+++ b/source/blender/python/api2_2x/matrix.c
@@ -483,7 +483,7 @@ static char MatrixObject_doc[] = "This is a wrapper for matrix objects.";
sequence length*/
static int Matrix_len(MatrixObject * self)
{
- return (self->colSize * self->rowSize);
+ return (self->rowSize);
}
/*----------------------------object[]---------------------------
sequence accessor (get)
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/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h
index ee7199a4295..15d696df89d 100644
--- a/source/blender/render/intern/include/pixelshading.h
+++ b/source/blender/render/intern/include/pixelshading.h
@@ -55,6 +55,7 @@ int shadeHaloFloat(HaloRen *har,
*/
void shadeSkyPixel(float *collector, float fx, float fy);
void shadeSkyView(float *colf, float *rco, float *view, float *dxyview);
+void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance);
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index 8414b6aefe3..2f97b19f75c 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -42,6 +42,7 @@
#include "RE_pipeline.h"
#include "RE_shader_ext.h" /* TexResult, ShadeResult, ShadeInput */
+#include "sunsky.h"
struct Object;
struct MemArena;
@@ -455,6 +456,9 @@ typedef struct LampRen {
float area_size, area_sizey, area_sizez;
float adapt_thresh;
+ /* sun/sky */
+ struct SunSky *sunsky;
+
struct ShadBuf *shb;
float *jitter;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 796a99ca796..faa7a68f754 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -114,6 +114,7 @@
#include "sss.h"
#include "strand.h"
#include "zbuf.h"
+#include "sunsky.h"
#ifndef DISABLE_YAFRAY /* disable yafray */
@@ -203,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,
@@ -3494,6 +3496,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
LampRen *lar;
GroupObject *go;
float mat[4][4], angle, xn, yn;
+ float vec[3];
int c;
/* previewrender sets this to zero... prevent accidents */
@@ -3576,8 +3579,9 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
lar->ray_samp_type= la->ray_samp_type;
lar->adapt_thresh= la->adapt_thresh;
+ lar->sunsky = NULL;
- if( ELEM3(lar->type, LA_SPOT, LA_SUN, LA_LOCAL)) {
+ if( ELEM(lar->type, LA_SPOT, LA_LOCAL)) {
lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
lar->area_shape = LA_AREA_SQUARE;
lar->area_sizey= lar->area_size;
@@ -3607,6 +3611,26 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
area_lamp_vectors(lar);
init_jitter_plane(lar); // subsamples
}
+ else if(lar->type==LA_SUN){
+ lar->ray_totsamp= lar->ray_samp*lar->ray_samp;
+ lar->area_shape = LA_AREA_SQUARE;
+ lar->area_sizey= lar->area_size;
+
+ if((la->sun_effect_type & LA_SUN_EFFECT_SKY) ||
+ (la->sun_effect_type & LA_SUN_EFFECT_AP)){
+ lar->sunsky = (struct SunSky*)MEM_callocN(sizeof(struct SunSky), "sunskyren");
+ lar->sunsky->effect_type = la->sun_effect_type;
+
+ VECCOPY(vec,ob->obmat[2]);
+ Normalize(vec);
+
+ InitSunSky(lar->sunsky, la->atm_turbidity, vec, la->horizon_brightness,
+ la->spread, la->sun_brightness, la->sun_size, la->backscattered_light);
+
+ InitAtmosphere(lar->sunsky, la->sun_intensity, 1.0, 1.0, la->atm_inscattering_factor, la->atm_extinction_factor,
+ la->atm_distance_factor);
+ }
+ }
else lar->ray_totsamp= 0;
#ifndef DISABLE_YAFRAY
@@ -4447,6 +4471,7 @@ void RE_Database_Free(Render *re)
freeshadowbuf(lar);
if(lar->jitter) MEM_freeN(lar->jitter);
if(lar->shadsamp) MEM_freeN(lar->shadsamp);
+ if(lar->sunsky) MEM_freeN(lar->sunsky);
curvemapping_free(lar->curfalloff);
}
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index fc5ac68e8c9..2e3509f0471 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -57,6 +57,7 @@
#include "rendercore.h"
#include "shadbuf.h"
#include "pixelshading.h"
+#include "sunsky.h"
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
@@ -567,13 +568,49 @@ void shadeSkyView(float *colf, float *rco, float *view, float *dxyview)
}
}
+/* shade sky according to sun lamps, all parameters are like shadeSkyView except sunsky*/
+void shadeSunView(struct SunSky *sunsky, float *colf, float *rco, float *view, float *dxyview)
+{
+ float colorxyz[3];
+ float scale;
+
+ /**
+ sunAngle = sqrt(sunsky->sunSolidAngle / M_PI);
+
+ sunDir[0] = sunsky->toSun[0];
+ sunDir[1] = sunsky->toSun[1];
+ sunDir[2] = sunsky->toSun[2];
+ */
+
+ Normalize(view);
+ MTC_Mat3MulVecfl(R.imat, view);
+ if (view[2] < 0.0)
+ view[2] = 0.0;
+ Normalize(view);
+ GetSkyXYZRadiancef(sunsky, view, colorxyz);
+ scale = MAX3(colorxyz[0], colorxyz[1], colorxyz[2]);
+ colorxyz[0] /= scale;
+ colorxyz[1] /= scale;
+ colorxyz[2] /= scale;
+
+ xyz_to_rgb(colorxyz[0], colorxyz[1], colorxyz[2], &colf[0], &colf[1], &colf[2]);
+
+ ClipColor(colf);
+}
+
+
/*
Stuff the sky color into the collector.
*/
void shadeSkyPixel(float *collector, float fx, float fy)
{
float view[3], dxyview[2];
-
+ float sun_collector[3];
+ float suns_color[3];
+ short num_sun_lamp;
+ GroupObject *go;
+ LampRen *lar;
+
/*
The rules for sky:
1. Draw an image, if a background image was provided. Stop
@@ -585,7 +622,6 @@ void shadeSkyPixel(float *collector, float fx, float fy)
/* 1. Do a backbuffer image: */
if(R.r.bufflag & 1) {
fillBackgroundImage(collector, fx, fy);
- return;
}
else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
/* 2. solid color */
@@ -620,7 +656,45 @@ void shadeSkyPixel(float *collector, float fx, float fy)
shadeSkyView(collector, NULL, view, dxyview);
collector[3] = 0.0f;
}
+
+ suns_color[0] = suns_color[1] = suns_color[2] = 0;
+ num_sun_lamp = 0;
+ for(go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_SKY)){
+
+ num_sun_lamp ++;
+ calc_view_vector(view, fx, fy);
+ Normalize(view);
+
+ shadeSunView(lar->sunsky, sun_collector, NULL, view, NULL);
+ suns_color[0] += sun_collector[0];
+ suns_color[1] += sun_collector[1];
+ suns_color[2] += sun_collector[2];
+
+ }
+ }
+ if( num_sun_lamp > 0 ){
+ suns_color[0] /= num_sun_lamp;
+ suns_color[1] /= num_sun_lamp;
+ suns_color[2] /= num_sun_lamp;
+
+ collector[0] += suns_color[0];
+ collector[1] += suns_color[1];
+ collector[2] += suns_color[2];
+ ClipColor(collector);
+ }
}
+/* aerial perspective */
+void shadeAtmPixel(struct SunSky *sunsky, float *collector, float fx, float fy, float distance)
+{
+ float view[3];
+
+ calc_view_vector(view, fx, fy);
+ Normalize(view);
+ /*MTC_Mat3MulVecfl(R.imat, view);*/
+ AtmospherePixleShader(sunsky, view, distance, collector);
+}
/* eof */
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index dae7b0dcd88..67be0ce4c00 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -47,6 +47,7 @@
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_group_types.h"
#include "BKE_global.h"
#include "BKE_image.h"
@@ -665,6 +666,88 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
}
}
+static void atm_tile(RenderPart *pa, RenderLayer *rl)
+{
+ RenderPass *zpass;
+ GroupObject *go;
+ LampRen *lar;
+
+ int x, y;
+ short first_lamp;
+ float *zrect;
+ float *rgbrect;
+ float rgb[3]={0};
+ float tmp_rgb[3];
+ float fac;
+ float facm;
+
+ fac = 0.5;
+ facm = 1.0 - fac;
+
+ /* check that z pass is enabled */
+ if(pa->rectz==NULL) return;
+ for(zpass= rl->passes.first; zpass; zpass= zpass->next)
+ if(zpass->passtype==SCE_PASS_Z)
+ break;
+
+ if(zpass==NULL) return;
+
+ /* check for at least one sun lamp that its atmosphere flag is is enabled */
+ first_lamp = 1;
+ for(go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar->type==LA_SUN && lar->sunsky &&
+ (lar->sunsky->effect_type & LA_SUN_EFFECT_AP)){
+ first_lamp = 0;
+ break;
+ }
+ }
+ /* do nothign and return if there is no sun lamp */
+ if(first_lamp)
+ return;
+
+ zrect = zpass->rect;
+ rgbrect = rl->rectf;
+ /* for each x,y and sun lamp*/
+ for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
+ for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, zrect++, rgbrect+=4) {
+
+ first_lamp = 1;
+ for(go=R.lights.first; go; go= go->next) {
+ lar= go->lampren;
+ if(lar->type==LA_SUN && lar->sunsky)
+
+ {
+ /* if it's sky continue and don't apply atmosphere effect on it */
+ if(*zrect >= 9.9e10){
+ continue;
+ }
+
+ if(lar->sunsky->effect_type & LA_SUN_EFFECT_AP){
+ VECCOPY(tmp_rgb, rgbrect);
+
+ shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
+
+ if(first_lamp){
+ VECCOPY(rgb, tmp_rgb);
+ first_lamp = 0;
+ }
+ else{
+ rgb[0] = facm*rgb[0] + fac*tmp_rgb[0];
+ rgb[1] = facm*rgb[1] + fac*tmp_rgb[1];
+ rgb[2] = facm*rgb[2] + fac*tmp_rgb[2];
+ }
+ }
+ }
+ }
+
+ /* if at least for one sun lamp aerial perspective was applied*/
+ if(first_lamp==0)
+ VECCOPY(rgbrect, rgb);
+ }
+ }
+}
+
static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
{
RenderResult *rr= pa->result;
@@ -1122,6 +1205,10 @@ void zbufshadeDA_tile(RenderPart *pa)
if(R.r.mode & R_EDGE)
edge_enhance_add(pa, rl->rectf, edgerect);
+ /* sun/sky */
+ if(rl->layflag & SCE_LAY_SKY)
+ atm_tile(pa, rl);
+
if(rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
@@ -1282,6 +1369,10 @@ void zbufshade_tile(RenderPart *pa)
edge_enhance_add(pa, rl->rectf, edgerect);
}
+ /* sun/sky */
+ if(rl->layflag & SCE_LAY_SKY)
+ atm_tile(pa, rl);
+
if(rl->passflag & SCE_PASS_VECTOR)
reset_sky_speed(pa, rl);
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 36ab0961150..a21dc8b0f5d 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -5291,32 +5291,6 @@ static void verify_posegroup_groupname(void *arg1, void *arg2)
BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
}
-static char *build_colorsets_menustr ()
-{
- DynStr *pupds= BLI_dynstr_new();
- char *str;
- char buf[48];
- int i;
-
- /* add title first (and the "default" entry) */
- BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|");
-
- /* loop through set indices, adding them */
- for (i=1; i<21; i++) {
- sprintf(buf, "%d - Theme Color Set%%x%d|", i, i);
- BLI_dynstr_append(pupds, buf);
- }
-
- /* add the 'custom' entry */
- BLI_dynstr_append(pupds, "Custom Set %x-1");
-
- /* convert to normal MEM_malloc'd string */
- str= BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-
- return str;
-}
-
static void editing_panel_links(Object *ob)
{
uiBlock *block;
@@ -5476,32 +5450,14 @@ static void editing_panel_links(Object *ob)
/* color set for 'active' group */
if (pose->active_group && grp) {
uiBlockBeginAlign(block);
- menustr= build_colorsets_menustr();
+ menustr= BIF_ThemeColorSetsPup(1);
uiDefButI(block, MENU,B_POSEGRP_RECALC, menustr, xco,85,140,19, &grp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme");
MEM_freeN(menustr);
/* show color-selection/preview */
if (grp->customCol) {
- if (grp->customCol > 0) {
- /* copy theme colors on-to group's custom color in case user tries to edit color */
- bTheme *btheme= U.themes.first;
- ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
-
- memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
- }
- else {
- /* init custom colors with a generic multi-color rgb set, if not initialised already */
- if (grp->cs.solid[0] == 0) {
- /* define for setting colors in theme below */
- #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
-
- SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
- SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
- SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
-
- #undef SETCOL
- }
- }
+ /* do color copying/init (to stay up to date) */
+ actionbone_group_copycolors(grp, 1);
/* color changing */
uiDefButC(block, COL, B_POSEGRP_MCUSTOM, "", xco, 65, 30, 19, grp->cs.solid, 0, 0, 0, 0, "Color to use for surface of bones");
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index 4e5e8a605ee..441d00ffc30 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -387,7 +387,6 @@ void do_logic_buts(unsigned short event)
bSensor *sens;
bController *cont;
bActuator *act;
- Base *base;
Object *ob;
int didit, bit;
@@ -443,16 +442,14 @@ void do_logic_buts(unsigned short event)
break;
case B_ADD_SENS:
- base= FIRSTBASE;
- while(base) {
- if(base->object->scaflag & OB_ADDSENS) {
- base->object->scaflag &= ~OB_ADDSENS;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ if(ob->scaflag & OB_ADDSENS) {
+ ob->scaflag &= ~OB_ADDSENS;
sens= new_sensor(SENS_ALWAYS);
- BLI_addtail(&(base->object->sensors), sens);
+ BLI_addtail(&(ob->sensors), sens);
make_unique_prop_names(sens->name);
- base->object->scaflag |= OB_SHOWSENS;
+ ob->scaflag |= OB_SHOWSENS;
}
- base= base->next;
}
BIF_undo_push("Add sensor");
@@ -460,9 +457,8 @@ void do_logic_buts(unsigned short event)
break;
case B_CHANGE_SENS:
- base= FIRSTBASE;
- while(base) {
- sens= base->object->sensors.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ sens= ob->sensors.first;
while(sens) {
if(sens->type != sens->otype) {
init_sensor(sens);
@@ -471,43 +467,39 @@ void do_logic_buts(unsigned short event)
}
sens= sens->next;
}
- base= base->next;
}
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_DEL_SENS:
- base= FIRSTBASE;
- while(base) {
- sens= base->object->sensors.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ sens= ob->sensors.first;
while(sens) {
if(sens->flag & SENS_DEL) {
- BLI_remlink(&(base->object->sensors), sens);
+ BLI_remlink(&(ob->sensors), sens);
free_sensor(sens);
break;
}
sens= sens->next;
}
- base= base->next;
}
BIF_undo_push("Delete sensor");
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_ADD_CONT:
- base= FIRSTBASE;
- while(base) {
- if(base->object->scaflag & OB_ADDCONT) {
- base->object->scaflag &= ~OB_ADDCONT;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ if(ob->scaflag & OB_ADDCONT) {
+ ob->scaflag &= ~OB_ADDCONT;
cont= new_controller(CONT_LOGIC_AND);
make_unique_prop_names(cont->name);
- base->object->scaflag |= OB_SHOWCONT;
- BLI_addtail(&(base->object->controllers), cont);
+ ob->scaflag |= OB_SHOWCONT;
+ BLI_addtail(&(ob->controllers), cont);
/* set the controller state mask from the current object state.
A controller is always in a single state, so select the lowest bit set
from the object state */
for (bit=0; bit<32; bit++) {
- if (base->object->state & (1<<bit))
+ if (ob->state & (1<<bit))
break;
}
cont->state_mask = (1<<bit);
@@ -516,42 +508,36 @@ void do_logic_buts(unsigned short event)
cont->state_mask = 1;
}
}
- base= base->next;
}
BIF_undo_push("Add controller");
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_SET_STATE_BIT:
- base= FIRSTBASE;
- while(base) {
- if(base->object->scaflag & OB_SETSTBIT) {
- base->object->scaflag &= ~OB_SETSTBIT;
- base->object->state = 0x3FFFFFFF;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ if(ob->scaflag & OB_SETSTBIT) {
+ ob->scaflag &= ~OB_SETSTBIT;
+ ob->state = 0x3FFFFFFF;
}
- base= base->next;
}
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_INIT_STATE_BIT:
- base= FIRSTBASE;
- while(base) {
- if(base->object->scaflag & OB_INITSTBIT) {
- base->object->scaflag &= ~OB_INITSTBIT;
- base->object->state = base->object->init_state;
- if (!base->object->state)
- base->object->state = 1;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ if(ob->scaflag & OB_INITSTBIT) {
+ ob->scaflag &= ~OB_INITSTBIT;
+ ob->state = ob->init_state;
+ if (!ob->state)
+ ob->state = 1;
}
- base= base->next;
}
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_CHANGE_CONT:
- base= FIRSTBASE;
- while(base) {
- cont= base->object->controllers.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ cont= ob->controllers.first;
while(cont) {
if(cont->type != cont->otype) {
init_controller(cont);
@@ -560,51 +546,45 @@ void do_logic_buts(unsigned short event)
}
cont= cont->next;
}
- base= base->next;
}
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_DEL_CONT:
- base= FIRSTBASE;
- while(base) {
- cont= base->object->controllers.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ cont= ob->controllers.first;
while(cont) {
if(cont->flag & CONT_DEL) {
- BLI_remlink(&(base->object->controllers), cont);
+ BLI_remlink(&(ob->controllers), cont);
unlink_controller(cont);
free_controller(cont);
break;
}
cont= cont->next;
}
- base= base->next;
}
BIF_undo_push("Delete controller");
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_ADD_ACT:
- base= FIRSTBASE;
- while(base) {
- if(base->object->scaflag & OB_ADDACT) {
- base->object->scaflag &= ~OB_ADDACT;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ if(ob->scaflag & OB_ADDACT) {
+ ob->scaflag &= ~OB_ADDACT;
act= new_actuator(ACT_OBJECT);
make_unique_prop_names(act->name);
- BLI_addtail(&(base->object->actuators), act);
- base->object->scaflag |= OB_SHOWACT;
+ BLI_addtail(&(ob->actuators), act);
+ ob->scaflag |= OB_SHOWACT;
}
- base= base->next;
}
BIF_undo_push("Add actuator");
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_CHANGE_ACT:
- base= FIRSTBASE;
- while(base) {
- act= base->object->actuators.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ act= ob->actuators.first;
while(act) {
if(act->type != act->otype) {
init_actuator(act);
@@ -613,25 +593,22 @@ void do_logic_buts(unsigned short event)
}
act= act->next;
}
- base= base->next;
}
allqueue(REDRAWBUTSLOGIC, 0);
break;
case B_DEL_ACT:
- base= FIRSTBASE;
- while(base) {
- act= base->object->actuators.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ act= ob->actuators.first;
while(act) {
if(act->flag & ACT_DEL) {
- BLI_remlink(&(base->object->actuators), act);
+ BLI_remlink(&(ob->actuators), act);
unlink_actuator(act);
free_actuator(act);
break;
}
act= act->next;
}
- base= base->next;
}
BIF_undo_push("Delete actuator");
allqueue(REDRAWBUTSLOGIC, 0);
@@ -640,10 +617,8 @@ void do_logic_buts(unsigned short event)
case B_SOUNDACT_BROWSE:
/* since we don't know which... */
didit= 0;
- base= FIRSTBASE;
- while(base)
- {
- act= base->object->actuators.first;
+ for(ob=G.main->object.first; ob; ob=ob->id.next) {
+ act= ob->actuators.first;
while(act)
{
if(act->type==ACT_SOUND)
@@ -684,7 +659,6 @@ void do_logic_buts(unsigned short event)
}
if(didit)
break;
- base= base->next;
}
allqueue(REDRAWBUTSLOGIC, 0);
allqueue(REDRAWSOUND, 0);
@@ -707,6 +681,8 @@ static char *sensor_name(int type)
return "Keyboard";
case SENS_PROPERTY:
return "Property";
+ case SENS_ACTUATOR:
+ return "Actuator";
case SENS_MOUSE:
return "Mouse";
case SENS_COLLISION:
@@ -730,7 +706,7 @@ static char *sensor_pup(void)
/* the number needs to match defines in game.h */
return "Sensors %t|Always %x0|Keyboard %x3|Mouse %x5|"
"Touch %x1|Collision %x6|Near %x2|Radar %x7|"
- "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11";
+ "Property %x4|Random %x8|Ray %x9|Message %x10|Joystick %x11|Actuator %x12";
}
static char *controller_name(int type)
@@ -1029,6 +1005,7 @@ static int get_col_sensor(int type)
case SENS_NEAR: return TH_BUT_SETTING1;
case SENS_KEYBOARD: return TH_BUT_SETTING2;
case SENS_PROPERTY: return TH_BUT_NUM;
+ case SENS_ACTUATOR: return TH_BUT_NUM;
case SENS_MOUSE: return TH_BUT_TEXTFIELD;
case SENS_RADAR: return TH_BUT_POPUP;
case SENS_RANDOM: return TH_BUT_NEUTRAL;
@@ -1093,6 +1070,7 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
bRaySensor *raySens = NULL;
bMessageSensor *mes = NULL;
bJoystickSensor *joy = NULL;
+ bActuatorSensor *as = NULL;
short ysize;
char *str;
@@ -1303,6 +1281,22 @@ static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short
yco-= ysize;
break;
}
+ case SENS_ACTUATOR:
+ {
+ ysize= 48;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize,
+ (float)xco+width, (float)yco, 1);
+
+ draw_default_sensor_header(sens, block, xco, yco, width);
+ as= sens->data;
+
+ uiDefBut(block, TEX, 1, "Act: ", xco+30,yco-44,width-60, 19,
+ as->name, 0, 31, 0, 0, "Actuator name, actuator active state modifications will be detected");
+ yco-= ysize;
+ break;
+ }
case SENS_MOUSE:
{
ms= sens->data;
@@ -1563,6 +1557,48 @@ static void set_col_actuator(int item, int medium)
}
+static void change_object_actuator(void *act, void *arg)
+{
+ bObjectActuator *oa = act;
+
+ if (oa->type != oa->otype) {
+ switch (oa->type) {
+ case ACT_OBJECT_NORMAL:
+ memset(oa, 0, sizeof(bObjectActuator));
+ oa->flag = ACT_FORCE_LOCAL|ACT_TORQUE_LOCAL|ACT_DLOC_LOCAL|ACT_DROT_LOCAL;
+ oa->type = ACT_OBJECT_NORMAL;
+ break;
+
+ case ACT_OBJECT_SERVO:
+ memset(oa, 0, sizeof(bObjectActuator));
+ oa->flag = ACT_LIN_VEL_LOCAL;
+ oa->type = ACT_OBJECT_SERVO;
+ oa->forcerot[0] = 30.0f;
+ oa->forcerot[1] = 0.5f;
+ oa->forcerot[2] = 0.0f;
+ break;
+ }
+ }
+}
+
+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;
+ oa->forcerot[0] = 60.0f*oa->forcerot[1];
+}
+
char *get_state_name(Object *ob, short bit)
{
bController *cont;
@@ -1604,6 +1640,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
short ysize = 0, wval;
char *str;
int myline, stbit;
+ uiBut *but;
/* yco is at the top of the rect, draw downwards */
uiBlockSetEmboss(block, UI_EMBOSSM);
@@ -1613,57 +1650,100 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
{
case ACT_OBJECT:
{
- ysize= 152;
-
- glRects(xco, yco-ysize, xco+width, yco);
- uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
-
oa = act->data;
wval = (width-100)/3;
-
- uiDefBut(block, LABEL, 0, "Force", xco, yco-22, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
- uiDefButF(block, NUM, 0, "", xco+45, yco-22, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-22, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-22, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
-
- uiDefBut(block, LABEL, 0, "Torque", xco, yco-41, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
- uiDefButF(block, NUM, 0, "", xco+45, yco-41, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-41, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-41, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
-
- uiDefBut(block, LABEL, 0, "dLoc", xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc");
- uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
-
- uiDefBut(block, LABEL, 0, "dRot", xco, yco-83, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot");
- uiDefButF(block, NUM, 0, "", xco+45, yco-83, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-83, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-83, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
-
- uiDefBut(block, LABEL, 0, "linV", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
- uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
-
- uiDefBut(block, LABEL, 0, "angV", xco, yco-125, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
- uiDefButF(block, NUM, 0, "", xco+45, yco-125, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+wval, yco-125, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-125, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, "");
-
- uiDefBut(block, LABEL, 0, "damp", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity");
- uiDefButI(block, NUM, 0, "", xco+45, yco-148, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, "");
- uiDefButBitS(block, TOG, ACT_CLAMP_VEL, 0, "clamp",xco+45+wval, yco-148, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between SET and CLAMP Velocity");
-
- uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-22, 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-41, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-83, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
- uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-125, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
-
- uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-106, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
-
+ if (oa->type == ACT_OBJECT_NORMAL)
+ {
+ ysize= 175;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+
+ uiDefBut(block, LABEL, 0, "Force", xco, yco-45, 55, 19, NULL, 0, 0, 0, 0, "Sets the force");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, "");
+
+ uiDefBut(block, LABEL, 0, "Torque", xco, yco-64, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");
+
+ uiDefBut(block, LABEL, 0, "dLoc", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
+
+ uiDefBut(block, LABEL, 0, "dRot", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
+
+ uiDefBut(block, LABEL, 0, "linV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
+
+ uiDefBut(block, LABEL, 0, "angV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, "");
+ 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");
+ 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");
+ uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+ uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation");
+
+ uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV");
+
+ } else if (oa->type == ACT_OBJECT_SERVO)
+ {
+ ysize= 172;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+
+ uiDefBut(block, LABEL, 0, "linV", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the target linear velocity, it will be achieve by automatic application of force. Null velocity is a valid target");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, "");
+ uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Velocity is defined in local coordinates");
+
+ uiDefBut(block, LABEL, 0, "Limit", xco, yco-68, 45, 19, NULL, 0, 0, 0, 0, "Select if the force need to be limited along certain axis (local or global depending on LinV Local flag)");
+ uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_X, B_REDR, "X", xco+45, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the X axis");
+ uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Y, B_REDR, "Y", xco+45+wval, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Y axis");
+ uiDefButBitS(block, TOG, ACT_SERVO_LIMIT_Z, B_REDR, "Z", xco+45+2*wval, yco-68, wval, 19, &oa->flag, 0.0, 0.0, 0, 0, "Set limit to force along the Z axis");
+ uiDefBut(block, LABEL, 0, "Max", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Set the upper limit for force");
+ uiDefBut(block, LABEL, 0, "Min", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Set the lower limit for force");
+ if (oa->flag & ACT_SERVO_LIMIT_X) {
+ uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, "");
+ }
+ if (oa->flag & ACT_SERVO_LIMIT_Y) {
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, "");
+ }
+ if (oa->flag & ACT_SERVO_LIMIT_Z) {
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, "");
+ }
+ uiDefBut(block, LABEL, 0, "Servo", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Coefficients of the PID servo controller");
+ uiDefButF(block, NUMSLI, B_REDR, "P: ", xco+45, yco-129, wval*3, 19, oa->forcerot, 0.00, 200.0, 100, 0, "Proportional coefficient, typical value is 60x Integral coefficient");
+ uiDefBut(block, LABEL, 0, "Slow", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Low value of I coefficient correspond to slow response");
+ but = uiDefButF(block, NUMSLI, B_REDR, " I : ", xco+45, yco-148, wval*3, 19, oa->forcerot+1, 0.0, 3.0, 1, 0, "Integral coefficient, low value (0.01) for slow response, high value (0.5) for fast response");
+ uiButSetFunc(but, update_object_actuator_PID, oa, NULL);
+ uiDefBut(block, LABEL, 0, "Fast", xco+45+3*wval, yco-148, 45, 19, NULL, 0, 0, 0, 0, "High value of I coefficient correspond to fast response");
+ uiDefButF(block, NUMSLI, B_REDR, "D: ", xco+45, yco-167, wval*3, 19, oa->forcerot+2, -100.0, 100.0, 100, 0, "Derivate coefficient, not required, high values can cause instability");
+ }
+ str= "Motion Type %t|Simple motion %x0|Servo Control %x1";
+ but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &oa->type, 0.0, 0.0, 0, 0, "");
+ oa->otype = oa->type;
+ uiButSetFunc(but, change_object_actuator, oa, NULL);
yco-= ysize;
break;
}
@@ -1689,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
@@ -1731,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;
}
@@ -1898,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;
@@ -1956,34 +2047,97 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
break;
case ACT_CONSTRAINT:
+ coa= act->data;
- ysize= 44;
+ if (coa->type == ACT_CONST_TYPE_LOC) {
+ ysize= 69;
- glRects(xco, yco-ysize, xco+width, yco);
- uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+
+ /* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */
+ /* coa->flag &= ~(63); */
+ str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4";
+ coa->flag &= ~(7);
+ coa->time = 0;
+ uiDefButS(block, MENU, 1, str, xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, "");
- coa= act->data;
+ uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Min", xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
+
+ if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc;
+ else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1;
+ else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2;
+ else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot;
+ else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1;
+ else fp= coa->minrot+2;
+
+ uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, "");
+ } else if (coa->type == ACT_CONST_TYPE_DIST) {
+ ysize= 106;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+
+ str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32";
+ uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray");
-/* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */
- str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4";
- uiDefButS(block, MENU, 1, str, xco+10, yco-40, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, "");
-
- uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-20, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "Min", xco+80, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
- uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-20, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, "");
-
- if(coa->flag & ACT_CONST_LOCX) fp= coa->minloc;
- else if(coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1;
- else if(coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2;
- else if(coa->flag & ACT_CONST_ROTX) fp= coa->minrot;
- else if(coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1;
- else fp= coa->minrot+2;
+ uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Range", xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray");
+ uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist", xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray");
+
+ if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRMX)) fp= coa->minloc;
+ else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRMY)) fp= coa->minloc+1;
+ else fp= coa->minloc+2;
+
+ uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray");
+ if (coa->flag & ACT_CONST_DISTANCE)
+ uiDefButF(block, NUM, 0, "", xco+80+(width-115)/2, yco-65, (width-115)/2, 19, fp, -2000.0, 2000.0, 10, 0, "Keep this distance to target");
+ uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19,
+ &coa->flag, 0.0, 0.0, 0, 0, "Set object axis along the normal at hit position");
+ uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19,
+ &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property");
+ if (coa->flag & ACT_CONST_MATERIAL)
+ {
+ uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19,
+ coa->matprop, 0, 31, 0, 0,
+ "Ray detects only Objects with this material");
+ }
+ else
+ {
+ uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19,
+ coa->matprop, 0, 31, 0, 0,
+ "Ray detect only Objects with this property");
+ }
+ uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19,
+ &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target");
+ uiDefButS(block, NUM, 0, "time", xco+50, yco-103, (width-60)/2, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
+ uiDefButS(block, NUM, 0, "rotDamp", xco+50+(width-60)/2, yco-103, (width-60)/2, 19, &(coa->rotdamp), 0.0, 100.0, 0, 0, "Use a different damping for orientation");
+ } else if (coa->type == ACT_CONST_TYPE_ORI) {
+ ysize= 87;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+
+ str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4";
+ uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction");
- uiDefButF(block, NUM, 0, "", xco+80, yco-40, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, "");
- uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-40, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, "");
+ uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/3, 19, &coa->maxrot[0], -2000.0, 2000.0, 10, 0, "X component of reference direction");
+ uiDefButF(block, NUM, 0, "", xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction");
+ uiDefButF(block, NUM, 0, "", xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction");
+
+ uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70+(width-115)/3, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited");
+ }
+ str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2";
+ but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, "");
yco-= ysize;
-
break;
case ACT_SCENE:
@@ -2116,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;
@@ -2382,11 +2536,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
break;
case ACT_2DFILTER_CUSTOMFILTER:
uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30,yco-44,width-60,19,&tdfa->int_arg,0.0,MAX_RENDER_PASS-1,0.0,0.0,"Set motion blur value");
- uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width/2-32, 19, &tdfa->text, "");
- uiDefButS(block, TOG|BIT|0, B_REDR, "Depth", xco+width/2+2 , yco - 64, width/4-16 , 19,
- &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Depth Texture (bgl_DepthTexture)");
- uiDefButS(block, TOG|BIT|1, B_REDR, "Luminance", xco+3*width/4-14 , yco - 64, width/4-16 , 19,
- &tdfa->texture_flag, 0.0, 0.0, 0, 0, "Includes Luminance Texture (bgl_LuminanceTexture)");
+ uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30,yco-64,width-60, 19, &tdfa->text, "");
break;
}
@@ -2994,6 +3144,8 @@ void logic_buts(void)
ob= OBACT;
for(a=0; a<count; a++) {
+ unsigned int controller_state_mask = 0; /* store a bitmask for states that are used */
+
ob= (Object *)idar[a];
uiClearButLock();
uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
@@ -3018,6 +3170,7 @@ void logic_buts(void)
act = cont->links[iact];
act->flag |= ACT_LINKED;
}
+ controller_state_mask |= cont->state_mask;
cont = cont->next;
}
@@ -3032,11 +3185,11 @@ void logic_buts(void)
for (offset=0; offset<15; offset+=5) {
uiBlockBeginAlign(block);
for (stbit=0; stbit<5; stbit++) {
- but = uiDefButBitI(block, TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset)));
+ but = uiDefButBitI(block, controller_state_mask&(1<<(stbit+offset)) ? BUT_TOGDUAL:TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset)));
uiButSetFunc(but, check_object_state, but, &(ob->state));
}
for (stbit=0; stbit<5; stbit++) {
- but = uiDefButBitI(block, 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));
}
}
@@ -3120,7 +3273,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++) {
@@ -3193,7 +3346,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 1c98950080a..af90d01fb59 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 04a497ffdea..1b580381ca5 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -2803,6 +2803,42 @@ static void lamp_panel_yafray(Object *ob, Lamp *la)
}
+static void lamp_panel_atmosphere(Object *ob, Lamp *la)
+{
+ uiBlock *block;
+ int y;
+ block= uiNewBlock(&curarea->uiblocks, "lamp_panel_atm", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Shadow and Spot", "Lamp");
+ if(uiNewPanel(curarea, block, "Sky/Atmosphere", "Lamp", 3*PANELX, PANELY, PANELW, PANELH)==0) return;
+
+ uiSetButLock(la->id.lib!=0, ERROR_LIBDATA_MESSAGE);
+
+ uiDefButBitS(block, TOG, LA_SUN_EFFECT_SKY, REDRAWVIEW3D, "Sky", 10,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on sky.");
+ uiDefButBitS(block, TOG, LA_SUN_EFFECT_AP, REDRAWVIEW3D, "Atmosphere", 20+BUTW2,205,BUTW2,20,&(la->sun_effect_type), 0, 0, 0, 0, "Apply sun light effect on atmosphere.");
+
+ if(la->sun_effect_type & (LA_SUN_EFFECT_SKY|LA_SUN_EFFECT_AP)){
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Turbidity:",10,180,BUTW1,19, &(la->atm_turbidity), 1.000f, 30.0f, 1, 0, "Sky Turbidity");
+ }
+
+ y = 180;
+ if(la->sun_effect_type & LA_SUN_EFFECT_SKY)
+ {
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Hor.Bright:",10,y-25,BUTW2,19, &(la->horizon_brightness), 0.00f, 20.00f, 10, 0, "Sets horizon brightness.");
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Hor.Spread:",10,y-50,BUTW2,19, &(la->spread), 0.00f, 10.00f, 10, 0, "Sets horizon spread.");
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Bright:",10,y-75,BUTW2,19, &(la->sun_brightness), 0.00f, 10.0f, 10, 0, "Sets sun brightness.");
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Size:",10,y-100,BUTW2,19, &(la->sun_size), 0.00f, 10.00f, 10, 0, "Sets sun size.");
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Back Light:",10,y-125,BUTW2,19, &(la->backscattered_light), -1.00f, 1.00f, 10, 0, "Sets backscatter light.");
+ }
+
+ if(la->sun_effect_type & LA_SUN_EFFECT_AP)
+ {
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Sun Intens.:",20+BUTW2,y-25,BUTW2,19, &(la->sun_intensity), 0.00f, 10.00f, 10, 0, "Sets sun intensity.");
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Inscattering:",20+BUTW2,y-50,BUTW2,19, &(la->atm_inscattering_factor), 0.00f, 1.00f, 10, 0, "In Scattering Contribution Factor.");
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Extinction:",20+BUTW2,y-75,BUTW2,19, &(la->atm_extinction_factor), 0.00f, 1.00f, 10, 0, "Extinction Scattering Contribution Factor.");
+ uiDefButF(block, NUM, B_LAMPREDRAW, "Distance:",20+BUTW2,y-100,BUTW2,19, &(la->atm_distance_factor), 0.000f, 500.0f, 10, 0, "Scale blender distance to real distance.");
+ }
+}
+
static void lamp_panel_falloff(Object *ob, Lamp *la)
{
uiBlock *block;
@@ -2864,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);
@@ -4354,6 +4390,11 @@ void lamp_panels()
/* spherelight radius default is zero, so nothing to do */
lamp_panel_yafray(ob, la);
}
+
+ if(la->type == LA_SUN){
+ lamp_panel_atmosphere(ob, ob->data);
+ }
+
lamp_panel_texture(ob, ob->data);
lamp_panel_mapto(ob, ob->data);
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index 89466151a39..6fe37c1c6e5 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -32,6 +32,7 @@
#include <math.h>
#include <stdlib.h>
+#include <string.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -56,6 +57,7 @@
#include "DNA_space_types.h"
#include "DNA_constraint_types.h"
#include "DNA_key_types.h"
+#include "DNA_userdef_types.h"
#include "BKE_action.h"
#include "BKE_depsgraph.h"
@@ -928,12 +930,55 @@ static void draw_channel_strips(void)
void do_actionbuts(unsigned short event)
{
switch(event) {
+ /* general */
case REDRAWVIEW3D:
allqueue(REDRAWVIEW3D, 0);
break;
case B_REDR:
allqueue(REDRAWACTION, 0);
break;
+
+ /* action-groups */
+ case B_ACTCUSTCOLORS: /* only when of the color wells is edited */
+ {
+ bActionGroup *agrp= get_active_actiongroup(G.saction->action);
+
+ if (agrp)
+ agrp->customCol= -1;
+
+ allqueue(REDRAWACTION, 0);
+ }
+ break;
+ case B_ACTCOLSSELECTOR: /* sync color set after using selector */
+ {
+ bActionGroup *agrp= get_active_actiongroup(G.saction->action);
+
+ if (agrp)
+ actionbone_group_copycolors(agrp, 1);
+
+ allqueue(REDRAWACTION, 0);
+ }
+ break;
+ case B_ACTGRP_SELALL: /* select all grouped channels */
+ {
+ bAction *act= G.saction->action;
+ bActionGroup *agrp= get_active_actiongroup(act);
+
+ /* select all in group, then reselect/activate group as the previous operation clears that */
+ select_action_group_channels(act, agrp);
+ agrp->flag |= (AGRP_ACTIVE|AGRP_SELECTED);
+
+ allqueue(REDRAWACTION, 0);
+ }
+ break;
+ case B_ACTGRP_ADDTOSELF: /* add all selected action channels to self */
+ action_groups_group(0);
+ break;
+ case B_ACTGRP_UNGROUP: /* remove channels from active group */
+ // FIXME: todo...
+ printf("FIXME: remove achans from active Action-Group not implemented yet! \n");
+ break;
+
}
}
@@ -941,14 +986,68 @@ void do_actionbuts(unsigned short event)
static void action_panel_properties(short cntrl) // ACTION_HANDLER_PROPERTIES
{
uiBlock *block;
-
+ void *data;
+ short datatype;
+
block= uiNewBlock(&curarea->uiblocks, "action_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(ACTION_HANDLER_PROPERTIES); // for close and esc
- if (uiNewPanel(curarea, block, "Transform Properties", "Action", 10, 230, 318, 204)==0)
+
+ /* get datatype */
+ data= get_action_context(&datatype);
+ //if (data == NULL) return;
+
+ if (uiNewPanel(curarea, block, "Active Channel Properties", "Action", 10, 230, 318, 204)==0)
return;
-
- uiDefBut(block, LABEL, 0, "test text", 10,180,300,19, 0, 0, 0, 0, 0, "");
+
+ /* currently, only show data for actions */
+ if (datatype == ACTCONT_ACTION) {
+ bActionGroup *agrp= get_active_actiongroup(data);
+ //bActionChannel *achan= get_hilighted_action_channel(data);
+ char *menustr;
+
+ /* only for action-groups */
+ if (agrp) {
+ /* general stuff */
+ uiDefBut(block, LABEL, 1, "Action Group:", 10, 180, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefBut(block, TEX, B_REDR, "Name: ", 10,160,150,20, agrp->name, 0.0, 31.0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, AGRP_EXPANDED, B_REDR, "Expanded", 170, 160, 75, 20, &agrp->flag, 0, 0, 0, 0, "Action Group is expanded");
+ uiDefButBitI(block, TOG, AGRP_PROTECTED, B_REDR, "Protected", 245, 160, 75, 20, &agrp->flag, 0, 0, 0, 0, "Action Group is protected");
+ uiBlockEndAlign(block);
+
+ /* color stuff */
+ uiDefBut(block, LABEL, 1, "Group Colors:", 10, 107, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
+ uiBlockBeginAlign(block);
+ menustr= BIF_ThemeColorSetsPup(1);
+ uiDefButI(block, MENU,B_ACTCOLSSELECTOR, menustr, 10,85,150,19, &agrp->customCol, -1, 20, 0.0, 0.0, "Index of set of Custom Colors to shade Group's bones with. 0 = Use Default Color Scheme, -1 = Use Custom Color Scheme");
+ MEM_freeN(menustr);
+
+ /* show color-selection/preview */
+ if (agrp->customCol) {
+ /* do color copying/init (to stay up to date) */
+ actionbone_group_copycolors(agrp, 1);
+
+ /* color changing */
+ uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 10, 65, 50, 19, agrp->cs.active, 0, 0, 0, 0, "Color to use for 'top-level' channels");
+ uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 60, 65, 50, 19, agrp->cs.select, 0, 0, 0, 0, "Color to use for '2nd-level' channels");
+ uiDefButC(block, COL, B_ACTCUSTCOLORS, "", 110, 65, 50, 19, agrp->cs.solid, 0, 0, 0, 0, "Color to use for '3rd-level' channels");
+ }
+ uiBlockEndAlign(block);
+
+ /* commands for active group */
+ uiDefBut(block, BUT, B_ACTGRP_SELALL, "Select Grouped", 170,85,150,20, 0, 21, 0, 0, 0, "Select all action-channels belonging to this group (same as doing Ctrl-Shift-LMB)");
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, BUT, B_ACTGRP_ADDTOSELF, "Add to Group", 170,60,150,20, 0, 21, 0, 0, 0, "Add selected action-channels to this group");
+ uiDefBut(block, BUT, B_ACTGRP_UNGROUP, "Un-Group", 170,40,150,20, 0, 21, 0, 0, 0, "Remove selected action-channels from this group (unimplemented)");
+ uiBlockEndAlign(block);
+ }
+ }
+ else {
+ /* Currently, there isn't anything to display for these types ... */
+ }
}
static void action_blockhandlers(ScrArea *sa)
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/editaction.c b/source/blender/src/editaction.c
index f93a1526e3c..4cc0e52ce3f 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -1114,6 +1114,38 @@ void action_groups_ungroup (void)
allqueue(REDRAWACTION, 0);
}
+/* Copy colors from a specified theme's color set to an Action/Bone Group */
+void actionbone_group_copycolors (bActionGroup *grp, short init_new)
+{
+ /* error checking */
+ if (grp == NULL)
+ return;
+
+ /* only do color copying if using a custom color */
+ if (grp->customCol) {
+ if (grp->customCol > 0) {
+ /* copy theme colors on-to group's custom color in case user tries to edit color */
+ bTheme *btheme= U.themes.first;
+ ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
+
+ memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
+ }
+ else if (init_new) {
+ /* init custom colors with a generic multi-color rgb set, if not initialised already (and allowed to do so) */
+ if (grp->cs.solid[0] == 0) {
+ /* define for setting colors in theme below */
+ #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
+
+ SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
+ SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
+ SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
+
+ #undef SETCOL
+ }
+ }
+ }
+}
+
/* This function is used when inserting keyframes for pose-channels. It assigns the
* action-channel with the nominated name to a group with the same name as that of
* the pose-channel with the nominated name.
@@ -1160,34 +1192,9 @@ void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
/* copy name */
sprintf(grp->name, agrp->name);
- /* deal with group-color copying */
- if (agrp->customCol) {
- if (agrp->customCol > 0) {
- /* copy theme colors on-to group's custom color in case user tries to edit color */
- bTheme *btheme= U.themes.first;
- ThemeWireColor *col_set= &btheme->tarm[(agrp->customCol - 1)];
-
- memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
- }
- else {
- /* init custom colors with a generic multi-color rgb set, if not initialised already */
- if (agrp->cs.solid[0] == 0) {
- /* define for setting colors in theme below */
- #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
-
- SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
- SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
- SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
-
- #undef SETCOL
- }
- else {
- /* just copy color set specified */
- memcpy(&grp->cs, &agrp->cs, sizeof(ThemeWireColor));
- }
- }
- }
- grp->customCol= agrp->customCol;
+ /* deal with group-color copying (grp is destination, agrp is source) */
+ memcpy(grp, agrp, sizeof(bActionGroup));
+ actionbone_group_copycolors(grp, 1);
BLI_addtail(&act->groups, grp);
}
@@ -2697,6 +2704,28 @@ int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode)
return flag;
}
+
+/* select only the active action-group's action channels */
+void select_action_group_channels (bAction *act, bActionGroup *agrp)
+{
+ bActionChannel *achan;
+
+ /* error checking */
+ if (ELEM(NULL, act, agrp))
+ return;
+
+ /* deselect all other channels */
+ deselect_actionchannels(act, 0);
+
+ /* only select channels in group */
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ select_channel(act, achan, SELECT_ADD);
+
+ /* messy... set active bone */
+ select_poseelement_by_name(achan->name, 1);
+ }
+}
+
/* ----------------------------------------- */
/* De-selects or inverts the selection of Channels in a given Action
@@ -3672,17 +3701,8 @@ static void mouse_actionchannels (short mval[])
select_action_group(act, agrp, SELECT_INVERT);
}
else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
- bActionChannel *achan;
-
/* select all in group (and deselect everthing else) */
- deselect_actionchannels(act, 0);
-
- for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
- select_channel(act, achan, SELECT_ADD);
-
- /* messy... set active bone */
- select_poseelement_by_name(achan->name, 1);
- }
+ select_action_group_channels(act, agrp);
select_action_group(act, agrp, SELECT_ADD);
}
else {
@@ -4682,11 +4702,13 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case NKEY:
if (G.qual==0) {
- numbuts_action();
-
- /* no panel (yet). current numbuts are not easy to put in panel... */
- //add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
- //scrarea_queue_winredraw(curarea);
+ /* panel will not always show useful info! */
+ if (mval[0] > ACTWIDTH) {
+ add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
+ scrarea_queue_winredraw(curarea);
+ }
+ else
+ numbuts_action();
}
break;
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/editseq.c b/source/blender/src/editseq.c
index b9351f82d1e..f9432f8e69a 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -2135,12 +2135,25 @@ void del_seq(void)
Sequence *seq;
MetaStack *ms;
Editing *ed;
-
- if(okee("Erase selected")==0) return;
+ int nothingSelected = TRUE;
ed= G.scene->ed;
if(ed==0) return;
+ seq=get_last_seq();
+ if (seq && seq->flag & SELECT) { /* avoid a loop since this is likely to be selected */
+ nothingSelected = FALSE;
+ } else {
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ if (seq->flag & SELECT) {
+ nothingSelected = FALSE;
+ break;
+ }
+ }
+ }
+
+ if(nothingSelected || okee("Erase selected")==0) return;
+
/* free imbufs of all dependent strips */
for(seq=ed->seqbasep->first; seq; seq=seq->next)
if(seq->flag & SELECT)
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/editsound.c b/source/blender/src/editsound.c
index 1cb7ec276cb..05eb094a7c2 100644
--- a/source/blender/src/editsound.c
+++ b/source/blender/src/editsound.c
@@ -148,7 +148,7 @@ void winqreadsoundspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
first= 0;
CFRA= cfra;
update_for_newframe();
- force_draw_plus(SPACE_VIEW3D, 1);
+ force_draw_all(0);
}
else PIL_sleep_ms(30);
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/headerbuttons.c b/source/blender/src/headerbuttons.c
index 81ad135f514..1a91ada1562 100644
--- a/source/blender/src/headerbuttons.c
+++ b/source/blender/src/headerbuttons.c
@@ -1628,6 +1628,7 @@ void do_global_buttons(unsigned short event)
allqueue(REDRAWOOPS, 1);
allqueue(REDRAWACTION, 1);
allqueue(REDRAWNLA, 1);
+ allqueue(REDRAWVIEW3D, 1);
/* name scene also in set PUPmenu */
allqueue(REDRAWBUTSALL, 0);
allqueue(REDRAWIMAGE, 0);
diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c
index 83f1221b1fb..e7041e60003 100644
--- a/source/blender/src/interface_draw.c
+++ b/source/blender/src/interface_draw.c
@@ -180,8 +180,12 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon, int blend)
height= ICON_HEIGHT;
if(but->flag & UI_ICON_LEFT) {
- if (but->type==BUT_TOGDUAL && but->drawstr[0]) {
- xs= but->x1-1.0;
+ if (but->type==BUT_TOGDUAL) {
+ if (but->drawstr[0]) {
+ xs= but->x1-1.0;
+ } else {
+ xs= (but->x1+but->x2- height)/2.0;
+ }
}
else if (but->type==BUTM ) {
xs= but->x1+1.0;
diff --git a/source/blender/src/poselib.c b/source/blender/src/poselib.c
index 2d8b0c81175..fb2bfe5b605 100644
--- a/source/blender/src/poselib.c
+++ b/source/blender/src/poselib.c
@@ -756,6 +756,13 @@ static void poselib_keytag_pose (tPoseLib_PreviewData *pld)
*/
static void poselib_preview_get_next (tPoseLib_PreviewData *pld, int step)
{
+ /* check if we no longer have search-string, but don't have any marker */
+ if (pld->marker == NULL) {
+ if ((step) && (pld->searchstr[0] == 0))
+ pld->marker= pld->act->markers.first;
+ }
+
+ /* the following operations assume that there is a starting point and direction */
if ((pld->marker) && (step)) {
/* search-string dictates a special approach */
if (pld->searchstr[0]) {
@@ -1262,9 +1269,14 @@ void poselib_preview_poses (Object *ob, short apply_active)
/* get search-string */
index= pld.search_cursor;
- memcpy(&tempstr[0], &pld.searchstr[0], index);
- tempstr[index]= '|';
- memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index);
+ if (IN_RANGE(index, 0, 64)) {
+ memcpy(&tempstr[0], &pld.searchstr[0], index);
+ tempstr[index]= '|';
+ memcpy(&tempstr[index+1], &pld.searchstr[index], 64-index);
+ }
+ else {
+ strncpy(tempstr, pld.searchstr, 64);
+ }
/* get marker name */
if (pld.marker)
diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c
index 046d14c990d..f47f14a605c 100644
--- a/source/blender/src/resources.c
+++ b/source/blender/src/resources.c
@@ -52,6 +52,7 @@
#include "BIF_interface_icons.h"
#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
#include "blendef.h" // CLAMP
#include "datatoc.h"
@@ -784,6 +785,33 @@ char *BIF_ThemeColorsPup(int spacetype)
return cp;
}
+char *BIF_ThemeColorSetsPup (short inc_custom)
+{
+ DynStr *pupds= BLI_dynstr_new();
+ char *str;
+ char buf[48];
+ int i;
+
+ /* add title first (and the "default" entry) */
+ BLI_dynstr_append(pupds, "Bone Color Set%t|Default Colors%x0|");
+
+ /* loop through set indices, adding them */
+ for (i=1; i<21; i++) {
+ sprintf(buf, "%d - Theme Color Set%%x%d|", i, i);
+ BLI_dynstr_append(pupds, buf);
+ }
+
+ /* add the 'custom' entry */
+ if (inc_custom)
+ BLI_dynstr_append(pupds, "Custom Set %x-1");
+
+ /* convert to normal MEM_malloc'd string */
+ str= BLI_dynstr_get_cstring(pupds);
+ BLI_dynstr_free(pupds);
+
+ return str;
+}
+
void BIF_SetTheme(ScrArea *sa)
{
if(sa==NULL) { // called for safety, when delete themes
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..58420604c83 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;
@@ -4833,9 +4844,9 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if( cfra!=CFRA || first ) {
first= 0;
-
+
CFRA= cfra;
- force_draw(0);
+ force_draw_all(0);
update_for_newframe(); /* for audio scrubbing */
}
else PIL_sleep_ms(30);
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/transform_snap.c b/source/blender/src/transform_snap.c
index d16308f17ae..3c17d0c1da8 100644
--- a/source/blender/src/transform_snap.c
+++ b/source/blender/src/transform_snap.c
@@ -814,7 +814,7 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
{
efa = EM_get_face_for_index(index);
- if (efa && efa->f & SELECT)
+ if (efa && ((efa->v1->f & SELECT) || (efa->v2->f & SELECT) || (efa->v3->f & SELECT) || (efa->v4 && efa->v4->f & SELECT)))
{
test = 0;
}
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/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index 73d2870720a..220d174d464 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -483,9 +483,9 @@ void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
-void KX_BlenderRenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag)
+void KX_BlenderRenderTools::Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
{
- m_filtermanager.EnableFilter(filtermode, pass, text, texture_flag);
+ m_filtermanager.EnableFilter(propNames, gameObj, filtermode, pass, text);
}
void KX_BlenderRenderTools::Render2DFilters(RAS_ICanvas* canvas)
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
index 7748e31156d..8abce1b8c3e 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
@@ -101,7 +101,7 @@ public:
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
- virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag);
+ virtual void Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
virtual void Render2DFilters(RAS_ICanvas* canvas);
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index 5050da3fe7f..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
};
@@ -641,6 +648,9 @@ PyObject* BL_ActionActuator::PySetAction(PyObject* self,
m_blendframe = 0;
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -660,6 +670,9 @@ PyObject* BL_ActionActuator::PySetStart(PyObject* self,
{
m_startframe = start;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -679,6 +692,9 @@ PyObject* BL_ActionActuator::PySetEnd(PyObject* self,
{
m_endframe = end;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -699,6 +715,9 @@ PyObject* BL_ActionActuator::PySetBlendin(PyObject* self,
{
m_blendin = blendin;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -724,6 +743,9 @@ PyObject* BL_ActionActuator::PySetBlendtime(PyObject* self,
if (m_blendframe>m_blendin)
m_blendframe = m_blendin;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -745,6 +767,9 @@ PyObject* BL_ActionActuator::PySetPriority(PyObject* self,
{
m_priority = priority;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -768,6 +793,9 @@ PyObject* BL_ActionActuator::PySetFrame(PyObject* self,
else if (m_localtime>m_endframe)
m_localtime=m_endframe;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -788,6 +816,9 @@ PyObject* BL_ActionActuator::PySetProperty(PyObject* self,
{
m_propname = string;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -807,6 +838,9 @@ PyObject* BL_ActionActuator::PySetFrameProperty(PyObject* self,
{
m_framepropname = string;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -822,6 +856,9 @@ PyObject* BL_ActionActuator::PyGetChannel(PyObject* self,
{
m_propname = string;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -846,7 +883,8 @@ PyObject* BL_ActionActuator::PySetChannel(PyObject* self,
int row,col;
int mode = 0; /* 0 for bone space, 1 for armature/world space */
- PyArg_ParseTuple(args,"sO|i", &string, &pylist, &mode);
+ if (!PyArg_ParseTuple(args,"sO|i", &string, &pylist, &mode))
+ return NULL;
if (pylist->ob_type == &CListValue::Type)
{
@@ -947,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_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp
index 58d46d76e5b..7196b393ed4 100644
--- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp
@@ -604,6 +604,9 @@ PyObject* BL_ShapeActionActuator::PySetAction(PyObject* self,
m_blendframe = 0.f;
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -623,6 +626,9 @@ PyObject* BL_ShapeActionActuator::PySetStart(PyObject* self,
{
m_startframe = start;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -642,6 +648,9 @@ PyObject* BL_ShapeActionActuator::PySetEnd(PyObject* self,
{
m_endframe = end;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -662,6 +671,9 @@ PyObject* BL_ShapeActionActuator::PySetBlendin(PyObject* self,
{
m_blendin = blendin;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -687,6 +699,9 @@ PyObject* BL_ShapeActionActuator::PySetBlendtime(PyObject* self,
if (m_blendframe>m_blendin)
m_blendframe = m_blendin;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -708,6 +723,9 @@ PyObject* BL_ShapeActionActuator::PySetPriority(PyObject* self,
{
m_priority = priority;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -731,6 +749,9 @@ PyObject* BL_ShapeActionActuator::PySetFrame(PyObject* self,
else if (m_localtime>m_endframe)
m_localtime=m_endframe;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
@@ -751,6 +772,9 @@ PyObject* BL_ShapeActionActuator::PySetProperty(PyObject* self,
{
m_propname = string;
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
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 ea26c55a44e..1cc1b2e27a3 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -159,7 +159,7 @@ void BL_ConvertActuators(char* maggiename,
bitLocalFlag.DRot = bool((obact->flag & ACT_DROT_LOCAL)!=0);
bitLocalFlag.LinearVelocity = bool((obact->flag & ACT_LIN_VEL_LOCAL)!=0);
bitLocalFlag.AngularVelocity = bool((obact->flag & ACT_ANG_VEL_LOCAL)!=0);
- bitLocalFlag.ClampVelocity = bool((obact->flag & ACT_CLAMP_VEL)!=0);
+ bitLocalFlag.ServoControl = bool(obact->type == ACT_OBJECT_SERVO);
bitLocalFlag.AddOrSetLinV = bool((obact->flag & ACT_ADD_LIN_VEL)!=0);
@@ -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;
}
@@ -537,7 +539,7 @@ void BL_ConvertActuators(char* maggiename,
// does the 'original' for replication exists, and
// is it in a non-active layer ?
- CValue* originalval = NULL;
+ SCA_IObject* originalval = NULL;
if (editobact->ob && !(editobact->ob->lay & activeLayerBitInfo))
originalval = converter->FindGameObject(editobact->ob);
@@ -619,51 +621,105 @@ void BL_ConvertActuators(char* maggiename,
case ACT_CONSTRAINT:
{
float min = 0.0, max = 0.0;
+ char *prop = NULL;
KX_ConstraintActuator::KX_CONSTRAINTTYPE locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_NODEF;
bConstraintActuator *conact
= (bConstraintActuator*) bact->data;
/* convert settings... degrees in the ui become radians */
/* internally */
- switch (conact->flag) {
- case ACT_CONST_LOCX:
- locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX;
- min = conact->minloc[0];
- max = conact->maxloc[0];
- break;
- case ACT_CONST_LOCY:
- locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY;
- min = conact->minloc[1];
- max = conact->maxloc[1];
- break;
- case ACT_CONST_LOCZ:
- locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ;
- min = conact->minloc[2];
- max = conact->maxloc[2];
- break;
- case ACT_CONST_ROTX:
- locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX;
- min = MT_2_PI * conact->minrot[0] / 360.0;
- max = MT_2_PI * conact->maxrot[0] / 360.0;
- break;
- case ACT_CONST_ROTY:
- locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY;
- min = MT_2_PI * conact->minrot[1] / 360.0;
- max = MT_2_PI * conact->maxrot[1] / 360.0;
- break;
- case ACT_CONST_ROTZ:
- locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ;
- min = MT_2_PI * conact->minrot[2] / 360.0;
- max = MT_2_PI * conact->maxrot[2] / 360.0;
- break;
- default:
- ; /* error */
+ if (conact->type == ACT_CONST_TYPE_ORI) {
+ switch (conact->mode) {
+ case ACT_CONST_DIRPX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIX;
+ break;
+ case ACT_CONST_DIRPY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIY;
+ break;
+ case ACT_CONST_DIRPZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ORIZ;
+ break;
+ }
+ } else if (conact->type == ACT_CONST_TYPE_DIST) {
+ switch (conact->mode) {
+ case ACT_CONST_DIRPX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPX;
+ min = conact->minloc[0];
+ max = conact->maxloc[0];
+ break;
+ case ACT_CONST_DIRPY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPY;
+ min = conact->minloc[1];
+ max = conact->maxloc[1];
+ break;
+ case ACT_CONST_DIRPZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRPZ;
+ min = conact->minloc[2];
+ max = conact->maxloc[2];
+ break;
+ case ACT_CONST_DIRMX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMX;
+ min = conact->minloc[0];
+ max = conact->maxloc[0];
+ break;
+ case ACT_CONST_DIRMY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMY;
+ min = conact->minloc[1];
+ max = conact->maxloc[1];
+ break;
+ case ACT_CONST_DIRMZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_DIRMZ;
+ min = conact->minloc[2];
+ max = conact->maxloc[2];
+ break;
+ }
+ prop = conact->matprop;
+ } else {
+ switch (conact->flag) {
+ case ACT_CONST_LOCX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCX;
+ min = conact->minloc[0];
+ max = conact->maxloc[0];
+ break;
+ case ACT_CONST_LOCY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCY;
+ min = conact->minloc[1];
+ max = conact->maxloc[1];
+ break;
+ case ACT_CONST_LOCZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_LOCZ;
+ min = conact->minloc[2];
+ max = conact->maxloc[2];
+ break;
+ case ACT_CONST_ROTX:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTX;
+ min = MT_2_PI * conact->minrot[0] / 360.0;
+ max = MT_2_PI * conact->maxrot[0] / 360.0;
+ break;
+ case ACT_CONST_ROTY:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTY;
+ min = MT_2_PI * conact->minrot[1] / 360.0;
+ max = MT_2_PI * conact->maxrot[1] / 360.0;
+ break;
+ case ACT_CONST_ROTZ:
+ locrot = KX_ConstraintActuator::KX_ACT_CONSTRAINT_ROTZ;
+ min = MT_2_PI * conact->minrot[2] / 360.0;
+ max = MT_2_PI * conact->maxrot[2] / 360.0;
+ break;
+ default:
+ ; /* error */
+ }
}
KX_ConstraintActuator *tmpconact
= new KX_ConstraintActuator(gameobj,
- conact->damp,
- min,
- max,
- locrot);
+ conact->damp,
+ conact->rotdamp,
+ min,
+ max,
+ conact->maxrot,
+ locrot,
+ conact->time,
+ conact->flag,
+ prop);
baseact = tmpconact;
break;
}
@@ -944,7 +1000,7 @@ void BL_ConvertActuators(char* maggiename,
}
tmp = new SCA_2DFilterActuator(gameobj, filtermode, _2dfilter->flag,
- _2dfilter->float_arg,_2dfilter->int_arg,_2dfilter->texture_flag,ketsjiEngine->GetRasterizer(),rendertools);
+ _2dfilter->float_arg,_2dfilter->int_arg,ketsjiEngine->GetRasterizer(),rendertools);
if (_2dfilter->text)
{
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index e7e4eeae7d2..7c9df688d45 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -64,6 +64,7 @@ probably misplaced */
#include "KX_MouseFocusSensor.h"
#include "SCA_JoystickSensor.h"
#include "KX_NetworkMessageSensor.h"
+#include "SCA_ActuatorSensor.h"
#include "SCA_PropertySensor.h"
@@ -538,6 +539,19 @@ void BL_ConvertSensors(struct Object* blenderobject,
break;
}
+ case SENS_ACTUATOR:
+ {
+ bActuatorSensor* blenderactsensor = (bActuatorSensor*) sens->data;
+ // we will reuse the property event manager, there is nothing special with this sensor
+ SCA_EventManager* eventmgr
+ = logicmgr->FindEventManager(SCA_EventManager::ACTUATOR_EVENTMGR);
+ if (eventmgr)
+ {
+ STR_String propname=blenderactsensor->name;
+ gamesensor = new SCA_ActuatorSensor(eventmgr,gameobj,propname);
+ }
+ break;
+ }
case SENS_RADAR:
{
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index de89ed9b5c8..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
@@ -99,6 +117,18 @@ static inline void Py_Fatal(char *M) {
return ((class_name*) self)->Py##method_name(self, args, kwds); \
}; \
+#define KX_PYMETHOD_NOARGS(class_name, method_name) \
+ PyObject* Py##method_name(PyObject* self); \
+ static PyObject* sPy##method_name( PyObject* self) { \
+ return ((class_name*) self)->Py##method_name(self); \
+ }; \
+
+#define KX_PYMETHOD_O(class_name, method_name) \
+ PyObject* Py##method_name(PyObject* self, PyObject* value); \
+ static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
+ return ((class_name*) self)->Py##method_name(self, value); \
+ }; \
+
#define KX_PYMETHOD_DOC(class_name, method_name) \
PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
@@ -106,6 +136,21 @@ static inline void Py_Fatal(char *M) {
}; \
static char method_name##_doc[]; \
+#define KX_PYMETHOD_DOC_O(class_name, method_name) \
+ PyObject* Py##method_name(PyObject* self, PyObject* value); \
+ static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \
+ return ((class_name*) self)->Py##method_name(self, value); \
+ }; \
+ static char method_name##_doc[]; \
+
+#define KX_PYMETHOD_DOC_NOARGS(class_name, method_name) \
+ PyObject* Py##method_name(PyObject* self); \
+ static PyObject* sPy##method_name( PyObject* self) { \
+ return ((class_name*) self)->Py##method_name(self); \
+ }; \
+ static char method_name##_doc[]; \
+
+
/* The line above should remain empty */
/**
* Method table macro (with doc)
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index f0195d5df82..48136eb9dc3 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -405,7 +405,20 @@ bool CValue::RemoveProperty(const STR_String & inName)
return false;
}
-
+//
+// Get Property Names
+//
+vector<STR_String> CValue::GetPropertyNames()
+{
+ vector<STR_String> result;
+ if(!m_pNamedPropertyArray) return result;
+ for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
+ !(it == m_pNamedPropertyArray->end());it++)
+ {
+ result.push_back((*it).first);
+ }
+ return result;
+}
//
// Clear all properties
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index 561e5521d60..bcf231cf4f0 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -286,6 +286,7 @@ public:
STR_String GetPropertyText(const STR_String & inName,const STR_String& deftext=""); // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
float GetPropertyNumber(const STR_String& inName,float defnumber);
virtual bool RemoveProperty(const STR_String & inName); // Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
+ virtual vector<STR_String> GetPropertyNames();
virtual void ClearProperties(); // Clear all properties
virtual void SetPropertiesModified(bool inModified); // Set all properties' modified flag to <inModified>
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index 56249bb52ec..96a770a553f 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -7,7 +7,6 @@
#endif
#include <iostream>
-
SCA_2DFilterActuator::~SCA_2DFilterActuator()
{
}
@@ -18,7 +17,6 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
short flag,
float float_arg,
int int_arg,
- short texture_flag,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools,
PyTypeObject* T)
@@ -26,11 +24,15 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
m_type(type),
m_flag(flag),
m_int_arg(int_arg),
- m_texture_flag(texture_flag),
m_float_arg(float_arg),
m_rasterizer(rasterizer),
m_rendertools(rendertools)
{
+ m_gameObj = NULL;
+ if(gameobj){
+ m_propNames = gameobj->GetPropertyNames();
+ m_gameObj = gameobj;
+ }
}
void SCA_2DFilterActuator::SetShaderText(STR_String text)
@@ -52,8 +54,6 @@ CValue* SCA_2DFilterActuator::GetReplica()
bool SCA_2DFilterActuator::Update()
{
- bool result = false;
-
bool bNegativeEvent = IsNegativeEvent();
RemoveAllEvents();
@@ -74,7 +74,7 @@ bool SCA_2DFilterActuator::Update()
}
else if(m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
{
- m_rendertools->Update2DFilter(m_type, m_int_arg, m_shaderText, m_texture_flag);
+ m_rendertools->Update2DFilter(m_propNames, m_gameObj, m_type, m_int_arg, m_shaderText);
}
return true;
}
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
index 451a7b9491a..7ec07cf5b19 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -5,18 +5,17 @@
#include "RAS_IRenderTools.h"
#include "SCA_IActuator.h"
-
class SCA_2DFilterActuator : public SCA_IActuator
{
Py_Header;
private:
-
+ vector<STR_String> m_propNames;
+ void * m_gameObj;
RAS_2DFilterManager::RAS_2DFILTER_MODE m_type;
short m_flag;
float m_float_arg;
int m_int_arg;
- short m_texture_flag;
STR_String m_shaderText;
RAS_IRasterizer* m_rasterizer;
RAS_IRenderTools* m_rendertools;
@@ -29,7 +28,6 @@ public:
short flag,
float float_arg,
int int_arg,
- short texture_flag,
RAS_IRasterizer* rasterizer,
RAS_IRenderTools* rendertools,
PyTypeObject* T=&Type
diff --git a/source/gameengine/GameLogic/SCA_EventManager.cpp b/source/gameengine/GameLogic/SCA_EventManager.cpp
index 1ca88182ddc..0169864a133 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.cpp
+++ b/source/gameengine/GameLogic/SCA_EventManager.cpp
@@ -72,7 +72,9 @@ void SCA_EventManager::EndFrame()
{
}
-
+void SCA_EventManager::UpdateFrame()
+{
+}
int SCA_EventManager::GetType()
{
diff --git a/source/gameengine/GameLogic/SCA_EventManager.h b/source/gameengine/GameLogic/SCA_EventManager.h
index 89731497f6f..9cc1718cd1e 100644
--- a/source/gameengine/GameLogic/SCA_EventManager.h
+++ b/source/gameengine/GameLogic/SCA_EventManager.h
@@ -49,7 +49,8 @@ public:
RAY_EVENTMGR,
RADAR_EVENTMGR,
NETWORK_EVENTMGR,
- JOY_EVENTMGR
+ JOY_EVENTMGR,
+ ACTUATOR_EVENTMGR
};
SCA_EventManager(EVENT_MANAGER_TYPE mgrtype);
@@ -58,6 +59,7 @@ public:
virtual void RemoveSensor(class SCA_ISensor* sensor);
virtual void NextFrame(double curtime, double fixedtime);
virtual void NextFrame();
+ virtual void UpdateFrame();
virtual void EndFrame();
virtual void RegisterSensor(class SCA_ISensor* sensor)=0;
int GetType();
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_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index bbe5a51db3c..8f156cc63e7 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -133,11 +133,11 @@ void SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
}
if (!(actit==m_linkedactuators.end()))
{
- m_linkedactuators.erase(actit);
if (IsActive())
{
(*actit)->DecLink();
}
+ m_linkedactuators.erase(actit);
}
}
@@ -163,11 +163,11 @@ void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor)
}
if (!(sensit==m_linkedsensors.end()))
{
- m_linkedsensors.erase(sensit);
if (IsActive())
{
(*sensit)->DecLink();
}
+ m_linkedsensors.erase(sensit);
}
}
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
index 8423d06dfcd..f6efd485adb 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -242,8 +242,8 @@ PyParentObject SCA_ILogicBrick::Parents[] = {
PyMethodDef SCA_ILogicBrick::Methods[] = {
- {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_VARARGS},
- {"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
+ {"getOwner", (PyCFunction) SCA_ILogicBrick::sPyGetOwner, METH_NOARGS},
+ {"getExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_NOARGS},
{"setExecutePriority", (PyCFunction) SCA_ILogicBrick::sPySetExecutePriority, METH_VARARGS},
{NULL,NULL} //Sentinel
};
@@ -258,9 +258,7 @@ SCA_ILogicBrick::_getattr(const STR_String& attr)
-PyObject* SCA_ILogicBrick::PyGetOwner(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_ILogicBrick::PyGetOwner(PyObject* self)
{
CValue* parent = GetParent();
if (parent)
@@ -294,9 +292,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* self,
-PyObject* SCA_ILogicBrick::PyGetExecutePriority(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_ILogicBrick::PyGetExecutePriority(PyObject* self)
{
return PyInt_FromLong(m_Execute_Ueber_Priority);
}
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
index f359ee0911b..80bc6ae3b86 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.h
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -82,9 +82,9 @@ public:
// python methods
- KX_PYMETHOD(SCA_ILogicBrick,GetOwner);
+ KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetOwner);
KX_PYMETHOD(SCA_ILogicBrick,SetExecutePriority);
- KX_PYMETHOD(SCA_ILogicBrick,GetExecutePriority);
+ KX_PYMETHOD_NOARGS(SCA_ILogicBrick,GetExecutePriority);
enum KX_BOOL_TYPE {
KX_BOOL_NODEF = 0,
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index 826e7bbdf0e..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;
}
@@ -157,15 +157,17 @@ bool SCA_IObject::GetIgnoreActivityCulling()
void SCA_IObject::ReParentLogic()
{
- SCA_SensorList& oldsensors = GetSensors();
-
- int sen = 0;
- SCA_SensorList::iterator its;
- for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
+ SCA_ActuatorList& oldactuators = GetActuators();
+ int act = 0;
+ SCA_ActuatorList::iterator ita;
+ for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
{
- SCA_ISensor* newsensor = (SCA_ISensor*)(*its)->GetReplica();
- newsensor->ReParent(this);
- oldsensors[sen++] = newsensor;
+ 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;
}
SCA_ControllerList& oldcontrollers = GetControllers();
@@ -175,20 +177,24 @@ void SCA_IObject::ReParentLogic()
{
SCA_IController* newcontroller = (SCA_IController*)(*itc)->GetReplica();
newcontroller->ReParent(this);
+ newcontroller->SetActive(false);
oldcontrollers[con++]=newcontroller;
}
- SCA_ActuatorList& oldactuators = GetActuators();
-
- int act = 0;
- SCA_ActuatorList::iterator ita;
- for (ita = oldactuators.begin(); !(ita==oldactuators.end()); ++ita)
+ // convert sensors last so that actuators are already available for Actuator sensor
+ SCA_SensorList& oldsensors = GetSensors();
+ int sen = 0;
+ SCA_SensorList::iterator its;
+ for (its = oldsensors.begin(); !(its==oldsensors.end()); ++its)
{
- SCA_IActuator* newactuator = (SCA_IActuator*) (*ita)->GetReplica();
- newactuator->ReParent(this);
- newactuator->SetActive(false);
- oldactuators[act++] = newactuator;
+ 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;
}
+
// a new object cannot be client of any actuator
m_registeredActuators.clear();
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.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 6cfae9d8919..68341b57435 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -56,6 +56,7 @@ SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
m_suspended = false;
m_invert = false;
m_level = false;
+ m_reset = false;
m_pos_ticks = 0;
m_neg_ticks = 0;
m_pos_pulsemode = false;
@@ -118,7 +119,7 @@ void SCA_ISensor::Resume() {
}
void SCA_ISensor::Init() {
- printf("Sensor %s has no init function, please report this bug to Blender.org\n", m_name);
+ printf("Sensor %s has no init function, please report this bug to Blender.org\n", m_name.Ptr());
}
void SCA_ISensor::DecLink() {
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index 3527b87ebdb..4ce49e71507 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -64,6 +64,9 @@ class SCA_ISensor : public SCA_ILogicBrick
/** detect level instead of edge*/
bool m_level;
+ /** sensor has been reset */
+ bool m_reset;
+
/** Sensor must ignore updates? */
bool m_suspended;
@@ -123,6 +126,8 @@ public:
/** Resume sensing. */
void Resume();
+ void ClrLink()
+ { m_links = 0; }
void IncLink()
{ m_links++; }
void DecLink();
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
index 8668c22f044..3fb439eb25b 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
@@ -70,6 +70,7 @@ std::cout << " hat flag " << m_hatf << std::endl;
void SCA_JoystickSensor::Init()
{
m_istrig=(m_invert)?1:0;
+ m_reset = true;
}
SCA_JoystickSensor::~SCA_JoystickSensor()
@@ -79,9 +80,10 @@ SCA_JoystickSensor::~SCA_JoystickSensor()
CValue* SCA_JoystickSensor::GetReplica()
{
- CValue* replica = new SCA_JoystickSensor(*this);
+ SCA_JoystickSensor* replica = new SCA_JoystickSensor(*this);
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
+ replica->Init();
return replica;
}
@@ -99,7 +101,9 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
{
SCA_Joystick *js = m_pJoystickMgr->GetJoystickDevice();
bool result = false;
+ bool reset = m_reset && m_level;
+ m_reset = false;
switch(m_joymode)
{
case KX_JOYSENSORMODE_AXIS:
@@ -240,6 +244,8 @@ bool SCA_JoystickSensor::Evaluate(CValue* event)
if(!js->IsTrig()){
m_istrig = 0;
}
+ if (reset)
+ result = true;
return result;
}
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index 43ce25f94df..a7a6fa93db4 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -78,14 +78,15 @@ void SCA_KeyboardSensor::Init()
// However, if the target key is pressed when the sensor is reactivated, it
// will not generated an event (see remark in Evaluate()).
m_val = (m_invert)?1:0;
+ m_reset = true;
}
CValue* SCA_KeyboardSensor::GetReplica()
{
- CValue* replica = new SCA_KeyboardSensor(*this);
+ SCA_KeyboardSensor* replica = new SCA_KeyboardSensor(*this);
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
-
+ replica->Init();
return replica;
}
@@ -120,8 +121,8 @@ bool SCA_KeyboardSensor::TriggerOnAllKeys()
bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
{
bool result = false;
+ bool reset = m_reset && m_level;
SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
-
// cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";
/* See if we need to do logging: togPropState exists and is
@@ -134,7 +135,7 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
LogKeystrokes();
}
-
+ m_reset = false;
/* Now see whether events must be bounced. */
if (m_bAllKeys)
@@ -176,8 +177,8 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
{
if (m_val == 0)
{
+ m_val = 1;
if (m_level) {
- m_val = 1;
result = true;
}
}
@@ -229,9 +230,9 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
{
if (m_val == 0)
{
+ m_val = 1;
if (m_level)
{
- m_val = 1;
result = true;
}
}
@@ -240,7 +241,9 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
}
}
}
-
+ if (reset)
+ // force an event
+ result = true;
return result;
}
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index fb1a2c29eb6..f50161cbecb 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -271,6 +271,10 @@ void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
}
m_removedActuators.clear();
+ // About to run actuators, but before update the sensors for those which depends on actuators
+ for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin(); !(ie==m_eventmanagers.end()); ie++)
+ (*ie)->UpdateFrame();
+
for (set<SmartActuatorPtr>::iterator ia = m_activeActuators.begin();!(ia==m_activeActuators.end());ia++)
{
//SCA_IActuator* actua = *ia;
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
index 42d35837489..2298ddb0743 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -84,6 +84,7 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
void SCA_MouseSensor::Init()
{
m_val = (m_invert)?1:0; /* stores the latest attribute */
+ m_reset = true;
}
SCA_MouseSensor::~SCA_MouseSensor()
@@ -95,9 +96,10 @@ SCA_MouseSensor::~SCA_MouseSensor()
CValue* SCA_MouseSensor::GetReplica()
{
- CValue* replica = new SCA_MouseSensor(*this);
+ SCA_MouseSensor* replica = new SCA_MouseSensor(*this);
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
+ replica->Init();
return replica;
}
@@ -132,6 +134,7 @@ SCA_IInputDevice::KX_EnumInputs SCA_MouseSensor::GetHotKey()
bool SCA_MouseSensor::Evaluate(CValue* event)
{
bool result = false;
+ bool reset = m_reset && m_level;
SCA_IInputDevice* mousedev = m_pMouseMgr->GetInputDevice();
@@ -143,7 +146,7 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
/* both MOUSEX and MOUSEY. Treat all of these as key-presses. */
/* So, treat KX_MOUSESENSORMODE_POSITION as */
/* KX_MOUSESENSORMODE_POSITIONX || KX_MOUSESENSORMODE_POSITIONY */
-
+ m_reset = false;
switch (m_mousemode) {
case KX_MOUSESENSORMODE_LEFTBUTTON:
case KX_MOUSESENSORMODE_MIDDLEBUTTON:
@@ -168,9 +171,9 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
{
if (m_val == 0)
{
+ m_val = 1;
if (m_level)
{
- m_val = 1;
result = true;
}
}
@@ -222,6 +225,9 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
; /* error */
}
+ if (reset)
+ // force an event
+ result = true;
return result;
}
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index 655e9060238..c50c011cc63 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -78,6 +78,7 @@ void SCA_PropertySensor::Init()
{
m_recentresult = false;
m_lastresult = m_invert?true:false;
+ m_reset = true;
}
void SCA_PropertySensor::PrecalculateRangeExpression()
@@ -111,6 +112,7 @@ CValue* SCA_PropertySensor::GetReplica()
SCA_PropertySensor* replica = new SCA_PropertySensor(*this);
// m_range_expr must be recalculated on replica!
CValue::AddDataToReplica(replica);
+ replica->Init();
replica->m_range_expr = NULL;
if (replica->m_checktype==KX_PROPSENSOR_INTERVAL)
@@ -153,14 +155,15 @@ SCA_PropertySensor::~SCA_PropertySensor()
bool SCA_PropertySensor::Evaluate(CValue* event)
{
bool result = CheckPropertyCondition();
+ bool reset = m_reset && m_level;
+ m_reset = false;
if (m_lastresult!=result)
{
m_lastresult = result;
return true;
}
-
- return false;
+ return (reset) ? true : false;
}
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index be00117cd21..76386079bdf 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -144,9 +144,7 @@ static char* sPyGetCurrentController__doc__;
#endif
-PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self)
{
m_sCurrentController->AddRef();
return m_sCurrentController;
@@ -159,8 +157,7 @@ static char* sPyAddActiveActuator__doc__;
PyObject* SCA_PythonController::sPyAddActiveActuator(
PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args)
{
PyObject* ob1;
@@ -187,8 +184,7 @@ PyObject* SCA_PythonController::sPyAddActiveActuator(
m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)act,boolval);
boolval->Release();
}
- Py_INCREF(Py_None);
- return Py_None;
+ Py_RETURN_NONE;
}
@@ -222,17 +218,13 @@ PyParentObject SCA_PythonController::Parents[] = {
NULL
};
PyMethodDef SCA_PythonController::Methods[] = {
- {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators,
- METH_VARARGS, SCA_PythonController::GetActuators_doc},
- {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator,
- METH_VARARGS, SCA_PythonController::GetActuator_doc},
- {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors,
- METH_VARARGS, SCA_PythonController::GetSensors_doc},
- {"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor,
- METH_VARARGS, SCA_PythonController::GetSensor_doc},
- {"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_VARARGS},
- {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_VARARGS},
- {"getState", (PyCFunction) SCA_PythonController::sPyGetState, METH_VARARGS},
+ {"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators, METH_NOARGS, SCA_PythonController::GetActuators_doc},
+ {"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator, METH_O, SCA_PythonController::GetActuator_doc},
+ {"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors, METH_NOARGS, SCA_PythonController::GetSensors_doc},
+ {"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor, METH_O, SCA_PythonController::GetSensor_doc},
+ {"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_NOARGS},
+ {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O},
+ {"getState", (PyCFunction) SCA_PythonController::sPyGetState, METH_NOARGS},
{NULL,NULL} //Sentinel
};
@@ -330,14 +322,12 @@ PyObject* SCA_PythonController::_getattr(const STR_String& attr)
-PyObject* SCA_PythonController::PyGetActuators(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::PyGetActuators(PyObject* self)
{
PyObject* resultlist = PyList_New(m_linkedactuators.size());
for (unsigned int index=0;index<m_linkedactuators.size();index++)
{
- PyList_SetItem(resultlist,index,m_linkedactuators[index]->AddRef());
+ PyList_SET_ITEM(resultlist,index,m_linkedactuators[index]->AddRef());
}
return resultlist;
@@ -346,14 +336,12 @@ PyObject* SCA_PythonController::PyGetActuators(PyObject* self,
char SCA_PythonController::GetSensor_doc[] =
"GetSensor (char sensorname) return linked sensor that is named [sensorname]\n";
PyObject*
-SCA_PythonController::PyGetSensor(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+SCA_PythonController::PyGetSensor(PyObject* self, PyObject* value)
{
- char *scriptArg;
-
- if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ char *scriptArg = PyString_AsString(value);
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string (sensor name)");
return NULL;
}
@@ -376,14 +364,12 @@ SCA_PythonController::PyGetSensor(PyObject* self,
char SCA_PythonController::GetActuator_doc[] =
"GetActuator (char sensorname) return linked actuator that is named [actuatorname]\n";
PyObject*
-SCA_PythonController::PyGetActuator(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+SCA_PythonController::PyGetActuator(PyObject* self, PyObject* value)
{
- char *scriptArg;
-
- if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ char *scriptArg = PyString_AsString(value);
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string (actuator name)");
return NULL;
}
@@ -404,34 +390,29 @@ SCA_PythonController::PyGetActuator(PyObject* self,
char SCA_PythonController::GetSensors_doc[] = "getSensors returns a list of all attached sensors";
PyObject*
-SCA_PythonController::PyGetSensors(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+SCA_PythonController::PyGetSensors(PyObject* self)
{
PyObject* resultlist = PyList_New(m_linkedsensors.size());
for (unsigned int index=0;index<m_linkedsensors.size();index++)
{
- PyList_SetItem(resultlist,index,m_linkedsensors[index]->AddRef());
+ PyList_SET_ITEM(resultlist,index,m_linkedsensors[index]->AddRef());
}
return resultlist;
}
/* 1. getScript */
-PyObject* SCA_PythonController::PyGetScript(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::PyGetScript(PyObject* self)
{
return PyString_FromString(m_scriptText);
}
/* 2. setScript */
-PyObject* SCA_PythonController::PySetScript(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::PySetScript(PyObject* self, PyObject* value)
{
- char *scriptArg;
- if (!PyArg_ParseTuple(args, "s", &scriptArg)) {
+ char *scriptArg = PyString_AsString(value);
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string (script name)");
return NULL;
}
@@ -440,13 +421,11 @@ PyObject* SCA_PythonController::PySetScript(PyObject* self,
this->SetScriptText(scriptArg);
- Py_Return;
+ Py_RETURN_NONE;
}
/* 1. getScript */
-PyObject* SCA_PythonController::PyGetState(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* SCA_PythonController::PyGetState(PyObject* self)
{
return PyInt_FromLong(m_statemask);
}
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
index f3af54f402f..39b6c68c359 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.h
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -66,22 +66,19 @@ class SCA_PythonController : public SCA_IController
void SetDictionary(PyObject* pythondictionary);
static char* sPyGetCurrentController__doc__;
- static PyObject* sPyGetCurrentController(PyObject* self,
- PyObject* args,
- PyObject* kwds);
+ static PyObject* sPyGetCurrentController(PyObject* self);
static char* sPyAddActiveActuator__doc__;
static PyObject* sPyAddActiveActuator(PyObject* self,
- PyObject* args,
- PyObject* kwds);
+ PyObject* args);
virtual PyObject* _getattr(const STR_String& attr);
- KX_PYMETHOD_DOC(SCA_PythonController,GetSensors);
- KX_PYMETHOD_DOC(SCA_PythonController,GetSensor);
- KX_PYMETHOD_DOC(SCA_PythonController,GetActuator);
- KX_PYMETHOD_DOC(SCA_PythonController,GetActuators);
- KX_PYMETHOD(SCA_PythonController,SetScript);
- KX_PYMETHOD(SCA_PythonController,GetScript);
- KX_PYMETHOD(SCA_PythonController,GetState);
+ KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetSensors);
+ KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetActuators);
+ KX_PYMETHOD_DOC_O(SCA_PythonController,GetSensor);
+ KX_PYMETHOD_DOC_O(SCA_PythonController,GetActuator);
+ KX_PYMETHOD_O(SCA_PythonController,SetScript);
+ KX_PYMETHOD_NOARGS(SCA_PythonController,GetScript);
+ KX_PYMETHOD_NOARGS(SCA_PythonController,GetState);
};
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index a5017574873..8b828393c67 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -602,9 +602,9 @@ void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
}
}
-void GPC_RenderTools::Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag)
+void GPC_RenderTools::Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)
{
- m_filtermanager.EnableFilter(filtermode, pass, text, texture_flag);
+ m_filtermanager.EnableFilter(propNames, gameObj, filtermode, pass, text);
}
void GPC_RenderTools::Render2DFilters(RAS_ICanvas* canvas)
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
index cb7193f3513..8fae3d2b305 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
@@ -142,7 +142,7 @@ public:
virtual void MotionBlur(RAS_IRasterizer* rasterizer);
- virtual void Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short texture_flag);
+ virtual void Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text);
virtual void Render2DFilters(RAS_ICanvas* canvas);
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/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index 15350db6650..f6f9a29b0e2 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -812,7 +812,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg
mUse = 0;
Py_Return;
}
- Py_Return;
+ return NULL;
}
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
index 3ade810c394..85921ae75ca 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
@@ -158,6 +158,9 @@ PyObject* KX_NetworkMessageActuator::PySetToPropName(
if (PyArg_ParseTuple(args, "s", &ToPropName)) {
m_toPropName = ToPropName;
}
+ else {
+ return NULL;
+ }
Py_Return;
}
@@ -173,7 +176,10 @@ PyObject* KX_NetworkMessageActuator::PySetSubject(
if (PyArg_ParseTuple(args, "s", &Subject)) {
m_subject = Subject;
}
-
+ else {
+ return NULL;
+ }
+
Py_Return;
}
@@ -188,6 +194,9 @@ PyObject* KX_NetworkMessageActuator::PySetBodyType(
if (PyArg_ParseTuple(args, "i", &BodyType)) {
m_bodyType = BodyType;
}
+ else {
+ return NULL;
+ }
Py_Return;
}
@@ -203,6 +212,9 @@ PyObject* KX_NetworkMessageActuator::PySetBody(
if (PyArg_ParseTuple(args, "s", &Body)) {
m_body = Body;
}
+ else {
+ return NULL;
+ }
Py_Return;
}
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
index 027cb2a0ffa..0c66ac1fde3 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -233,6 +233,9 @@ PyObject* KX_NetworkMessageSensor::PySetSubjectFilterText(
{
m_subject = Subject;
}
+ else {
+ return NULL;
+ }
Py_Return;
}
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_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index 27e47d72bbe..3830d422138 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -588,7 +588,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, sphereInsideFrustum,
PyErr_SetString(PyExc_TypeError, "sphereInsideFrustum: Expected arguments: (center, radius)");
- Py_Return;
+ return NULL;
}
KX_PYMETHODDEF_DOC(KX_Camera, boxInsideFrustum,
@@ -766,6 +766,10 @@ KX_PYMETHODDEF_DOC(KX_Camera, enableViewport,
else
EnableViewport(false);
}
+ else {
+ return NULL;
+ }
+
Py_Return;
}
@@ -777,6 +781,8 @@ KX_PYMETHODDEF_DOC(KX_Camera, setViewport,
if (PyArg_ParseTuple(args,"iiii",&left, &bottom, &right, &top))
{
SetViewport(left, bottom, right, top);
+ } else {
+ return NULL;
}
Py_Return;
}
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index bd843d97199..80288a72485 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -35,6 +35,7 @@
#include "MT_Point3.h"
#include "MT_Matrix3x3.h"
#include "KX_GameObject.h"
+#include "KX_RayCast.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -45,35 +46,54 @@
/* ------------------------------------------------------------------------- */
KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj,
- int dampTime,
+ int posDampTime,
+ int rotDampTime,
float minBound,
float maxBound,
+ float refDir[3],
int locrotxyz,
- PyTypeObject* T)
- : SCA_IActuator(gameobj, T)
+ int time,
+ int option,
+ char *property,
+ PyTypeObject* T) :
+ m_refDirection(refDir),
+ m_currentTime(0),
+ SCA_IActuator(gameobj, T)
{
- m_dampTime = dampTime;
+ m_posDampTime = posDampTime;
+ m_rotDampTime = rotDampTime;
m_locrot = locrotxyz;
+ m_option = option;
+ m_activeTime = time;
+ if (property) {
+ strncpy(m_property, property, sizeof(m_property));
+ m_property[sizeof(m_property)-1] = 0;
+ } else {
+ m_property[0] = 0;
+ }
/* The units of bounds are determined by the type of constraint. To */
/* make the constraint application easier and more transparent later on, */
/* I think converting the bounds to the applicable domain makes more */
/* sense. */
switch (m_locrot) {
- case KX_ACT_CONSTRAINT_LOCX:
- case KX_ACT_CONSTRAINT_LOCY:
- case KX_ACT_CONSTRAINT_LOCZ:
+ case KX_ACT_CONSTRAINT_ORIX:
+ case KX_ACT_CONSTRAINT_ORIY:
+ case KX_ACT_CONSTRAINT_ORIZ:
+ {
+ MT_Scalar len = m_refDirection.length();
+ if (MT_fuzzyZero(len)) {
+ // missing a valid direction
+ std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no valid reference direction!" << std::endl;
+ m_locrot = KX_ACT_CONSTRAINT_NODEF;
+ } else {
+ m_refDirection /= len;
+ }
+ }
+ break;
+ default:
m_minimumBound = minBound;
m_maximumBound = maxBound;
break;
- case KX_ACT_CONSTRAINT_ROTX:
- case KX_ACT_CONSTRAINT_ROTY:
- case KX_ACT_CONSTRAINT_ROTZ:
- /* The user interface asks for degrees, we are radian. */
- m_minimumBound = MT_radians(minBound);
- m_maximumBound = MT_radians(maxBound);
- break;
- default:
- ; /* error */
}
} /* End of constructor */
@@ -83,77 +103,239 @@ KX_ConstraintActuator::~KX_ConstraintActuator()
// there's nothing to be done here, really....
} /* end of destructor */
-bool KX_ConstraintActuator::Update(double curtime, bool frame)
+bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data)
{
- bool result = false;
- bool bNegativeEvent = IsNegativeEvent();
- RemoveAllEvents();
-
- if (bNegativeEvent)
- return false; // do nothing on negative events
-
- /* Constraint clamps the values to the specified range, with a sort of */
- /* low-pass filtered time response, if the damp time is unequal to 0. */
-
- /* Having to retrieve location/rotation and setting it afterwards may not */
- /* be efficient enough... Somthing to look at later. */
- KX_GameObject *parent = (KX_GameObject*) GetParent();
- MT_Point3 position = parent->NodeGetWorldPosition();
- MT_Matrix3x3 rotation = parent->NodeGetWorldOrientation();
-// MT_Vector3 eulerrot = rotation.getEuler();
+ KX_GameObject* hitKXObj = client->m_gameobject;
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_LOCX:
- Clamp(position[0], m_minimumBound, m_maximumBound);
- result = true;
- break;
- case KX_ACT_CONSTRAINT_LOCY:
- Clamp(position[1], m_minimumBound, m_maximumBound);
- result = true;
- break;
- case KX_ACT_CONSTRAINT_LOCZ:
- Clamp(position[2], m_minimumBound, m_maximumBound);
- result = true;
- break;
-
-// case KX_ACT_CONSTRAINT_ROTX:
-// /* The angles are Euler angles (I think that's what they are called) */
-// /* but we need to convert from/to the MT_Matrix3x3. */
-// Clamp(eulerrot[0], m_minimumBound, m_maximumBound);
-// break;
-// case KX_ACT_CONSTRAINT_ROTY:
-// Clamp(eulerrot[1], m_minimumBound, m_maximumBound);
-// break;
-// case KX_ACT_CONSTRAINT_ROTZ:
-// Clamp(eulerrot[2], m_minimumBound, m_maximumBound);
-// break;
-// default:
-// ; /* error */
+ if (client->m_type > KX_ClientObjectInfo::ACTOR)
+ {
+ // false hit
+ return false;
}
+ bool bFound = false;
- /* Will be replaced by a filtered clamp. */
-
+ if (m_property[0] == 0)
+ {
+ bFound = true;
+ }
+ else
+ {
+ if (m_option & KX_ACT_CONSTRAINT_MATERIAL)
+ {
+ if (client->m_auxilary_info)
+ {
+ bFound = !strcmp(m_property, ((char*)client->m_auxilary_info));
+ }
+ }
+ else
+ {
+ bFound = hitKXObj->GetProperty(m_property) != NULL;
+ }
+ }
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_LOCX:
- case KX_ACT_CONSTRAINT_LOCY:
- case KX_ACT_CONSTRAINT_LOCZ:
- parent->NodeSetLocalPosition(position);
- break;
+ return bFound;
+}
+bool KX_ConstraintActuator::Update(double curtime, bool frame)
+{
-// case KX_ACT_CONSTRAINT_ROTX:
-// case KX_ACT_CONSTRAINT_ROTY:
-// case KX_ACT_CONSTRAINT_ROTZ:
-// rotation.setEuler(eulerrot);
-// parent->NodeSetLocalOrientation(rotation);
- break;
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
- default:
- ; /* error */
+ if (!bNegativeEvent) {
+ /* Constraint clamps the values to the specified range, with a sort of */
+ /* low-pass filtered time response, if the damp time is unequal to 0. */
+
+ /* Having to retrieve location/rotation and setting it afterwards may not */
+ /* be efficient enough... Somthing to look at later. */
+ KX_GameObject *obj = (KX_GameObject*) GetParent();
+ MT_Point3 position = obj->NodeGetWorldPosition();
+ MT_Point3 newposition;
+ MT_Vector3 direction;
+ MT_Matrix3x3 rotation = obj->NodeGetWorldOrientation();
+ MT_Scalar filter, newdistance;
+ int axis, sign;
+
+ if (m_posDampTime) {
+ filter = m_posDampTime/(1.0+m_posDampTime);
+ }
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_ORIX:
+ case KX_ACT_CONSTRAINT_ORIY:
+ case KX_ACT_CONSTRAINT_ORIZ:
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_ORIX:
+ direction[0] = rotation[0][0];
+ direction[1] = rotation[1][0];
+ direction[2] = rotation[2][0];
+ axis = 0;
+ break;
+ case KX_ACT_CONSTRAINT_ORIY:
+ direction[0] = rotation[0][1];
+ direction[1] = rotation[1][1];
+ direction[2] = rotation[2][1];
+ axis = 1;
+ break;
+ case KX_ACT_CONSTRAINT_ORIZ:
+ direction[0] = rotation[0][2];
+ direction[1] = rotation[1][2];
+ direction[2] = rotation[2][2];
+ axis = 2;
+ break;
+ }
+ // apply damping on the direction
+ if (m_posDampTime) {
+ direction = filter*direction + (1.0-filter)*m_refDirection;
+ }
+ obj->AlignAxisToVect(direction, axis);
+ result = true;
+ goto CHECK_TIME;
+ case KX_ACT_CONSTRAINT_DIRPX:
+ case KX_ACT_CONSTRAINT_DIRPY:
+ case KX_ACT_CONSTRAINT_DIRPZ:
+ case KX_ACT_CONSTRAINT_DIRMX:
+ case KX_ACT_CONSTRAINT_DIRMY:
+ case KX_ACT_CONSTRAINT_DIRMZ:
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_DIRPX:
+ direction[0] = rotation[0][0];
+ direction[1] = rotation[1][0];
+ direction[2] = rotation[2][0];
+ axis = 0; // axis according to KX_GameObject::AlignAxisToVect()
+ sign = 1; // X axis will be anti parrallel to normal
+ break;
+ case KX_ACT_CONSTRAINT_DIRPY:
+ direction[0] = rotation[0][1];
+ direction[1] = rotation[1][1];
+ direction[2] = rotation[2][1];
+ axis = 1;
+ sign = 1;
+ break;
+ case KX_ACT_CONSTRAINT_DIRPZ:
+ direction[0] = rotation[0][2];
+ direction[1] = rotation[1][2];
+ direction[2] = rotation[2][2];
+ axis = 2;
+ sign = 1;
+ break;
+ case KX_ACT_CONSTRAINT_DIRMX:
+ direction[0] = -rotation[0][0];
+ direction[1] = -rotation[1][0];
+ direction[2] = -rotation[2][0];
+ axis = 0;
+ sign = 0;
+ break;
+ case KX_ACT_CONSTRAINT_DIRMY:
+ direction[0] = -rotation[0][1];
+ direction[1] = -rotation[1][1];
+ direction[2] = -rotation[2][1];
+ axis = 1;
+ sign = 0;
+ break;
+ case KX_ACT_CONSTRAINT_DIRMZ:
+ direction[0] = -rotation[0][2];
+ direction[1] = -rotation[1][2];
+ direction[2] = -rotation[2][2];
+ axis = 2;
+ sign = 0;
+ break;
+ }
+ direction.normalize();
+ {
+ MT_Point3 topoint = position + (m_maximumBound) * direction;
+ MT_Point3 resultpoint;
+ MT_Vector3 resultnormal;
+ PHY_IPhysicsEnvironment* pe = obj->GetPhysicsEnvironment();
+ KX_IPhysicsController *spc = obj->GetPhysicsController();
+
+ if (!pe) {
+ std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no physics environment!" << std::endl;
+ goto CHECK_TIME;
+ }
+ if (!spc) {
+ // the object is not physical, we probably want to avoid hitting its own parent
+ KX_GameObject *parent = obj->GetParent();
+ if (parent) {
+ spc = parent->GetPhysicsController();
+ parent->Release();
+ }
+ }
+ result = KX_RayCast::RayTest(spc, pe, position, topoint, resultpoint, resultnormal, KX_RayCast::Callback<KX_ConstraintActuator>(this));
+
+ if (result) {
+ // compute new position & orientation
+ if ((m_option & (KX_ACT_CONSTRAINT_NORMAL|KX_ACT_CONSTRAINT_DISTANCE)) == 0) {
+ // if none option is set, the actuator does nothing but detect ray
+ // (works like a sensor)
+ goto CHECK_TIME;
+ }
+ if (m_option & KX_ACT_CONSTRAINT_NORMAL) {
+ // the new orientation must be so that the axis is parallel to normal
+ if (sign)
+ resultnormal = -resultnormal;
+ // apply damping on the direction
+ if (m_rotDampTime) {
+ MT_Scalar rotFilter = 1.0/(1.0+m_rotDampTime);
+ resultnormal = (-m_rotDampTime*rotFilter)*direction + rotFilter*resultnormal;
+ } else if (m_posDampTime) {
+ resultnormal = -filter*direction + (1.0-filter)*resultnormal;
+ }
+ obj->AlignAxisToVect(resultnormal, axis);
+ direction = -resultnormal;
+ }
+ if (m_option & KX_ACT_CONSTRAINT_DISTANCE) {
+ if (m_posDampTime) {
+ newdistance = filter*(position-resultpoint).length()+(1.0-filter)*m_minimumBound;
+ } else {
+ newdistance = m_minimumBound;
+ }
+ } else {
+ newdistance = (position-resultpoint).length();
+ }
+ newposition = resultpoint-newdistance*direction;
+ } else if (m_option & KX_ACT_CONSTRAINT_PERMANENT) {
+ // no contact but still keep running
+ result = true;
+ goto CHECK_TIME;
+ }
+ }
+ break;
+ case KX_ACT_CONSTRAINT_LOCX:
+ case KX_ACT_CONSTRAINT_LOCY:
+ case KX_ACT_CONSTRAINT_LOCZ:
+ newposition = position;
+ switch (m_locrot) {
+ case KX_ACT_CONSTRAINT_LOCX:
+ Clamp(newposition[0], m_minimumBound, m_maximumBound);
+ break;
+ case KX_ACT_CONSTRAINT_LOCY:
+ Clamp(newposition[1], m_minimumBound, m_maximumBound);
+ break;
+ case KX_ACT_CONSTRAINT_LOCZ:
+ Clamp(newposition[2], m_minimumBound, m_maximumBound);
+ break;
+ }
+ result = true;
+ if (m_posDampTime) {
+ newposition = filter*position + (1.0-filter)*newposition;
+ }
+ break;
+ }
+ if (result) {
+ // set the new position but take into account parent if any
+ obj->NodeSetWorldPosition(newposition);
+ }
+ CHECK_TIME:
+ if (result && m_activeTime > 0 ) {
+ if (++m_currentTime >= m_activeTime)
+ result = false;
+ }
+ }
+ if (!result) {
+ m_currentTime = 0;
}
-
return result;
} /* end of KX_ConstraintActuator::Update(double curtime,double deltatime) */
@@ -214,10 +396,24 @@ PyParentObject KX_ConstraintActuator::Parents[] = {
PyMethodDef KX_ConstraintActuator::Methods[] = {
{"setDamp", (PyCFunction) KX_ConstraintActuator::sPySetDamp, METH_VARARGS, SetDamp_doc},
{"getDamp", (PyCFunction) KX_ConstraintActuator::sPyGetDamp, METH_VARARGS, GetDamp_doc},
+ {"setRotDamp", (PyCFunction) KX_ConstraintActuator::sPySetRotDamp, METH_VARARGS, SetRotDamp_doc},
+ {"getRotDamp", (PyCFunction) KX_ConstraintActuator::sPyGetRotDamp, METH_VARARGS, GetRotDamp_doc},
+ {"setDirection", (PyCFunction) KX_ConstraintActuator::sPySetDirection, METH_VARARGS, SetDirection_doc},
+ {"getDirection", (PyCFunction) KX_ConstraintActuator::sPyGetDirection, METH_VARARGS, GetDirection_doc},
+ {"setOption", (PyCFunction) KX_ConstraintActuator::sPySetOption, METH_VARARGS, SetOption_doc},
+ {"getOption", (PyCFunction) KX_ConstraintActuator::sPyGetOption, METH_VARARGS, GetOption_doc},
+ {"setTime", (PyCFunction) KX_ConstraintActuator::sPySetTime, METH_VARARGS, SetTime_doc},
+ {"getTime", (PyCFunction) KX_ConstraintActuator::sPyGetTime, METH_VARARGS, GetTime_doc},
+ {"setProperty", (PyCFunction) KX_ConstraintActuator::sPySetProperty, METH_VARARGS, SetProperty_doc},
+ {"getProperty", (PyCFunction) KX_ConstraintActuator::sPyGetProperty, METH_VARARGS, GetProperty_doc},
{"setMin", (PyCFunction) KX_ConstraintActuator::sPySetMin, METH_VARARGS, SetMin_doc},
{"getMin", (PyCFunction) KX_ConstraintActuator::sPyGetMin, METH_VARARGS, GetMin_doc},
+ {"setDistance", (PyCFunction) KX_ConstraintActuator::sPySetMin, METH_VARARGS, SetDistance_doc},
+ {"getDistance", (PyCFunction) KX_ConstraintActuator::sPyGetMin, METH_VARARGS, GetDistance_doc},
{"setMax", (PyCFunction) KX_ConstraintActuator::sPySetMax, METH_VARARGS, SetMax_doc},
{"getMax", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_VARARGS, GetMax_doc},
+ {"setRayLength", (PyCFunction) KX_ConstraintActuator::sPySetMax, METH_VARARGS, SetRayLength_doc},
+ {"getRayLength", (PyCFunction) KX_ConstraintActuator::sPyGetMax, METH_VARARGS, GetRayLength_doc},
{"setLimit", (PyCFunction) KX_ConstraintActuator::sPySetLimit, METH_VARARGS, SetLimit_doc},
{"getLimit", (PyCFunction) KX_ConstraintActuator::sPyGetLimit, METH_VARARGS, GetLimit_doc},
{NULL,NULL} //Sentinel
@@ -231,7 +427,7 @@ PyObject* KX_ConstraintActuator::_getattr(const STR_String& attr) {
char KX_ConstraintActuator::SetDamp_doc[] =
"setDamp(duration)\n"
"\t- duration: integer\n"
-"\tSets the time with which the constraint application is delayed.\n"
+"\tSets the time constant of the orientation and distance constraint.\n"
"\tIf the duration is negative, it is set to 0.\n";
PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self,
PyObject* args,
@@ -241,21 +437,192 @@ PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self,
return NULL;
}
- m_dampTime = dampArg;
- if (m_dampTime < 0) m_dampTime = 0;
+ m_posDampTime = dampArg;
+ if (m_posDampTime < 0) m_posDampTime = 0;
Py_Return;
}
/* 3. getDamp */
char KX_ConstraintActuator::GetDamp_doc[] =
-"GetDamp()\n"
-"\tReturns the damping time for application of the constraint.\n";
+"getDamp()\n"
+"\tReturns the damping parameter.\n";
PyObject* KX_ConstraintActuator::PyGetDamp(PyObject* self,
PyObject* args,
PyObject* kwds){
- return PyInt_FromLong(m_dampTime);
+ return PyInt_FromLong(m_posDampTime);
}
+/* 2. setRotDamp */
+char KX_ConstraintActuator::SetRotDamp_doc[] =
+"setRotDamp(duration)\n"
+"\t- duration: integer\n"
+"\tSets the time constant of the orientation constraint.\n"
+"\tIf the duration is negative, it is set to 0.\n";
+PyObject* KX_ConstraintActuator::PySetRotDamp(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int dampArg;
+ if(!PyArg_ParseTuple(args, "i", &dampArg)) {
+ return NULL;
+ }
+
+ m_rotDampTime = dampArg;
+ if (m_rotDampTime < 0) m_rotDampTime = 0;
+
+ Py_Return;
+}
+/* 3. getRotDamp */
+char KX_ConstraintActuator::GetRotDamp_doc[] =
+"getRotDamp()\n"
+"\tReturns the damping time for application of the constraint.\n";
+PyObject* KX_ConstraintActuator::PyGetRotDamp(PyObject* self,
+ PyObject* args,
+ PyObject* kwds){
+ return PyInt_FromLong(m_rotDampTime);
+}
+
+/* 2. setDirection */
+char KX_ConstraintActuator::SetDirection_doc[] =
+"setDirection(vector)\n"
+"\t- vector: 3-tuple\n"
+"\tSets the reference direction in world coordinate for the orientation constraint.\n";
+PyObject* KX_ConstraintActuator::PySetDirection(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ float x, y, z;
+ MT_Scalar len;
+ MT_Vector3 dir;
+
+ if(!PyArg_ParseTuple(args, "(fff)", &x, &y, &z)) {
+ return NULL;
+ }
+ dir[0] = x;
+ dir[1] = y;
+ dir[2] = z;
+ len = dir.length();
+ if (MT_fuzzyZero(len)) {
+ std::cout << "Invalid direction" << std::endl;
+ return NULL;
+ }
+ m_refDirection = dir/len;
+
+ Py_Return;
+}
+/* 3. getDirection */
+char KX_ConstraintActuator::GetDirection_doc[] =
+"getDirection()\n"
+"\tReturns the reference direction of the orientation constraint as a 3-tuple.\n";
+PyObject* KX_ConstraintActuator::PyGetDirection(PyObject* self,
+ PyObject* args,
+ PyObject* kwds){
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_refDirection[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_refDirection[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_refDirection[2]));
+ return retVal;
+}
+
+/* 2. setOption */
+char KX_ConstraintActuator::SetOption_doc[] =
+"setOption(option)\n"
+"\t- option: integer\n"
+"\tSets several options of the distance constraint.\n"
+"\tBinary combination of the following values:\n"
+"\t\t 64 : Activate alignment to surface\n"
+"\t\t128 : Detect material rather than property\n"
+"\t\t256 : No deactivation if ray does not hit target\n"
+"\t\t512 : Activate distance control\n";
+PyObject* KX_ConstraintActuator::PySetOption(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int option;
+ if(!PyArg_ParseTuple(args, "i", &option)) {
+ return NULL;
+ }
+
+ m_option = option;
+
+ Py_Return;
+}
+/* 3. getOption */
+char KX_ConstraintActuator::GetOption_doc[] =
+"getOption()\n"
+"\tReturns the option parameter.\n";
+PyObject* KX_ConstraintActuator::PyGetOption(PyObject* self,
+ PyObject* args,
+ PyObject* kwds){
+ return PyInt_FromLong(m_option);
+}
+
+/* 2. setTime */
+char KX_ConstraintActuator::SetTime_doc[] =
+"setTime(duration)\n"
+"\t- duration: integer\n"
+"\tSets the activation time of the actuator.\n"
+"\tThe actuator disables itself after this many frame.\n"
+"\tIf set to 0 or negative, the actuator is not limited in time.\n";
+PyObject* KX_ConstraintActuator::PySetTime(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int t;
+ if(!PyArg_ParseTuple(args, "i", &t)) {
+ return NULL;
+ }
+
+ if (t < 0)
+ t = 0;
+ m_activeTime = t;
+
+ Py_Return;
+}
+/* 3. getTime */
+char KX_ConstraintActuator::GetTime_doc[] =
+"getTime()\n"
+"\tReturns the time parameter.\n";
+PyObject* KX_ConstraintActuator::PyGetTime(PyObject* self,
+ PyObject* args,
+ PyObject* kwds){
+ return PyInt_FromLong(m_activeTime);
+}
+
+/* 2. setProperty */
+char KX_ConstraintActuator::SetProperty_doc[] =
+"setProperty(property)\n"
+"\t- property: string\n"
+"\tSets the name of the property or material for the ray detection of the distance constraint.\n"
+"\tIf empty, the ray will detect any collisioning object.\n";
+PyObject* KX_ConstraintActuator::PySetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ char *property;
+ if (!PyArg_ParseTuple(args, "s", &property)) {
+ return NULL;
+ }
+ if (property == NULL) {
+ m_property[0] = 0;
+ } else {
+ strncpy(m_property, property, sizeof(m_property));
+ m_property[sizeof(m_property)-1] = 0;
+ }
+
+ Py_Return;
+}
+/* 3. getProperty */
+char KX_ConstraintActuator::GetProperty_doc[] =
+"getProperty()\n"
+"\tReturns the property parameter.\n";
+PyObject* KX_ConstraintActuator::PyGetProperty(PyObject* self,
+ PyObject* args,
+ PyObject* kwds){
+ return PyString_FromString(m_property);
+}
+
+/* 4. setDistance */
+char KX_ConstraintActuator::SetDistance_doc[] =
+"setDistance(distance)\n"
+"\t- distance: float\n"
+"\tSets the target distance in distance constraint\n";
/* 4. setMin */
char KX_ConstraintActuator::SetMin_doc[] =
"setMin(lower_bound)\n"
@@ -271,9 +638,7 @@ PyObject* KX_ConstraintActuator::PySetMin(PyObject* self,
}
switch (m_locrot) {
- case KX_ACT_CONSTRAINT_LOCX:
- case KX_ACT_CONSTRAINT_LOCY:
- case KX_ACT_CONSTRAINT_LOCZ:
+ default:
m_minimumBound = minArg;
break;
case KX_ACT_CONSTRAINT_ROTX:
@@ -281,12 +646,14 @@ PyObject* KX_ConstraintActuator::PySetMin(PyObject* self,
case KX_ACT_CONSTRAINT_ROTZ:
m_minimumBound = MT_radians(minArg);
break;
- default:
- ; /* error */
}
Py_Return;
}
+/* 5. getDistance */
+char KX_ConstraintActuator::GetDistance_doc[] =
+"getDistance()\n"
+"\tReturns the distance parameter \n";
/* 5. getMin */
char KX_ConstraintActuator::GetMin_doc[] =
"getMin()\n"
@@ -298,6 +665,11 @@ PyObject* KX_ConstraintActuator::PyGetMin(PyObject* self,
return PyFloat_FromDouble(m_minimumBound);
}
+/* 6. setRayLength */
+char KX_ConstraintActuator::SetRayLength_doc[] =
+"setRayLength(length)\n"
+"\t- length: float\n"
+"\tSets the maximum ray length of the distance constraint\n";
/* 6. setMax */
char KX_ConstraintActuator::SetMax_doc[] =
"setMax(upper_bound)\n"
@@ -313,9 +685,7 @@ PyObject* KX_ConstraintActuator::PySetMax(PyObject* self,
}
switch (m_locrot) {
- case KX_ACT_CONSTRAINT_LOCX:
- case KX_ACT_CONSTRAINT_LOCY:
- case KX_ACT_CONSTRAINT_LOCZ:
+ default:
m_maximumBound = maxArg;
break;
case KX_ACT_CONSTRAINT_ROTX:
@@ -323,12 +693,14 @@ PyObject* KX_ConstraintActuator::PySetMax(PyObject* self,
case KX_ACT_CONSTRAINT_ROTZ:
m_maximumBound = MT_radians(maxArg);
break;
- default:
- ; /* error */
}
Py_Return;
}
+/* 7. getRayLength */
+char KX_ConstraintActuator::GetRayLength_doc[] =
+"getRayLength()\n"
+"\tReturns the length of the ray\n";
/* 7. getMax */
char KX_ConstraintActuator::GetMax_doc[] =
"getMax()\n"
@@ -345,9 +717,19 @@ PyObject* KX_ConstraintActuator::PyGetMax(PyObject* self,
/* 8. setLimit */
char KX_ConstraintActuator::SetLimit_doc[] =
"setLimit(type)\n"
-"\t- type: KX_CONSTRAINTACT_LOCX, KX_CONSTRAINTACT_LOCY,\n"
-"\t KX_CONSTRAINTACT_LOCZ, KX_CONSTRAINTACT_ROTX,\n"
-"\t KX_CONSTRAINTACT_ROTY, or KX_CONSTRAINTACT_ROTZ.\n"
+"\t- type: integer\n"
+"\t 1 : LocX\n"
+"\t 2 : LocY\n"
+"\t 3 : LocZ\n"
+"\t 7 : Distance along +X axis\n"
+"\t 8 : Distance along +Y axis\n"
+"\t 9 : Distance along +Z axis\n"
+"\t 10 : Distance along -X axis\n"
+"\t 11 : Distance along -Y axis\n"
+"\t 12 : Distance along -Z axis\n"
+"\t 13 : Align X axis\n"
+"\t 14 : Align Y axis\n"
+"\t 15 : Align Z axis\n"
"\tSets the type of constraint.\n";
PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self,
PyObject* args,
@@ -363,7 +745,7 @@ PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self,
}
/* 9. getLimit */
char KX_ConstraintActuator::GetLimit_doc[] =
-"getLimit(type)\n"
+"getLimit()\n"
"\tReturns the type of constraint.\n";
PyObject* KX_ConstraintActuator::PyGetLimit(PyObject* self,
PyObject* args,
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h
index a21a5f30de6..5a1d4d23217 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.h
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h
@@ -34,19 +34,31 @@
#include "SCA_IActuator.h"
#include "MT_Scalar.h"
+#include "MT_Vector3.h"
+#include "KX_ClientObjectInfo.h"
class KX_ConstraintActuator : public SCA_IActuator
{
Py_Header;
protected:
// Damp time (int),
- int m_dampTime;
- // min (float),
+ int m_posDampTime;
+ int m_rotDampTime;
+ // min (float)
float m_minimumBound;
- // max (float),
+ // max (float)
float m_maximumBound;
+ // reference direction
+ MT_Vector3 m_refDirection;
// locrotxyz choice (pick one): only one choice allowed at a time!
int m_locrot;
+ // active time of actuator
+ int m_activeTime;
+ int m_currentTime;
+ // option
+ int m_option;
+ // property to check
+ char m_property[32];
/**
* Clamp <var> to <min>, <max>. Borders are included (in as far as
@@ -56,6 +68,7 @@ protected:
public:
+ // m_locrot
enum KX_CONSTRAINTTYPE {
KX_ACT_CONSTRAINT_NODEF = 0,
KX_ACT_CONSTRAINT_LOCX,
@@ -64,16 +77,37 @@ protected:
KX_ACT_CONSTRAINT_ROTX,
KX_ACT_CONSTRAINT_ROTY,
KX_ACT_CONSTRAINT_ROTZ,
+ KX_ACT_CONSTRAINT_DIRPX,
+ KX_ACT_CONSTRAINT_DIRPY,
+ KX_ACT_CONSTRAINT_DIRPZ,
+ KX_ACT_CONSTRAINT_DIRMX,
+ KX_ACT_CONSTRAINT_DIRMY,
+ KX_ACT_CONSTRAINT_DIRMZ,
+ KX_ACT_CONSTRAINT_ORIX,
+ KX_ACT_CONSTRAINT_ORIY,
+ KX_ACT_CONSTRAINT_ORIZ,
KX_ACT_CONSTRAINT_MAX
};
-
+ // match ACT_CONST_... values from BIF_interface.h
+ enum KX_CONSTRAINTOPT {
+ KX_ACT_CONSTRAINT_NORMAL = 64,
+ KX_ACT_CONSTRAINT_MATERIAL = 128,
+ KX_ACT_CONSTRAINT_PERMANENT = 256,
+ KX_ACT_CONSTRAINT_DISTANCE = 512
+ };
bool IsValidMode(KX_CONSTRAINTTYPE m);
+ bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
KX_ConstraintActuator(SCA_IObject* gameobj,
- int damptime,
+ int posDamptime,
+ int rotDampTime,
float min,
float max,
+ float refDir[3],
int locrot,
+ int time,
+ int option,
+ char *property,
PyTypeObject* T=&Type);
virtual ~KX_ConstraintActuator();
virtual CValue* GetReplica() {
@@ -94,13 +128,26 @@ protected:
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDamp);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetDamp);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetRotDamp);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetRotDamp);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDirection);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetDirection);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetOption);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetOption);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetTime);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetTime);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,SetProperty);
+ KX_PYMETHOD_DOC(KX_ConstraintActuator,GetProperty);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMin);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetMin);
+ static char SetDistance_doc[];
+ static char GetDistance_doc[];
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetMax);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetMax);
+ static char SetRayLength_doc[];
+ static char GetRayLength_doc[];
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetLimit);
KX_PYMETHOD_DOC(KX_ConstraintActuator,GetLimit);
-
};
#endif //__KX_CONSTRAINTACTUATOR
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index b7750e68e8f..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;
@@ -644,11 +661,19 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis)
NodeSetLocalOrientation(orimat);
}
+MT_Scalar KX_GameObject::GetMass()
+{
+ if (m_pPhysicsController1)
+ {
+ return m_pPhysicsController1->GetMass();
+ }
+ return 0.0;
+}
+
MT_Vector3 KX_GameObject::GetLinearVelocity(bool local)
{
MT_Vector3 velocity(0.0,0.0,0.0), locvel;
MT_Matrix3x3 ori;
- int i, j;
if (m_pPhysicsController1)
{
velocity = m_pPhysicsController1->GetLinearVelocity();
@@ -668,7 +693,6 @@ MT_Vector3 KX_GameObject::GetAngularVelocity(bool local)
{
MT_Vector3 velocity(0.0,0.0,0.0), locvel;
MT_Matrix3x3 ori;
- int i, j;
if (m_pPhysicsController1)
{
velocity = m_pPhysicsController1->GetAngularVelocity();
@@ -737,6 +761,31 @@ void KX_GameObject::NodeSetRelativeScale(const MT_Vector3& scale)
GetSGNode()->RelativeScale(scale);
}
+void KX_GameObject::NodeSetWorldPosition(const MT_Point3& trans)
+{
+ SG_Node* parent = m_pSGNode->GetSGParent();
+ if (parent != NULL)
+ {
+ // Make sure the objects have some scale
+ MT_Vector3 scale = parent->GetWorldScaling();
+ if (fabs(scale[0]) < FLT_EPSILON ||
+ fabs(scale[1]) < FLT_EPSILON ||
+ fabs(scale[2]) < FLT_EPSILON)
+ {
+ return;
+ }
+ scale[0] = 1.0/scale[0];
+ scale[1] = 1.0/scale[1];
+ scale[2] = 1.0/scale[2];
+ MT_Matrix3x3 invori = parent->GetWorldOrientation().inverse();
+ MT_Vector3 newpos = invori*(trans-parent->GetWorldPosition())*scale;
+ NodeSetLocalPosition(MT_Point3(newpos[0],newpos[1],newpos[2]));
+ }
+ else
+ {
+ NodeSetLocalPosition(trans);
+ }
+}
void KX_GameObject::NodeUpdateGS(double time,bool bInitiator)
@@ -802,35 +851,37 @@ void KX_GameObject::Suspend(void)
PyMethodDef KX_GameObject::Methods[] = {
- {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},
- {"getVisible",(PyCFunction) KX_GameObject::sPyGetVisible, METH_VARARGS},
- {"setState",(PyCFunction) KX_GameObject::sPySetState, METH_VARARGS},
- {"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_VARARGS},
- {"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
- {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_VARARGS},
- {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_VARARGS},
- {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_VARARGS},
- {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_VARARGS},
+ {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_NOARGS},
+ {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_O},
{"getLinearVelocity", (PyCFunction) KX_GameObject::sPyGetLinearVelocity, METH_VARARGS},
+ {"setLinearVelocity", (PyCFunction) KX_GameObject::sPySetLinearVelocity, METH_VARARGS},
{"getVelocity", (PyCFunction) KX_GameObject::sPyGetVelocity, METH_VARARGS},
- {"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_VARARGS},
- {"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_VARARGS},
+ {"getMass", (PyCFunction) KX_GameObject::sPyGetMass, METH_NOARGS},
+ {"getReactionForce", (PyCFunction) KX_GameObject::sPyGetReactionForce, METH_NOARGS},
+ {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_NOARGS},
+ {"setOrientation", (PyCFunction) KX_GameObject::sPySetOrientation, METH_O},
+ {"getVisible",(PyCFunction) KX_GameObject::sPyGetVisible, METH_NOARGS},
+ {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_O},
+ {"getState",(PyCFunction) KX_GameObject::sPyGetState, METH_NOARGS},
+ {"setState",(PyCFunction) KX_GameObject::sPySetState, METH_O},
+ {"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
+ {"getAxisVect",(PyCFunction) KX_GameObject::sPyGetAxisVect, METH_O},
+ {"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics,METH_NOARGS},
+ {"restoreDynamics", (PyCFunction)KX_GameObject::sPyRestoreDynamics,METH_NOARGS},
+ {"enableRigidBody", (PyCFunction)KX_GameObject::sPyEnableRigidBody,METH_NOARGS},
+ {"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_NOARGS},
{"applyImpulse", (PyCFunction) KX_GameObject::sPyApplyImpulse, METH_VARARGS},
- {"setCollisionMargin", (PyCFunction) KX_GameObject::sPySetCollisionMargin, METH_VARARGS},
- {"suspendDynamics", (PyCFunction)KX_GameObject::sPySuspendDynamics,METH_VARARGS},
- {"restoreDynamics", (PyCFunction)KX_GameObject::sPyRestoreDynamics,METH_VARARGS},
- {"enableRigidBody", (PyCFunction)KX_GameObject::sPyEnableRigidBody,METH_VARARGS},
- {"disableRigidBody", (PyCFunction)KX_GameObject::sPyDisableRigidBody,METH_VARARGS},
- {"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_VARARGS},
- {"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_VARARGS},
- {"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_VARARGS},
+ {"setCollisionMargin", (PyCFunction) KX_GameObject::sPySetCollisionMargin, METH_O},
+ {"getParent", (PyCFunction)KX_GameObject::sPyGetParent,METH_NOARGS},
+ {"setParent", (PyCFunction)KX_GameObject::sPySetParent,METH_O},
+ {"removeParent", (PyCFunction)KX_GameObject::sPyRemoveParent,METH_NOARGS},
{"getMesh", (PyCFunction)KX_GameObject::sPyGetMesh,METH_VARARGS},
- {"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_VARARGS},
- {"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_VARARGS},
- {"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_VARARGS},
- KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
+ {"getPhysicsId", (PyCFunction)KX_GameObject::sPyGetPhysicsId,METH_NOARGS},
+ {"getPropertyNames", (PyCFunction)KX_GameObject::sPyGetPropertyNames,METH_NOARGS},
+ {"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_NOARGS},
KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
KX_PYMETHODTABLE(KX_GameObject, rayCast),
+ KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
{NULL,NULL} //Sentinel
};
@@ -852,18 +903,7 @@ bool KX_GameObject::ConvertPythonVectorArgs(PyObject* args,
}
*/
-
-PyObject* KX_GameObject::sPySetPosition(PyObject* self,
- PyObject* args,
- PyObject* kwds)
-{
- return ((KX_GameObject*) self)->PySetPosition(self, args, kwds);
-}
-
-
-PyObject* KX_GameObject::PyEndObject(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyEndObject(PyObject* self)
{
KX_Scene *scene = PHY_GetActiveScene();
@@ -874,9 +914,7 @@ PyObject* KX_GameObject::PyEndObject(PyObject* self,
}
-PyObject* KX_GameObject::PyGetPosition(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetPosition(PyObject* self)
{
return PyObjectFrom(NodeGetWorldPosition());
}
@@ -930,7 +968,7 @@ PyObject* KX_GameObject::_getattr(const STR_String& attr)
parent->AddRef();
return parent;
}
- Py_Return;
+ Py_RETURN_NONE;
}
if (attr == "visible")
@@ -981,7 +1019,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr
{
MT_Scalar val = PyFloat_AsDouble(value);
if (attr == "timeOffset") {
- if (m_pSGNode->GetSGParent()->IsSlowParent()) {
+ if (m_pSGNode->GetSGParent() && m_pSGNode->GetSGParent()->IsSlowParent()) {
static_cast<KX_SlowParentRelation *>(m_pSGNode->GetSGParent()->GetParentRelation())->SetTimeOffset(val);
return 0;
} else {
@@ -1091,64 +1129,68 @@ PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self,
}
}
-
-
-PyObject* KX_GameObject::PySetVisible(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PySetLinearVelocity(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
{
- int visible = 1;
+ int local = 0;
+ PyObject* pyvect;
- if (PyArg_ParseTuple(args,"i",&visible))
- {
- MarkVisible(visible!=0);
- m_bVisible = (visible!=0);
+ if (PyArg_ParseTuple(args,"O|i",&pyvect,&local)) {
+ MT_Vector3 velocity;
+ if (PyVecTo(pyvect, velocity)) {
+ setLinearVelocity(velocity, (local!=0));
+ Py_RETURN_NONE;
+ }
}
- else
- {
- return NULL;
+ return NULL;
+}
+
+PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* value)
+{
+ int visible = PyInt_AsLong(value);
+
+ if (visible==-1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "expected 0 or 1");
+ return NULL;
}
- Py_Return;
+
+ MarkVisible(visible!=0);
+ m_bVisible = (visible!=0);
+ Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyGetVisible(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetVisible(PyObject* self)
{
return PyInt_FromLong(m_bVisible);
}
-PyObject* KX_GameObject::PyGetState(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetState(PyObject* self)
{
int state = 0;
state |= GetState();
return PyInt_FromLong(state);
}
-PyObject* KX_GameObject::PySetState(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PySetState(PyObject* self, PyObject* value)
{
- int state_i;
+ int state_i = PyInt_AsLong(value);
unsigned int state = 0;
- if (PyArg_ParseTuple(args,"i",&state_i))
- {
- state |= state_i;
- if ((state & ((1<<30)-1)) == 0) {
- PyErr_SetString(PyExc_AttributeError, "The state bitfield was not between 0 and 30 (1<<0 and 1<<29)");
- return NULL;
- }
- SetState(state);
+ if (state_i == -1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "expected an int bit field");
+ return NULL;
}
- else
- {
- return NULL;
+
+ state |= state_i;
+ if ((state & ((1<<30)-1)) == 0) {
+ PyErr_SetString(PyExc_AttributeError, "The state bitfield was not between 0 and 30 (1<<0 and 1<<29)");
+ return NULL;
}
- Py_Return;
+ SetState(state);
+
+ Py_RETURN_NONE;
}
@@ -1168,6 +1210,9 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* self,
if (pypos)
PyVecTo(pypos, point);
}
+ else {
+ return NULL;
+ }
if (m_pPhysicsController1)
{
@@ -1179,26 +1224,14 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* self,
-PyObject* KX_GameObject::PyGetMass(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetMass(PyObject* self)
{
- PyObject* pymass = NULL;
-
- float mass = GetPhysicsController()->GetMass();
- pymass = PyFloat_FromDouble(mass);
-
- if (pymass)
- return pymass;
-
- Py_Return;
+ return PyFloat_FromDouble(GetPhysicsController()->GetMass());
}
-PyObject* KX_GameObject::PyGetReactionForce(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetReactionForce(PyObject* self)
{
// only can get the velocity if we have a physics object connected to us...
return PyObjectFrom(GetPhysicsController()->getReactionForce());
@@ -1206,32 +1239,25 @@ PyObject* KX_GameObject::PyGetReactionForce(PyObject* self,
-PyObject* KX_GameObject::PyEnableRigidBody(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyEnableRigidBody(PyObject* self)
{
-
GetPhysicsController()->setRigidBody(true);
- Py_Return;
+ Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyDisableRigidBody(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyDisableRigidBody(PyObject* self)
{
GetPhysicsController()->setRigidBody(false);
- Py_Return;
+ Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyGetParent(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetParent(PyObject* self)
{
KX_GameObject* parent = this->GetParent();
if (parent)
@@ -1239,33 +1265,31 @@ PyObject* KX_GameObject::PyGetParent(PyObject* self,
parent->AddRef();
return parent;
}
- Py_Return;
+ Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PySetParent(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PySetParent(PyObject* self, PyObject* value)
{
- PyObject* gameobj;
- if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj))
- {
- // The object we want to set as parent
- CValue *m_ob = (CValue*)gameobj;
- KX_GameObject *obj = ((KX_GameObject*)m_ob);
- KX_Scene *scene = PHY_GetActiveScene();
-
- this->SetParent(scene, obj);
+ if (!PyObject_TypeCheck(value, &KX_GameObject::Type)) {
+ PyErr_SetString(PyExc_TypeError, "expected a KX_GameObject type");
+ return NULL;
}
- Py_Return;
+
+ // The object we want to set as parent
+ CValue *m_ob = (CValue*)value;
+ KX_GameObject *obj = ((KX_GameObject*)m_ob);
+ KX_Scene *scene = PHY_GetActiveScene();
+
+ this->SetParent(scene, obj);
+
+ Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyRemoveParent(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyRemoveParent(PyObject* self)
{
KX_Scene *scene = PHY_GetActiveScene();
this->RemoveParent(scene);
- Py_Return;
+ Py_RETURN_NONE;
}
PyObject* KX_GameObject::PyGetMesh(PyObject* self,
@@ -1282,28 +1306,28 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self,
return meshproxy;
}
}
- Py_Return;
+ Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PySetCollisionMargin(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PySetCollisionMargin(PyObject* self, PyObject* value)
{
- float collisionMargin;
- if (PyArg_ParseTuple(args, "f", &collisionMargin))
- {
- if (m_pPhysicsController1)
- {
- m_pPhysicsController1->setMargin(collisionMargin);
- Py_Return;
- }
-
+ float collisionMargin = PyFloat_AsDouble(value);
+
+ if (collisionMargin==-1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError, "expected a float");
+ return NULL;
}
+ if (m_pPhysicsController1)
+ {
+ m_pPhysicsController1->setMargin(collisionMargin);
+ Py_RETURN_NONE;
+ }
+ PyErr_SetString(PyExc_RuntimeError, "This object has no physics controller");
return NULL;
}
@@ -1315,17 +1339,20 @@ PyObject* KX_GameObject::PyApplyImpulse(PyObject* self,
{
PyObject* pyattach;
PyObject* pyimpulse;
+
+ if (!m_pPhysicsController1) {
+ PyErr_SetString(PyExc_RuntimeError, "This object has no physics controller");
+ return NULL;
+ }
+
if (PyArg_ParseTuple(args, "OO", &pyattach, &pyimpulse))
{
MT_Point3 attach;
MT_Vector3 impulse;
- if (m_pPhysicsController1)
+ if (PyVecTo(pyattach, attach) && PyVecTo(pyimpulse, impulse))
{
- if (PyVecTo(pyattach, attach) && PyVecTo(pyimpulse, impulse))
- {
- m_pPhysicsController1->applyImpulse(attach, impulse);
- Py_Return;
- }
+ m_pPhysicsController1->applyImpulse(attach, impulse);
+ Py_RETURN_NONE;
}
}
@@ -1335,59 +1362,46 @@ PyObject* KX_GameObject::PyApplyImpulse(PyObject* self,
-PyObject* KX_GameObject::PySuspendDynamics(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PySuspendDynamics(PyObject* self)
{
SuspendDynamics();
- Py_Return;
+ Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyRestoreDynamics(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyRestoreDynamics(PyObject* self)
{
RestoreDynamics();
- Py_Return;
+ Py_RETURN_NONE;
}
-PyObject* KX_GameObject::PyGetOrientation(PyObject* self,
- PyObject* args,
- PyObject* kwds) //keywords
+PyObject* KX_GameObject::PyGetOrientation(PyObject* self) //keywords
{
return PyObjectFrom(NodeGetWorldOrientation());
}
-PyObject* KX_GameObject::PySetOrientation(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PySetOrientation(PyObject* self, PyObject* value)
{
- PyObject* pylist;
-
- if (PyArg_ParseTuple(args,"O",&pylist))
+ MT_Matrix3x3 matrix;
+ if (PyObject_IsMT_Matrix(value, 3) && PyMatTo(value, matrix))
{
- MT_Matrix3x3 matrix;
- if (PyObject_IsMT_Matrix(pylist, 3) && PyMatTo(pylist, matrix))
- {
- NodeSetLocalOrientation(matrix);
- NodeUpdateGS(0.f,true);
- Py_Return;
- }
-
- MT_Quaternion quat;
- if (PyVecTo(pylist, quat))
- {
- matrix.setRotation(quat);
- NodeSetLocalOrientation(matrix);
- NodeUpdateGS(0.f,true);
- Py_Return;
- }
+ NodeSetLocalOrientation(matrix);
+ NodeUpdateGS(0.f,true);
+ Py_RETURN_NONE;
+ }
+
+ MT_Quaternion quat;
+ if (PyVecTo(value, quat))
+ {
+ matrix.setRotation(quat);
+ NodeSetLocalOrientation(matrix);
+ NodeUpdateGS(0.f,true);
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -1398,37 +1412,44 @@ 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);
- Py_Return;
+ AlignAxisToVect(vect,axis,fac);
+ Py_RETURN_NONE;
}
}
return NULL;
}
-PyObject* KX_GameObject::PySetPosition(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetAxisVect(PyObject* self, PyObject* value)
+{
+ MT_Vector3 vect;
+ if (PyVecTo(value, vect))
+ {
+ return PyObjectFrom(NodeGetWorldOrientation() * vect);
+ }
+ return NULL;
+}
+
+PyObject* KX_GameObject::PySetPosition(PyObject* self, PyObject* value)
{
MT_Point3 pos;
- if (PyVecArgTo(args, pos))
+ if (PyVecTo(value, pos))
{
NodeSetLocalPosition(pos);
NodeUpdateGS(0.f,true);
- Py_Return;
+ Py_RETURN_NONE;
}
-
+
return NULL;
}
-PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self)
{
KX_IPhysicsController* ctrl = GetPhysicsController();
uint_ptr physid=0;
@@ -1439,9 +1460,7 @@ PyObject* KX_GameObject::PyGetPhysicsId(PyObject* self,
return PyInt_FromLong((long)physid);
}
-PyObject* KX_GameObject::PyGetPropertyNames(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_GameObject::PyGetPropertyNames(PyObject* self)
{
return ConvertKeysToPython();
}
@@ -1505,8 +1524,10 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
{
KX_GameObject *other;
PyErr_Clear();
- if (!PyType_IsSubtype(pyarg->ob_type, &KX_GameObject::Type))
+ if (!PyType_IsSubtype(pyarg->ob_type, &KX_GameObject::Type)) {
+ PyErr_SetString(PyExc_TypeError, "the first argument to rayCastTo must be a vector or a KX_GameObject");
return NULL;
+ }
other = static_cast<KX_GameObject*>(pyarg);
toPoint = other->NodeGetWorldPosition();
}
@@ -1540,7 +1561,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
m_pHitObject->AddRef();
return m_pHitObject;
}
- Py_Return;
+ Py_RETURN_NONE;
}
KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
@@ -1566,8 +1587,10 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
if (!PyVecTo(pyto, toPoint))
{
PyErr_Clear();
- if (!PyType_IsSubtype(pyto->ob_type, &KX_GameObject::Type))
+ if (!PyType_IsSubtype(pyto->ob_type, &KX_GameObject::Type)) {
+ PyErr_SetString(PyExc_TypeError, "the first argument to rayCast must be a vector or a KX_GameObject");
return NULL;
+ }
other = static_cast<KX_GameObject*>(pyto);
toPoint = other->NodeGetWorldPosition();
}
@@ -1578,19 +1601,25 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
else if (!PyVecTo(pyfrom, fromPoint))
{
PyErr_Clear();
- if (!PyType_IsSubtype(pyfrom->ob_type, &KX_GameObject::Type))
+ if (!PyType_IsSubtype(pyfrom->ob_type, &KX_GameObject::Type)) {
+ PyErr_SetString(PyExc_TypeError, "the second optional argument to rayCast must be a vector or a KX_GameObject");
return NULL;
+ }
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();
@@ -1623,7 +1652,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
// resultNormal[0], resultNormal[1], resultNormal[2]);
}
return Py_BuildValue("OOO", Py_None, Py_None, Py_None);
- //Py_Return;
+ //Py_RETURN_NONE;
}
/* ---------------------------------------------------------------------
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 89f4cb396d1..ddbf863aa1a 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -258,6 +258,12 @@ public:
bool local=false
);
+ /**
+ * Return the mass of the object
+ */
+ MT_Scalar
+ GetMass();
+
/**
* Return the angular velocity of the game object.
*/
@@ -272,7 +278,8 @@ public:
void
AlignAxisToVect(
const MT_Vector3& vect,
- int axis = 2
+ int axis = 2,
+ float fac = 1.0
);
/**
@@ -332,6 +339,9 @@ public:
void NodeSetRelativeScale( const MT_Vector3& scale );
+ // adapt local position so that world position is set to desired position
+ void NodeSetWorldPosition(const MT_Point3& trans);
+
void
NodeUpdateGS(
double time,
@@ -481,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
@@ -696,46 +714,34 @@ public:
PyObject *value
); // _setattr method
- PyObject*
- PySetPosition(
- PyObject* self,
- PyObject* args,
- PyObject* kwds
- );
-
- static
- PyObject*
- sPySetPosition(
- PyObject* self,
- PyObject* args,
- PyObject* kwds
- );
-
- KX_PYMETHOD(KX_GameObject,GetPosition);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition);
+ KX_PYMETHOD_O(KX_GameObject,SetPosition);
KX_PYMETHOD(KX_GameObject,GetLinearVelocity);
+ KX_PYMETHOD(KX_GameObject,SetLinearVelocity);
KX_PYMETHOD(KX_GameObject,GetVelocity);
- KX_PYMETHOD(KX_GameObject,GetMass);
- KX_PYMETHOD(KX_GameObject,GetReactionForce);
- KX_PYMETHOD(KX_GameObject,GetOrientation);
- KX_PYMETHOD(KX_GameObject,SetOrientation);
- KX_PYMETHOD(KX_GameObject,GetVisible);
- KX_PYMETHOD(KX_GameObject,SetVisible);
- KX_PYMETHOD(KX_GameObject,GetState);
- KX_PYMETHOD(KX_GameObject,SetState);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetMass);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetReactionForce);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetOrientation);
+ KX_PYMETHOD_O(KX_GameObject,SetOrientation);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetVisible);
+ KX_PYMETHOD_O(KX_GameObject,SetVisible);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetState);
+ KX_PYMETHOD_O(KX_GameObject,SetState);
KX_PYMETHOD(KX_GameObject,AlignAxisToVect);
- KX_PYMETHOD(KX_GameObject,SuspendDynamics);
- KX_PYMETHOD(KX_GameObject,RestoreDynamics);
- KX_PYMETHOD(KX_GameObject,EnableRigidBody);
- KX_PYMETHOD(KX_GameObject,DisableRigidBody);
+ KX_PYMETHOD_O(KX_GameObject,GetAxisVect);
+ KX_PYMETHOD_NOARGS(KX_GameObject,SuspendDynamics);
+ KX_PYMETHOD_NOARGS(KX_GameObject,RestoreDynamics);
+ KX_PYMETHOD_NOARGS(KX_GameObject,EnableRigidBody);
+ KX_PYMETHOD_NOARGS(KX_GameObject,DisableRigidBody);
KX_PYMETHOD(KX_GameObject,ApplyImpulse);
- KX_PYMETHOD(KX_GameObject,SetCollisionMargin);
+ KX_PYMETHOD_O(KX_GameObject,SetCollisionMargin);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetParent);
+ KX_PYMETHOD_O(KX_GameObject,SetParent);
+ KX_PYMETHOD_NOARGS(KX_GameObject,RemoveParent);
KX_PYMETHOD(KX_GameObject,GetMesh);
- KX_PYMETHOD(KX_GameObject,GetParent);
- KX_PYMETHOD(KX_GameObject,SetParent);
- KX_PYMETHOD(KX_GameObject,RemoveParent);
- KX_PYMETHOD(KX_GameObject,GetPhysicsId);
- KX_PYMETHOD(KX_GameObject,GetPropertyNames);
- KX_PYMETHOD(KX_GameObject,EndObject);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetPhysicsId);
+ KX_PYMETHOD_NOARGS(KX_GameObject,GetPropertyNames);
+ KX_PYMETHOD_NOARGS(KX_GameObject,EndObject);
KX_PYMETHOD_DOC(KX_GameObject,rayCastTo);
KX_PYMETHOD_DOC(KX_GameObject,rayCast);
KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo);
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_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index 5c8fef1fca0..c7a251751cd 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -157,6 +157,9 @@ PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* self,
{
matname = m_meshobj->GetMaterialName(matid);
}
+ else {
+ return NULL;
+ }
return PyString_FromString(matname.Ptr());
@@ -174,6 +177,9 @@ PyObject* KX_MeshProxy::PyGetTextureName(PyObject* self,
{
matname = m_meshobj->GetTextureName(matid);
}
+ else {
+ return NULL;
+ }
return PyString_FromString(matname.Ptr());
@@ -195,6 +201,9 @@ PyObject* KX_MeshProxy::PyGetVertexArrayLength(PyObject* self,
length = m_meshobj->GetVertexArrayLength(mat);
}
}
+ else {
+ return NULL;
+ }
return PyInt_FromLong(length);
@@ -217,6 +226,9 @@ PyObject* KX_MeshProxy::PyGetVertex(PyObject* self,
vertexob = new KX_VertexProxy(this, vertex);
}
}
+ else {
+ return NULL;
+ }
return vertexob;
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index f89d32bbe66..db0bef8b7e1 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -77,15 +77,17 @@ void KX_MouseFocusSensor::Init()
m_mouse_over_in_previous_frame = (m_invert)?true:false;
m_positive_event = false;
m_hitObject = 0;
+ m_reset = true;
}
bool KX_MouseFocusSensor::Evaluate(CValue* event)
{
bool result = false;
bool obHasFocus = false;
+ bool reset = m_reset && m_level;
// cout << "evaluate focus mouse sensor "<<endl;
-
+ m_reset = false;
if (m_focusmode) {
/* Focus behaviour required. Test mouse-on. The rest is
* equivalent to handling a key. */
@@ -102,6 +104,10 @@ bool KX_MouseFocusSensor::Evaluate(CValue* event)
result = true;
}
}
+ if (reset) {
+ // force an event
+ result = true;
+ }
} else {
/* No focus behaviour required: revert to the basic mode. This
* mode is never used, because the converter never makes this
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index 4086ac53f2a..d69871275b9 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -102,10 +102,7 @@ CValue* KX_NearSensor::GetReplica()
{
KX_NearSensor* replica = new KX_NearSensor(*this);
replica->m_colliders = new CListValue();
- replica->m_bCollision = false;
- replica->m_bTriggered= false;
- replica->m_hitObject = NULL;
- replica->m_bLastTriggered = false;
+ replica->Init();
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
index 03ae14997ab..9ac0b4d4703 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -68,8 +68,15 @@ KX_ObjectActuator(
m_bitLocalFlag (flag),
m_active_combined_velocity (false),
m_linear_damping_active(false),
- m_angular_damping_active(false)
+ m_angular_damping_active(false),
+ m_error_accumulator(0.0,0.0,0.0),
+ m_previous_error(0.0,0.0,0.0)
{
+ if (m_bitLocalFlag.ServoControl)
+ {
+ // in servo motion, the force is local if the target velocity is local
+ m_bitLocalFlag.Force = m_bitLocalFlag.LinearVelocity;
+ }
UpdateFuzzyFlags();
}
@@ -87,105 +94,151 @@ bool KX_ObjectActuator::Update()
// it should reconcile the externally set velocity with it's
// own velocity.
if (m_active_combined_velocity) {
- parent->ResolveCombinedVelocities(
- m_linear_velocity,
- m_angular_velocity,
- (m_bitLocalFlag.LinearVelocity) != 0,
- (m_bitLocalFlag.AngularVelocity) != 0
- );
+ if (parent)
+ parent->ResolveCombinedVelocities(
+ m_linear_velocity,
+ m_angular_velocity,
+ (m_bitLocalFlag.LinearVelocity) != 0,
+ (m_bitLocalFlag.AngularVelocity) != 0
+ );
m_active_combined_velocity = false;
}
m_linear_damping_active = false;
+ m_angular_damping_active = false;
+ m_error_accumulator.setValue(0.0,0.0,0.0);
+ m_previous_error.setValue(0.0,0.0,0.0);
return false;
- } else
- if (parent)
+ } else if (parent)
{
- if (!m_bitLocalFlag.ZeroForce)
+ if (m_bitLocalFlag.ServoControl)
{
- if (m_bitLocalFlag.ClampVelocity && !m_bitLocalFlag.ZeroLinearVelocity)
+ // In this mode, we try to reach a target speed using force
+ // As we don't know the friction, we must implement a generic
+ // servo control to achieve the speed in a configurable
+ // v = current velocity
+ // V = target velocity
+ // e = V-v = speed error
+ // dt = time interval since previous update
+ // I = sum(e(t)*dt)
+ // dv = e(t) - e(t-1)
+ // KP, KD, KI : coefficient
+ // F = KP*e+KI*I+KD*dv
+ MT_Scalar mass = parent->GetMass();
+ if (mass < MT_EPSILON)
+ return false;
+ MT_Vector3 v = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
+ MT_Vector3 e = m_linear_velocity - v;
+ MT_Vector3 dv = e - m_previous_error;
+ MT_Vector3 I = m_error_accumulator + e;
+
+ m_force = m_torque.x()*e+m_torque.y()*I+m_torque.z()*dv;
+ // to automatically adapt the PID coefficient to mass;
+ m_force *= mass;
+ if (m_bitLocalFlag.Torque)
{
- // The user is requesting not to exceed the velocity set in m_linear_velocity
- // The verification is done by projecting the actual speed along the linV direction
- // and comparing it with the linV vector length
- MT_Vector3 linV;
- linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
- if (linV.dot(m_linear_velocity) < m_linear_length2)
- parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
- } else
+ if (m_force[0] > m_dloc[0])
+ {
+ m_force[0] = m_dloc[0];
+ I[0] = m_error_accumulator[0];
+ } else if (m_force[0] < m_drot[0])
+ {
+ m_force[0] = m_drot[0];
+ I[0] = m_error_accumulator[0];
+ }
+ }
+ if (m_bitLocalFlag.DLoc)
{
- parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
+ if (m_force[1] > m_dloc[1])
+ {
+ m_force[1] = m_dloc[1];
+ I[1] = m_error_accumulator[1];
+ } else if (m_force[1] < m_drot[1])
+ {
+ m_force[1] = m_drot[1];
+ I[1] = m_error_accumulator[1];
+ }
}
- }
- if (!m_bitLocalFlag.ZeroTorque)
+ if (m_bitLocalFlag.DRot)
+ {
+ if (m_force[2] > m_dloc[2])
+ {
+ m_force[2] = m_dloc[2];
+ I[2] = m_error_accumulator[2];
+ } else if (m_force[2] < m_drot[2])
+ {
+ m_force[2] = m_drot[2];
+ I[2] = m_error_accumulator[2];
+ }
+ }
+ m_previous_error = e;
+ m_error_accumulator = I;
+ parent->ApplyForce(m_force,(m_bitLocalFlag.LinearVelocity) != 0);
+ } else
{
- if (m_bitLocalFlag.ClampVelocity && !m_bitLocalFlag.ZeroAngularVelocity)
+ if (!m_bitLocalFlag.ZeroForce)
{
- // The user is requesting not to exceed the velocity set in m_angular_velocity
- // The verification is done by projecting the actual speed in the
- MT_Vector3 angV;
- angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity);
- if (angV.dot(m_angular_velocity) < m_angular_velocity.length2())
- parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
- } else
+ parent->ApplyForce(m_force,(m_bitLocalFlag.Force) != 0);
+ }
+ if (!m_bitLocalFlag.ZeroTorque)
{
parent->ApplyTorque(m_torque,(m_bitLocalFlag.Torque) != 0);
}
- }
- if (!m_bitLocalFlag.ZeroDLoc)
- {
- parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0);
- }
- if (!m_bitLocalFlag.ZeroDRot)
- {
- parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
- }
- if (!m_bitLocalFlag.ZeroLinearVelocity && !m_bitLocalFlag.ClampVelocity)
- {
- if (m_bitLocalFlag.AddOrSetLinV) {
- parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
- } else {
+ if (!m_bitLocalFlag.ZeroDLoc)
+ {
+ parent->ApplyMovement(m_dloc,(m_bitLocalFlag.DLoc) != 0);
+ }
+ if (!m_bitLocalFlag.ZeroDRot)
+ {
+ parent->ApplyRotation(m_drot,(m_bitLocalFlag.DRot) != 0);
+ }
+ if (!m_bitLocalFlag.ZeroLinearVelocity)
+ {
+ if (m_bitLocalFlag.AddOrSetLinV) {
+ parent->addLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
+ } else {
+ m_active_combined_velocity = true;
+ if (m_damping > 0) {
+ MT_Vector3 linV;
+ if (!m_linear_damping_active) {
+ // delta and the start speed (depends on the existing speed in that direction)
+ linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
+ // keep only the projection along the desired direction
+ m_current_linear_factor = linV.dot(m_linear_velocity)/m_linear_length2;
+ m_linear_damping_active = true;
+ }
+ if (m_current_linear_factor < 1.0)
+ m_current_linear_factor += 1.0/m_damping;
+ if (m_current_linear_factor > 1.0)
+ m_current_linear_factor = 1.0;
+ linV = m_current_linear_factor * m_linear_velocity;
+ parent->setLinearVelocity(linV,(m_bitLocalFlag.LinearVelocity) != 0);
+ } else {
+ parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
+ }
+ }
+ }
+ if (!m_bitLocalFlag.ZeroAngularVelocity)
+ {
m_active_combined_velocity = true;
if (m_damping > 0) {
- MT_Vector3 linV;
- if (!m_linear_damping_active) {
+ MT_Vector3 angV;
+ if (!m_angular_damping_active) {
// delta and the start speed (depends on the existing speed in that direction)
- linV = parent->GetLinearVelocity(m_bitLocalFlag.LinearVelocity);
+ angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity);
// keep only the projection along the desired direction
- m_current_linear_factor = linV.dot(m_linear_velocity)/m_linear_length2;
- m_linear_damping_active = true;
+ m_current_angular_factor = angV.dot(m_angular_velocity)/m_angular_length2;
+ m_angular_damping_active = true;
}
- if (m_current_linear_factor < 1.0)
- m_current_linear_factor += 1.0/m_damping;
- if (m_current_linear_factor > 1.0)
- m_current_linear_factor = 1.0;
- linV = m_current_linear_factor * m_linear_velocity;
- parent->setLinearVelocity(linV,(m_bitLocalFlag.LinearVelocity) != 0);
+ if (m_current_angular_factor < 1.0)
+ m_current_angular_factor += 1.0/m_damping;
+ if (m_current_angular_factor > 1.0)
+ m_current_angular_factor = 1.0;
+ angV = m_current_angular_factor * m_angular_velocity;
+ parent->setAngularVelocity(angV,(m_bitLocalFlag.AngularVelocity) != 0);
} else {
- parent->setLinearVelocity(m_linear_velocity,(m_bitLocalFlag.LinearVelocity) != 0);
- }
- }
- }
- if (!m_bitLocalFlag.ZeroAngularVelocity && !m_bitLocalFlag.ClampVelocity)
- {
- m_active_combined_velocity = true;
- if (m_damping > 0) {
- MT_Vector3 angV;
- if (!m_angular_damping_active) {
- // delta and the start speed (depends on the existing speed in that direction)
- angV = parent->GetAngularVelocity(m_bitLocalFlag.AngularVelocity);
- // keep only the projection along the desired direction
- m_current_angular_factor = angV.dot(m_angular_velocity)/m_angular_length2;
- m_angular_damping_active = true;
+ parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0);
}
- if (m_current_angular_factor < 1.0)
- m_current_angular_factor += 1.0/m_damping;
- if (m_current_angular_factor > 1.0)
- m_current_angular_factor = 1.0;
- angV = m_current_angular_factor * m_angular_velocity;
- parent->setAngularVelocity(angV,(m_bitLocalFlag.AngularVelocity) != 0);
- } else {
- parent->setAngularVelocity(m_angular_velocity,(m_bitLocalFlag.AngularVelocity) != 0);
}
}
@@ -263,8 +316,17 @@ PyMethodDef KX_ObjectActuator::Methods[] = {
{"setLinearVelocity", (PyCFunction) KX_ObjectActuator::sPySetLinearVelocity, METH_VARARGS},
{"getAngularVelocity", (PyCFunction) KX_ObjectActuator::sPyGetAngularVelocity, METH_VARARGS},
{"setAngularVelocity", (PyCFunction) KX_ObjectActuator::sPySetAngularVelocity, METH_VARARGS},
- {"setVelocityDamping", (PyCFunction) KX_ObjectActuator::sPySetVelocityDamping, METH_VARARGS},
- {"getVelocityDamping", (PyCFunction) KX_ObjectActuator::sPyGetVelocityDamping, METH_VARARGS},
+ {"setDamping", (PyCFunction) KX_ObjectActuator::sPySetDamping, METH_VARARGS},
+ {"getDamping", (PyCFunction) KX_ObjectActuator::sPyGetDamping, METH_VARARGS},
+ {"setForceLimitX", (PyCFunction) KX_ObjectActuator::sPySetForceLimitX, METH_VARARGS},
+ {"getForceLimitX", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitX, METH_VARARGS},
+ {"setForceLimitY", (PyCFunction) KX_ObjectActuator::sPySetForceLimitY, METH_VARARGS},
+ {"getForceLimitY", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitY, METH_VARARGS},
+ {"setForceLimitZ", (PyCFunction) KX_ObjectActuator::sPySetForceLimitZ, METH_VARARGS},
+ {"getForceLimitZ", (PyCFunction) KX_ObjectActuator::sPyGetForceLimitZ, METH_VARARGS},
+ {"setPID", (PyCFunction) KX_ObjectActuator::sPyGetPID, METH_VARARGS},
+ {"getPID", (PyCFunction) KX_ObjectActuator::sPySetPID, METH_VARARGS},
+
{NULL,NULL} //Sentinel
@@ -411,7 +473,6 @@ PyObject* KX_ObjectActuator::PyGetLinearVelocity(PyObject* self,
PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_linear_velocity[1]));
PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_linear_velocity[2]));
PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.LinearVelocity));
- PyList_SetItem(retVal, 4, BoolToPyArg(m_bitLocalFlag.ClampVelocity));
return retVal;
}
@@ -422,14 +483,12 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self,
PyObject* kwds) {
float vecArg[3];
int bToggle = 0;
- int bClamp = 0;
- if (!PyArg_ParseTuple(args, "fffi|i", &vecArg[0], &vecArg[1],
- &vecArg[2], &bToggle, &bClamp)) {
+ if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ &vecArg[2], &bToggle)) {
return NULL;
}
m_linear_velocity.setValue(vecArg);
m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle);
- m_bitLocalFlag.ClampVelocity = PyArgToBool(bClamp);
UpdateFuzzyFlags();
Py_Return;
}
@@ -445,7 +504,6 @@ PyObject* KX_ObjectActuator::PyGetAngularVelocity(PyObject* self,
PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_angular_velocity[1]));
PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_angular_velocity[2]));
PyList_SetItem(retVal, 3, BoolToPyArg(m_bitLocalFlag.AngularVelocity));
- PyList_SetItem(retVal, 4, BoolToPyArg(m_bitLocalFlag.ClampVelocity));
return retVal;
}
@@ -455,22 +513,20 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self,
PyObject* kwds) {
float vecArg[3];
int bToggle = 0;
- int bClamp = 0;
- if (!PyArg_ParseTuple(args, "fffi|i", &vecArg[0], &vecArg[1],
- &vecArg[2], &bToggle, &bClamp)) {
+ if (!PyArg_ParseTuple(args, "fffi", &vecArg[0], &vecArg[1],
+ &vecArg[2], &bToggle)) {
return NULL;
}
m_angular_velocity.setValue(vecArg);
m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle);
- m_bitLocalFlag.ClampVelocity = PyArgToBool(bClamp);
UpdateFuzzyFlags();
Py_Return;
}
-/* 13. setVelocityDamping */
-PyObject* KX_ObjectActuator::PySetVelocityDamping(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+/* 13. setDamping */
+PyObject* KX_ObjectActuator::PySetDamping(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
int damping = 0;
if (!PyArg_ParseTuple(args, "i", &damping) || damping < 0 || damping > 1000) {
return NULL;
@@ -480,11 +536,124 @@ PyObject* KX_ObjectActuator::PySetVelocityDamping(PyObject* self,
}
/* 13. getVelocityDamping */
-PyObject* KX_ObjectActuator::PyGetVelocityDamping(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_ObjectActuator::PyGetDamping(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
return Py_BuildValue("i",m_damping);
}
+/* 6. getForceLimitX */
+PyObject* KX_ObjectActuator::PyGetForceLimitX(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[0]));
+ PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.Torque));
+
+ return retVal;
+}
+/* 7. setForceLimitX */
+PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float vecArg[2];
+ int bToggle = 0;
+ if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
+ return NULL;
+ }
+ m_drot[0] = vecArg[0];
+ m_dloc[0] = vecArg[1];
+ m_bitLocalFlag.Torque = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+/* 6. getForceLimitY */
+PyObject* KX_ObjectActuator::PyGetForceLimitY(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[1]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[1]));
+ PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.DLoc));
+
+ return retVal;
+}
+/* 7. setForceLimitY */
+PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float vecArg[2];
+ int bToggle = 0;
+ if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
+ return NULL;
+ }
+ m_drot[1] = vecArg[0];
+ m_dloc[1] = vecArg[1];
+ m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+/* 6. getForceLimitZ */
+PyObject* KX_ObjectActuator::PyGetForceLimitZ(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_drot[2]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_dloc[2]));
+ PyList_SetItem(retVal, 2, BoolToPyArg(m_bitLocalFlag.DRot));
+
+ return retVal;
+}
+/* 7. setForceLimitZ */
+PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float vecArg[2];
+ int bToggle = 0;
+ if(!PyArg_ParseTuple(args, "ffi", &vecArg[0], &vecArg[1], &bToggle)) {
+ return NULL;
+ }
+ m_drot[2] = vecArg[0];
+ m_dloc[2] = vecArg[1];
+ m_bitLocalFlag.DRot = PyArgToBool(bToggle);
+ Py_Return;
+}
+
+/* 4. getPID */
+PyObject* KX_ObjectActuator::PyGetPID(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_torque[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_torque[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_torque[2]));
+
+ return retVal;
+}
+/* 5. setPID */
+PyObject* KX_ObjectActuator::PySetPID(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ float vecArg[3];
+ if (!PyArg_ParseTuple(args, "fff", &vecArg[0], &vecArg[1], &vecArg[2])) {
+ return NULL;
+ }
+ m_torque.setValue(vecArg);
+ Py_Return;
+}
+
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
index ec6dab5cd48..bb74756551f 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -47,7 +47,6 @@ struct KX_LocalFlags {
LinearVelocity(false),
AngularVelocity(false),
AddOrSetLinV(false),
- ClampVelocity(false),
ZeroForce(false),
ZeroDRot(false),
ZeroDLoc(false),
@@ -63,7 +62,7 @@ struct KX_LocalFlags {
unsigned short LinearVelocity : 1;
unsigned short AngularVelocity : 1;
unsigned short AddOrSetLinV : 1;
- unsigned short ClampVelocity : 1;
+ unsigned short ServoControl : 1;
unsigned short ZeroForce : 1;
unsigned short ZeroTorque : 1;
unsigned short ZeroDRot : 1;
@@ -84,9 +83,13 @@ class KX_ObjectActuator : public SCA_IActuator
MT_Vector3 m_angular_velocity;
MT_Scalar m_linear_length2;
MT_Scalar m_angular_length2;
+ // used in damping
MT_Scalar m_current_linear_factor;
MT_Scalar m_current_angular_factor;
short m_damping;
+ // used in servo control
+ MT_Vector3 m_previous_error;
+ MT_Vector3 m_error_accumulator;
KX_LocalFlags m_bitLocalFlag;
// A hack bool -- oh no sorry everyone
@@ -164,8 +167,16 @@ public:
KX_PYMETHOD(KX_ObjectActuator,SetLinearVelocity);
KX_PYMETHOD(KX_ObjectActuator,GetAngularVelocity);
KX_PYMETHOD(KX_ObjectActuator,SetAngularVelocity);
- KX_PYMETHOD(KX_ObjectActuator,SetVelocityDamping);
- KX_PYMETHOD(KX_ObjectActuator,GetVelocityDamping);
+ KX_PYMETHOD(KX_ObjectActuator,SetDamping);
+ KX_PYMETHOD(KX_ObjectActuator,GetDamping);
+ KX_PYMETHOD(KX_ObjectActuator,GetForceLimitX);
+ KX_PYMETHOD(KX_ObjectActuator,SetForceLimitX);
+ KX_PYMETHOD(KX_ObjectActuator,GetForceLimitY);
+ KX_PYMETHOD(KX_ObjectActuator,SetForceLimitY);
+ KX_PYMETHOD(KX_ObjectActuator,GetForceLimitZ);
+ KX_PYMETHOD(KX_ObjectActuator,SetForceLimitZ);
+ KX_PYMETHOD(KX_ObjectActuator,GetPID);
+ KX_PYMETHOD(KX_ObjectActuator,SetPID);
};
#endif //__KX_OBJECTACTUATOR
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_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
index 27cfaefc076..2df4c6a9980 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
@@ -58,6 +58,9 @@ PyObject* KX_PhysicsObjectWrapper::PySetPosition(PyObject* self,
{
m_ctrl->setPosition(x,y,z);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -72,6 +75,9 @@ PyObject* KX_PhysicsObjectWrapper::PySetLinearVelocity(PyObject* self,
{
m_ctrl->SetLinearVelocity(x,y,z,local != 0);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -85,6 +91,9 @@ PyObject* KX_PhysicsObjectWrapper::PySetAngularVelocity(PyObject* self,
{
m_ctrl->SetAngularVelocity(x,y,z,local != 0);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -97,6 +106,9 @@ PyObject* KX_PhysicsObjectWrapper::PySetActive(PyObject* self,
{
m_ctrl->SetActive(active!=0);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index 172882ff18d..c01d6a632a3 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -82,12 +82,15 @@ static PyObject* gPySetGravity(PyObject* self,
PyObject* kwds)
{
float x,y,z;
- int len = PyTuple_Size(args);
- if ((len == 3) && PyArg_ParseTuple(args,"fff",&x,&y,&z))
+ if (PyArg_ParseTuple(args,"fff",&x,&y,&z))
{
if (PHY_GetActiveEnvironment())
PHY_GetActiveEnvironment()->setGravity(x,y,z);
}
+ else {
+ return NULL;
+ }
+
Py_INCREF(Py_None); return Py_None;
}
@@ -105,6 +108,10 @@ static PyObject* gPySetDebugMode(PyObject* self,
}
}
+ else {
+ return NULL;
+ }
+
Py_INCREF(Py_None); return Py_None;
}
@@ -122,6 +129,9 @@ static PyObject* gPySetNumTimeSubSteps(PyObject* self,
PHY_GetActiveEnvironment()->setNumTimeSubSteps(substep);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -138,6 +148,9 @@ static PyObject* gPySetNumIterations(PyObject* self,
PHY_GetActiveEnvironment()->setNumIterations(iter);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -155,6 +168,9 @@ static PyObject* gPySetDeactivationTime(PyObject* self,
PHY_GetActiveEnvironment()->setDeactivationTime(deactive_time);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -171,6 +187,9 @@ static PyObject* gPySetDeactivationLinearTreshold(PyObject* self,
PHY_GetActiveEnvironment()->setDeactivationLinearTreshold( linearDeactivationTreshold);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -187,6 +206,9 @@ static PyObject* gPySetDeactivationAngularTreshold(PyObject* self,
PHY_GetActiveEnvironment()->setDeactivationAngularTreshold( angularDeactivationTreshold);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -202,6 +224,9 @@ static PyObject* gPySetContactBreakingTreshold(PyObject* self,
PHY_GetActiveEnvironment()->setContactBreakingTreshold( contactBreakingTreshold);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -218,6 +243,9 @@ static PyObject* gPySetCcdMode(PyObject* self,
PHY_GetActiveEnvironment()->setCcdMode( ccdMode);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -233,6 +261,9 @@ static PyObject* gPySetSorConstant(PyObject* self,
PHY_GetActiveEnvironment()->setSolverSorConstant( sor);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -248,6 +279,9 @@ static PyObject* gPySetSolverTau(PyObject* self,
PHY_GetActiveEnvironment()->setSolverTau( tau);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -264,6 +298,9 @@ static PyObject* gPySetSolverDamping(PyObject* self,
PHY_GetActiveEnvironment()->setSolverDamping( damping);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -279,6 +316,9 @@ static PyObject* gPySetLinearAirDamping(PyObject* self,
PHY_GetActiveEnvironment()->setLinearAirDamping( damping);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -295,6 +335,9 @@ static PyObject* gPySetUseEpa(PyObject* self,
PHY_GetActiveEnvironment()->setUseEpa(epa);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
static PyObject* gPySetSolverType(PyObject* self,
@@ -309,6 +352,9 @@ static PyObject* gPySetSolverType(PyObject* self,
PHY_GetActiveEnvironment()->setSolverType(solverType);
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -338,6 +384,9 @@ static PyObject* gPyGetVehicleConstraint(PyObject* self,
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -395,6 +444,9 @@ static PyObject* gPyCreateConstraint(PyObject* self,
}
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None); return Py_None;
}
@@ -421,6 +473,9 @@ static PyObject* gPyGetAppliedImpulse(PyObject* self,
appliedImpulse = PHY_GetActiveEnvironment()->getAppliedImpulse(constraintid);
}
}
+ else {
+ return NULL;
+ }
return PyFloat_FromDouble(appliedImpulse);
}
@@ -443,6 +498,10 @@ static PyObject* gPyRemoveConstraint(PyObject* self,
PHY_GetActiveEnvironment()->removeConstraint(constraintid);
}
}
+ else {
+ return NULL;
+ }
+
Py_INCREF(Py_None); return Py_None;
}
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 0831788009d..433e0636833 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -103,9 +103,7 @@ void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,cons
static PyObject* ErrorObject;
STR_String gPyGetRandomFloat_doc="getRandomFloat returns a random floating point value in the range [0..1)";
-static PyObject* gPyGetRandomFloat(PyObject*,
- PyObject*,
- PyObject*)
+static PyObject* gPyGetRandomFloat(PyObject*)
{
return PyFloat_FromDouble(MT_random());
}
@@ -156,9 +154,7 @@ static PyObject* gPyExpandPath(PyObject*,
static bool usedsp = false;
// this gets a pointer to an array filled with floats
-static PyObject* gPyGetSpectrum(PyObject*,
- PyObject* args,
- PyObject*)
+static PyObject* gPyGetSpectrum(PyObject*)
{
SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
@@ -237,7 +233,7 @@ static PyObject* gPySetLogicTicRate(PyObject*,
return NULL;
}
-static PyObject* gPyGetLogicTicRate(PyObject*, PyObject*, PyObject*)
+static PyObject* gPyGetLogicTicRate(PyObject*)
{
return PyFloat_FromDouble(KX_KetsjiEngine::GetTicRate());
}
@@ -273,7 +269,7 @@ static PyObject* gPySetPhysicsDebug(PyObject*,
-static PyObject* gPyGetPhysicsTicRate(PyObject*, PyObject*, PyObject*)
+static PyObject* gPyGetPhysicsTicRate(PyObject*)
{
return PyFloat_FromDouble(PHY_GetActiveEnvironment()->getFixedTimeStep());
}
@@ -281,9 +277,7 @@ static PyObject* gPyGetPhysicsTicRate(PyObject*, PyObject*, PyObject*)
static STR_String gPyGetCurrentScene_doc =
"getCurrentScene()\n"
"Gets a reference to the current scene.\n";
-static PyObject* gPyGetCurrentScene(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+static PyObject* gPyGetCurrentScene(PyObject* self)
{
Py_INCREF(gp_KetsjiScene);
return (PyObject*) gp_KetsjiScene;
@@ -366,19 +360,19 @@ static struct PyMethodDef game_methods[] = {
{"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, gPyExpandPath_doc},
{"getCurrentController",
(PyCFunction) SCA_PythonController::sPyGetCurrentController,
- METH_VARARGS, SCA_PythonController::sPyGetCurrentController__doc__},
+ METH_NOARGS, SCA_PythonController::sPyGetCurrentController__doc__},
{"getCurrentScene", (PyCFunction) gPyGetCurrentScene,
- METH_VARARGS, gPyGetCurrentScene_doc.Ptr()},
+ METH_NOARGS, gPyGetCurrentScene_doc.Ptr()},
{"addActiveActuator",(PyCFunction) SCA_PythonController::sPyAddActiveActuator,
METH_VARARGS, SCA_PythonController::sPyAddActiveActuator__doc__},
{"getRandomFloat",(PyCFunction) gPyGetRandomFloat,
- METH_VARARGS,gPyGetRandomFloat_doc.Ptr()},
+ METH_NOARGS,gPyGetRandomFloat_doc.Ptr()},
{"setGravity",(PyCFunction) gPySetGravity, METH_VARARGS,"set Gravitation"},
- {"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_VARARGS,"get audio spectrum"},
+ {"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_NOARGS,"get audio spectrum"},
{"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS,"stop using the audio dsp (for performance reasons)"},
- {"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_VARARGS, "Gets the logic tic rate"},
+ {"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_NOARGS, "Gets the logic tic rate"},
{"setLogicTicRate", (PyCFunction) gPySetLogicTicRate, METH_VARARGS, "Sets the logic tic rate"},
- {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_VARARGS, "Gets the physics tic rate"},
+ {"getPhysicsTicRate", (PyCFunction) gPyGetPhysicsTicRate, METH_NOARGS, "Gets the physics tic rate"},
{"setPhysicsTicRate", (PyCFunction) gPySetPhysicsTicRate, METH_VARARGS, "Sets the physics tic rate"},
{"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, "Prints GL Extension Info"},
{NULL, (PyCFunction) NULL, 0, NULL }
@@ -425,7 +419,7 @@ static PyObject* gPyEnableVisibility(PyObject*,
}
else
{
- Py_Return;
+ return NULL;
}
Py_Return;
}
@@ -449,6 +443,9 @@ static PyObject* gPyShowMouse(PyObject*,
gp_Canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
}
}
+ else {
+ return NULL;
+ }
Py_Return;
}
@@ -465,6 +462,9 @@ static PyObject* gPySetMousePosition(PyObject*,
if (gp_Canvas)
gp_Canvas->SetMousePosition(x,y);
}
+ else {
+ return NULL;
+ }
Py_Return;
}
@@ -568,6 +568,9 @@ static PyObject* gPySetMistStart(PyObject*,
gp_Rasterizer->SetFogStart(miststart);
}
}
+ else {
+ return NULL;
+ }
Py_Return;
}
@@ -586,6 +589,9 @@ static PyObject* gPySetMistEnd(PyObject*,
gp_Rasterizer->SetFogEnd(mistend);
}
}
+ else {
+ return NULL;
+ }
Py_Return;
}
@@ -623,6 +629,9 @@ static PyObject* gPyMakeScreenshot(PyObject*,
gp_Canvas->MakeScreenShot(filename);
}
}
+ else {
+ return NULL;
+ }
Py_Return;
}
@@ -638,6 +647,9 @@ static PyObject* gPyEnableMotionBlur(PyObject*,
gp_Rasterizer->EnableMotionBlur(motionblurvalue);
}
}
+ else {
+ return NULL;
+ }
Py_Return;
}
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index e847c59bae1..a416c8c9f89 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -72,6 +72,7 @@ void KX_RaySensor::Init()
m_bTriggered = (m_invert)?true:false;
m_rayHit = false;
m_hitObject = NULL;
+ m_reset = true;
}
KX_RaySensor::~KX_RaySensor()
@@ -83,9 +84,10 @@ KX_RaySensor::~KX_RaySensor()
CValue* KX_RaySensor::GetReplica()
{
- CValue* replica = new KX_RaySensor(*this);
+ KX_RaySensor* replica = new KX_RaySensor(*this);
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
+ replica->Init();
return replica;
}
@@ -151,6 +153,7 @@ bool KX_RaySensor::RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_
bool KX_RaySensor::Evaluate(CValue* event)
{
bool result = false;
+ bool reset = m_reset && m_level;
m_rayHit = false;
m_hitObject = NULL;
m_hitPosition = MT_Vector3(0,0,0);
@@ -162,6 +165,7 @@ bool KX_RaySensor::Evaluate(CValue* event)
MT_Matrix3x3 invmat = matje.inverse();
MT_Vector3 todir;
+ m_reset = false;
switch (m_axis)
{
case 1: // X
@@ -263,7 +267,9 @@ bool KX_RaySensor::Evaluate(CValue* event)
}
}
-
+ if (reset)
+ // force an event
+ result = true;
return result;
}
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index 76ce086ab97..e5ee4cbddf1 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -48,7 +48,7 @@
/* ------------------------------------------------------------------------- */
KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
- CValue* original,
+ SCA_IObject *original,
int time,
SCA_IScene* scene,
const MT_Vector3& linvel,
@@ -61,6 +61,9 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
m_linear_velocity(linvel),
m_localFlag(local)
{
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
+
m_lastCreatedObject = NULL;
m_timeProp = time;
}
@@ -69,6 +72,8 @@ KX_SCA_AddObjectActuator::KX_SCA_AddObjectActuator(SCA_IObject *gameobj,
KX_SCA_AddObjectActuator::~KX_SCA_AddObjectActuator()
{
+ if (m_OriginalObject)
+ m_OriginalObject->UnregisterActuator(this);
if (m_lastCreatedObject)
m_lastCreatedObject->Release();
}
@@ -108,12 +113,29 @@ CValue* KX_SCA_AddObjectActuator::GetReplica()
// this will copy properties and so on...
replica->ProcessReplica();
- replica->m_lastCreatedObject=NULL;
CValue::AddDataToReplica(replica);
return replica;
}
+void KX_SCA_AddObjectActuator::ProcessReplica()
+{
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
+ m_lastCreatedObject=NULL;
+ SCA_IActuator::ProcessReplica();
+}
+
+bool KX_SCA_AddObjectActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == m_OriginalObject)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_OriginalObject = NULL;
+ return true;
+ }
+ return false;
+}
/* ------------------------------------------------------------------------- */
@@ -181,7 +203,11 @@ PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self,
PyObject* gameobj;
if (PyArg_ParseTuple(args, "O!", &KX_GameObject::Type, &gameobj))
{
- m_OriginalObject = (CValue*)gameobj;
+ if (m_OriginalObject != NULL)
+ m_OriginalObject->UnregisterActuator(this);
+ m_OriginalObject = (SCA_IObject*)gameobj;
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
Py_Return;
}
PyErr_Clear();
@@ -189,8 +215,11 @@ PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self,
char* objectname;
if (PyArg_ParseTuple(args, "s", &objectname))
{
- m_OriginalObject= (CValue*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));;
-
+ if (m_OriginalObject != NULL)
+ m_OriginalObject->UnregisterActuator(this);
+ m_OriginalObject = (SCA_IObject*)SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(objectname));;
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
Py_Return;
}
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index 2126a646303..42123b94a68 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -53,7 +53,7 @@ class KX_SCA_AddObjectActuator : public SCA_IActuator
int m_timeProp;
/// Original object reference (object to replicate)
- CValue* m_OriginalObject;
+ SCA_IObject* m_OriginalObject;
/// Object will be added to the following scene
SCA_IScene* m_scene;
@@ -75,7 +75,7 @@ public:
KX_SCA_AddObjectActuator(
SCA_IObject *gameobj,
- CValue* original,
+ SCA_IObject *original,
int time,
SCA_IScene* scene,
const MT_Vector3& linvel,
@@ -89,6 +89,12 @@ public:
GetReplica(
) ;
+ virtual void
+ ProcessReplica();
+
+ virtual bool
+ UnlinkObject(SCA_IObject* clientobj);
+
virtual bool
Update();
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index a7e91e27df3..065800379d8 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -48,6 +48,7 @@
#include "SCA_KeyboardManager.h"
#include "SCA_MouseManager.h"
#include "SCA_PropertyEventManager.h"
+#include "SCA_ActuatorEventManager.h"
#include "KX_Camera.h"
#include "SCA_JoystickManager.h"
@@ -143,6 +144,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
SCA_AlwaysEventManager* alwaysmgr = new SCA_AlwaysEventManager(m_logicmgr);
SCA_PropertyEventManager* propmgr = new SCA_PropertyEventManager(m_logicmgr);
+ SCA_ActuatorEventManager* actmgr = new SCA_ActuatorEventManager(m_logicmgr);
SCA_RandomEventManager* rndmgr = new SCA_RandomEventManager(m_logicmgr);
KX_RayEventManager* raymgr = new KX_RayEventManager(m_logicmgr);
@@ -152,6 +154,7 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
m_logicmgr->RegisterEventManager(alwaysmgr);
m_logicmgr->RegisterEventManager(propmgr);
+ m_logicmgr->RegisterEventManager(actmgr);
m_logicmgr->RegisterEventManager(m_keyboardmgr);
m_logicmgr->RegisterEventManager(m_mousemgr);
m_logicmgr->RegisterEventManager(m_timemgr);
@@ -598,6 +601,8 @@ void KX_Scene::ReplicateLogic(KX_GameObject* newobj)
}
}
}
+ // ready to set initial state
+ newobj->ResetState();
}
@@ -883,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,
@@ -894,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;
}
@@ -999,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()))
{
@@ -1028,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())
{
@@ -1063,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();
@@ -1122,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/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 5311f059f03..ce3aa1de2ef 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -61,7 +61,9 @@ void KX_TouchSensor::EndFrame() {
bool KX_TouchSensor::Evaluate(CValue* event)
{
bool result = false;
+ bool reset = m_reset && m_level;
+ m_reset = false;
if (m_bTriggered != m_bLastTriggered)
{
m_bLastTriggered = m_bTriggered;
@@ -69,7 +71,9 @@ bool KX_TouchSensor::Evaluate(CValue* event)
m_hitObject = NULL;
result = true;
}
-
+ if (reset)
+ // force an event
+ result = true;
return result;
}
@@ -103,6 +107,7 @@ void KX_TouchSensor::Init()
m_bTriggered = false;
m_bLastTriggered = (m_invert)?true:false;
m_hitObject = NULL;
+ m_reset = true;
}
KX_TouchSensor::~KX_TouchSensor()
@@ -115,10 +120,7 @@ CValue* KX_TouchSensor::GetReplica()
{
KX_TouchSensor* replica = new KX_TouchSensor(*this);
replica->m_colliders = new CListValue();
- replica->m_bCollision = false;
- replica->m_bTriggered= false;
- replica->m_hitObject = NULL;
- replica->m_bLastTriggered = false;
+ replica->Init();
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
return replica;
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index b9792303565..731a610c2eb 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -224,7 +224,8 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
{
KX_GameObject* curobj = (KX_GameObject*) GetParent();
MT_Vector3 dir = ((KX_GameObject*)m_object)->NodeGetWorldPosition() - curobj->NodeGetWorldPosition();
- dir.normalize();
+ if (dir.length2())
+ dir.normalize();
MT_Vector3 up(0,0,1);
@@ -250,12 +251,12 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
#endif
if (m_allow3D)
{
- up = (up - up.dot(dir) * dir).normalized();
+ up = (up - up.dot(dir) * dir).safe_normalized();
}
else
{
- dir = (dir - up.dot(dir)*up).normalized();
+ dir = (dir - up.dot(dir)*up).safe_normalized();
}
MT_Vector3 left;
@@ -266,8 +267,8 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
case 0: // TRACK X
{
// (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up
- left = dir.normalized();
- dir = (left.cross(up)).normalized();
+ left = dir.safe_normalized();
+ dir = (left.cross(up)).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
@@ -279,7 +280,7 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
case 1: // TRACK Y
{
// (0.0 , 1.0 , 0.0 ) y direction is forward, z (0.0 , 0.0 , 1.0 ) up
- left = (dir.cross(up)).normalized();
+ left = (dir.cross(up)).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
@@ -291,10 +292,10 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
case 2: // track Z
{
- left = up.normalized();
- up = dir.normalized();
+ left = up.safe_normalized();
+ up = dir.safe_normalized();
dir = left;
- left = (dir.cross(up)).normalized();
+ left = (dir.cross(up)).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
@@ -306,8 +307,8 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
case 3: // TRACK -X
{
// (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up
- left = -dir.normalized();
- dir = -(left.cross(up)).normalized();
+ left = -dir.safe_normalized();
+ dir = -(left.cross(up)).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
@@ -319,7 +320,7 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
case 4: // TRACK -Y
{
// (0.0 , -1.0 , 0.0 ) -y direction is forward, z (0.0 , 0.0 , 1.0 ) up
- left = (-dir.cross(up)).normalized();
+ left = (-dir.cross(up)).safe_normalized();
mat.setValue (
left[0], -dir[0],up[0],
left[1], -dir[1],up[1],
@@ -329,10 +330,10 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
}
case 5: // track -Z
{
- left = up.normalized();
- up = -dir.normalized();
+ left = up.safe_normalized();
+ up = -dir.safe_normalized();
dir = left;
- left = (dir.cross(up)).normalized();
+ left = (dir.cross(up)).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
@@ -345,8 +346,8 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
default:
{
// (1.0 , 0.0 , 0.0 ) -x direction is forward, z (0.0 , 0.0 , 1.0 ) up
- left = -dir.normalized();
- dir = -(left.cross(up)).normalized();
+ left = -dir.safe_normalized();
+ dir = -(left.cross(up)).safe_normalized();
mat.setValue (
left[0], dir[0],up[0],
left[1], dir[1],up[1],
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index fba2ecc223b..7e8160a4d67 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -68,6 +68,8 @@ PyObject* KX_VehicleWrapper::PyAddWheel(PyObject* self,
printf("attempt for addWheel: suspensionRestLength%f wheelRadius %f, hasSteering:%d\n",suspensionRestLength,wheelRadius,hasSteering);
m_vehicle->AddWheel(motionState,aPos,aDir,aAxle,suspensionRestLength,wheelRadius,hasSteering);
+ } else {
+ return NULL;
}
Py_INCREF(Py_None);
return Py_None;
@@ -90,8 +92,7 @@ PyObject* KX_VehicleWrapper::PyGetWheelPosition(PyObject* self,
MT_Vector3 pos(position[0],position[1],position[2]);
return PyObjectFrom(pos);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return NULL;
}
PyObject* KX_VehicleWrapper::PyGetWheelRotation(PyObject* self,
@@ -103,8 +104,7 @@ PyObject* KX_VehicleWrapper::PyGetWheelRotation(PyObject* self,
{
return PyFloat_FromDouble(m_vehicle->GetWheelRotation(wheelIndex));
}
- Py_INCREF(Py_None);
- return Py_None;
+ return NULL;
}
PyObject* KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject* self,
@@ -120,8 +120,7 @@ PyObject* KX_VehicleWrapper::PyGetWheelOrientationQuaternion(PyObject* self,
MT_Matrix3x3 ornmat(quatorn);
return PyObjectFrom(ornmat);
}
- Py_INCREF(Py_None);
- return Py_None;
+ return NULL;
}
@@ -155,6 +154,9 @@ PyObject* KX_VehicleWrapper::PyApplyEngineForce(PyObject* self,
force *= -1.f;//someone reverse some conventions inside Bullet (axle winding)
m_vehicle->ApplyEngineForce(force,wheelIndex);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
@@ -170,6 +172,9 @@ PyObject* KX_VehicleWrapper::PySetTyreFriction(PyObject* self,
{
m_vehicle->SetWheelFriction(wheelFriction,wheelIndex);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
@@ -185,6 +190,9 @@ PyObject* KX_VehicleWrapper::PySetSuspensionStiffness(PyObject* self,
{
m_vehicle->SetSuspensionStiffness(suspensionStiffness,wheelIndex);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
@@ -199,6 +207,8 @@ PyObject* KX_VehicleWrapper::PySetSuspensionDamping(PyObject* self,
if (PyArg_ParseTuple(args,"fi",&suspensionDamping,&wheelIndex))
{
m_vehicle->SetSuspensionDamping(suspensionDamping,wheelIndex);
+ } else {
+ return NULL;
}
Py_INCREF(Py_None);
return Py_None;
@@ -214,6 +224,8 @@ PyObject* KX_VehicleWrapper::PySetSuspensionCompression(PyObject* self,
if (PyArg_ParseTuple(args,"fi",&suspensionCompression,&wheelIndex))
{
m_vehicle->SetSuspensionCompression(suspensionCompression,wheelIndex);
+ } else {
+ return NULL;
}
Py_INCREF(Py_None);
return Py_None;
@@ -230,6 +242,9 @@ PyObject* KX_VehicleWrapper::PySetRollInfluence(PyObject* self,
{
m_vehicle->SetRollInfluence(rollInfluence,wheelIndex);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
@@ -246,6 +261,9 @@ PyObject* KX_VehicleWrapper::PyApplyBraking(PyObject* self,
{
m_vehicle->ApplyBraking(braking,wheelIndex);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
@@ -264,6 +282,9 @@ PyObject* KX_VehicleWrapper::PySetSteeringValue(PyObject* self,
{
m_vehicle->SetSteeringValue(steeringValue,wheelIndex);
}
+ else {
+ return NULL;
+ }
Py_INCREF(Py_None);
return Py_None;
}
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/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index ec7496daa75..37c188b7f22 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -90,15 +90,26 @@ class KX_GameObject:
- 1: Y axis
- 2: Z axis (default)
"""
+ def getAxisVect(vect):
+ """
+ Returns the axis vector rotates by the objects worldspace orientation.
+ This is the equivalent if multiplying the vector by the orientation matrix.
+
+ @type vect: 3d vector.
+ @param vect: a vector to align the axis.
+ @rtype: 3d vector.
+ @return: The vector in relation to the objects rotation.
+
+ """
def getOrientation():
"""
Gets the game object's orientation.
- @rtype: 3x3 inverted rotation matrix
+ @rtype: 3x3 rotation matrix
@return: The game object's rotation matrix
@note: When using this matrix with Blender.Mathutils.Matrix() types, it will need to be transposed.
"""
- def getLinearVelocity(local):
+ def getLinearVelocity(local = 0):
"""
Gets the game object's linear velocity.
@@ -106,11 +117,24 @@ class KX_GameObject:
ie no angular velocity component.
@type local: boolean
- @param local: - False: you get the "global" velocity ie: relative to world orientation.
+ @param local: - False: you get the "global" velocity ie: relative to world orientation (default).
- True: you get the "local" velocity ie: relative to object orientation.
@rtype: list [vx, vy, vz]
@return: the object's linear velocity.
"""
+ def setLinearVelocity(velocity, local = 0):
+ """
+ Sets the game object's linear velocity.
+
+ This method sets game object's velocity through it's centre of mass,
+ ie no angular velocity component.
+
+ @type velocity: 3d vector.
+ @param velocity: linear velocity vector.
+ @type local: boolean
+ @param local: - False: you get the "global" velocity ie: relative to world orientation (default).
+ - True: you get the "local" velocity ie: relative to object orientation.
+ """
def getVelocity(point):
"""
Gets the game object's velocity at the specified point.
@@ -158,16 +182,19 @@ class KX_GameObject:
def restoreDynamics():
"""
Resumes physics for this object.
+ @Note: The objects linear velocity will be applied from when the dynamics were suspended.
"""
def enableRigidBody():
"""
Enables rigid body physics for this object.
Rigid body physics allows the object to roll on collisions.
+ @Note: This is not working with bullet physics yet.
"""
def disableRigidBody():
"""
Disables rigid body physics for this object.
+ @Note: This is not working with bullet physics yet. The angular is removed but rigid body physics can still rotate it later.
"""
def getParent():
"""
diff --git a/source/gameengine/Rasterizer/CMakeLists.txt b/source/gameengine/Rasterizer/CMakeLists.txt
index 18a755afefd..6d53ee53471 100644
--- a/source/gameengine/Rasterizer/CMakeLists.txt
+++ b/source/gameengine/Rasterizer/CMakeLists.txt
@@ -32,6 +32,8 @@ SET(INC
../../../intern/string
../../../intern/moto/include
../../../extern/glew/include
+ ../Expressions
+ ${PYTHON_INC}
)
BLENDERLIB(bf_rasterizer "${SRC}" "${INC}")
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index 23153fcd86c..958fead33ce 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -52,6 +52,7 @@
#include <config.h>
#endif
+#include "Value.h"
RAS_2DFilterManager::RAS_2DFilterManager():
texturewidth(-1), textureheight(-1),
@@ -73,12 +74,14 @@ numberoffilters(0)
m_filters[passindex] = 0;
m_enabled[passindex] = 0;
texflag[passindex] = 0;
+ m_gameObjects[passindex] = NULL;
}
texname[0] = texname[1] = texname[2] = -1;
}
RAS_2DFilterManager::~RAS_2DFilterManager()
{
+ FreeTextures();
}
unsigned int RAS_2DFilterManager::CreateShaderProgram(char* shadersource)
@@ -150,6 +153,27 @@ unsigned int RAS_2DFilterManager::CreateShaderProgram(int filtermode)
}
return 0;
}
+void RAS_2DFilterManager::AnalyseShader(int passindex, vector<STR_String>& propNames)
+{
+ texflag[passindex] = 0;
+ if(glGetUniformLocationARB(m_filters[passindex], "bgl_DepthTexture") != -1)
+ {
+ texflag[passindex] |= 0x1;
+ }
+ if(glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture") != -1)
+ {
+ texflag[passindex] |= 0x2;
+ }
+
+ if(m_gameObjects[passindex])
+ {
+ int objProperties = propNames.size();
+ int i;
+ for(i=0; i<objProperties; i++)
+ if(glGetUniformLocationARB(m_filters[passindex], propNames[i]) != -1)
+ m_properties[passindex].push_back(propNames[i]);
+ }
+}
void RAS_2DFilterManager::StartShaderProgram(int passindex)
{
@@ -177,7 +201,7 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
}
/* send luminance texture to glsl program if it needs */
- if(texflag[passindex] & 0x1){
+ if(texflag[passindex] & 0x2){
uniformLoc = glGetUniformLocationARB(m_filters[passindex], "bgl_LuminanceTexture");
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texname[2]);
@@ -203,6 +227,17 @@ void RAS_2DFilterManager::StartShaderProgram(int passindex)
{
glUniform1fARB(uniformLoc,textureheight);
}
+
+ int i, objProperties = m_properties[passindex].size();
+ for(i=0; i<objProperties; i++)
+ {
+ uniformLoc = glGetUniformLocationARB(m_filters[passindex], m_properties[passindex][i]);
+ if(uniformLoc != -1)
+ {
+ float value = ((CValue*)m_gameObjects[passindex])->GetPropertyNumber(m_properties[passindex][i], 0.0);
+ glUniform1fARB(uniformLoc,value);
+ }
+ }
}
void RAS_2DFilterManager::EndShaderProgram()
@@ -210,14 +245,21 @@ void RAS_2DFilterManager::EndShaderProgram()
glUseProgramObjectARB(0);
}
-void RAS_2DFilterManager::SetupTexture()
+void RAS_2DFilterManager::FreeTextures()
{
- if(texname[0]!=-1 || texname[1]!=-1)
- {
- glDeleteTextures(2, (GLuint*)texname);
- }
- glGenTextures(3, (GLuint*)texname);
+ if(texname[0]!=-1)
+ glDeleteTextures(1, (GLuint*)&texname[0]);
+ if(texname[1]!=-1)
+ glDeleteTextures(1, (GLuint*)&texname[1]);
+ if(texname[2]!=-1)
+ glDeleteTextures(1, (GLuint*)&texname[2]);
+}
+void RAS_2DFilterManager::SetupTextures(bool depth, bool luminance)
+{
+ FreeTextures();
+
+ glGenTextures(1, (GLuint*)&texname[0]);
glBindTexture(GL_TEXTURE_2D, texname[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texturewidth, textureheight, 0, GL_RGB,
GL_UNSIGNED_BYTE, 0);
@@ -226,23 +268,29 @@ void RAS_2DFilterManager::SetupTexture()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glBindTexture(GL_TEXTURE_2D, texname[1]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight, 0, GL_DEPTH_COMPONENT,
- GL_FLOAT,NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
+ if(depth){
+ glGenTextures(1, (GLuint*)&texname[1]);
+ glBindTexture(GL_TEXTURE_2D, texname[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, texturewidth,textureheight,
+ 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE,NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
GL_NONE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
- glBindTexture(GL_TEXTURE_2D, texname[2]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight, 0, GL_LUMINANCE,
- GL_UNSIGNED_BYTE, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
+
+ if(luminance){
+ glGenTextures(1, (GLuint*)&texname[2]);
+ glBindTexture(GL_TEXTURE_2D, texname[2]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE16, texturewidth, textureheight,
+ 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
}
void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height)
@@ -273,62 +321,72 @@ void RAS_2DFilterManager::UpdateOffsetMatrix(int width, int height)
textureoffsets[(((i*3)+j)*2)+1] = (-1.0f * yInc) + ((GLfloat)j * yInc);
}
}
-
- SetupTexture();
}
void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
{
+ bool need_depth=false;
+ bool need_luminance=false;
+ int num_filters = 0;
+
+ int passindex;
+
if(!isshadersupported)
return;
+ for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
+ {
+ if(m_filters[passindex] && m_enabled[passindex]){
+ num_filters ++;
+ if(texflag[passindex] & 0x1)
+ need_depth = true;
+ if(texflag[passindex] & 0x2)
+ need_luminance = true;
+ if(need_depth && need_luminance)
+ break;
+ }
+ }
+
+ if(num_filters <= 0)
+ return;
+
if(canvaswidth != canvas->GetWidth() || canvasheight != canvas->GetHeight())
{
UpdateOffsetMatrix(canvas->GetWidth(), canvas->GetHeight());
+ SetupTextures(need_depth, need_luminance);
}
GLuint viewport[4]={0};
- int passindex;
- bool first = true;
+ if(need_depth){
+ glActiveTextureARB(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, texname[1]);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0);
+ }
+
+ if(need_luminance){
+ glActiveTextureARB(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, texname[2]);
+ glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0);
+ }
+
+ glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
+ glViewport(0, 0, texturewidth, textureheight);
+
+ glDisable(GL_DEPTH_TEST);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
for(passindex =0; passindex<MAX_RENDER_PASS; passindex++)
{
if(m_filters[passindex] && m_enabled[passindex])
{
- if(first)
- {
- /* this pass needs depth texture*/
- if(texflag[passindex] & 0x1){
- glActiveTextureARB(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texname[1]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, 0,0, texturewidth,textureheight, 0);
- }
-
- /* this pass needs luminance texture*/
- if(texflag[passindex] & 0x2){
- glActiveTextureARB(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, texname[2]);
- glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, 0,0, texturewidth,textureheight, 0);
- }
-
- glGetIntegerv(GL_VIEWPORT,(GLint *)viewport);
- glViewport(0, 0, texturewidth, textureheight);
-
- glDisable(GL_DEPTH_TEST);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- first = false;
- }
-
StartShaderProgram(passindex);
-
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texname[0]);
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, texturewidth, textureheight, 0);
-
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
@@ -341,15 +399,12 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
}
- if(!first)
- {
- glEnable(GL_DEPTH_TEST);
- glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
- EndShaderProgram();
- }
+ glEnable(GL_DEPTH_TEST);
+ glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
+ EndShaderProgram();
}
-void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag)
+void RAS_2DFilterManager::EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text)
{
if(!isshadersupported)
return;
@@ -374,16 +429,19 @@ void RAS_2DFilterManager::EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_Str
glDeleteObjectARB(m_filters[pass]);
m_enabled[pass] = 0;
m_filters[pass] = 0;
+ m_gameObjects[pass] = NULL;
+ m_properties[pass].clear();
texflag[pass] = 0;
return;
}
if(mode == RAS_2DFILTER_CUSTOMFILTER)
{
- texflag[pass] = tflag;
if(m_filters[pass])
glDeleteObjectARB(m_filters[pass]);
m_filters[pass] = CreateShaderProgram(text.Ptr());
+ m_gameObjects[pass] = gameObj;
+ AnalyseShader(pass, propNames);
m_enabled[pass] = 1;
return;
}
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.h b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
index faf7c652388..9d8326b96de 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.h
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.h
@@ -28,8 +28,6 @@
#ifndef __RAS_I2DFILTER
#define __RAS_I2DFILTER
-
-
#define MAX_RENDER_PASS 100
class RAS_2DFilterManager
@@ -37,9 +35,15 @@ class RAS_2DFilterManager
private:
unsigned int CreateShaderProgram(char* shadersource);
unsigned int CreateShaderProgram(int filtermode);
+ void AnalyseShader(int passindex, vector<STR_String>& propNames);
void StartShaderProgram(int passindex);
void EndShaderProgram();
+ void SetupTextures(bool depth, bool luminance);
+ void FreeTextures();
+
+ void UpdateOffsetMatrix(int width, int height);
+
float textureoffsets[18];
float view[4];
/* texname[0] contains render to texture, texname[1] contains depth texture, texname[2] contains luminance texture*/
@@ -54,6 +58,13 @@ private:
short texflag[MAX_RENDER_PASS];
bool isshadersupported;
+
+ unsigned int m_filters[MAX_RENDER_PASS];
+ short m_enabled[MAX_RENDER_PASS];
+
+ // stores object properties to send to shaders in each pass
+ vector<STR_String> m_properties[MAX_RENDER_PASS];
+ void* m_gameObjects[MAX_RENDER_PASS];
public:
enum RAS_2DFILTER_MODE {
RAS_2DFILTER_ENABLED = -2,
@@ -74,19 +85,12 @@ public:
RAS_2DFILTER_NUMBER_OF_FILTERS
};
- unsigned int m_filters[MAX_RENDER_PASS];
- short m_enabled[MAX_RENDER_PASS];
-
RAS_2DFilterManager();
~RAS_2DFilterManager();
- void SetupTexture();
-
- void UpdateOffsetMatrix(int width, int height);
-
void RenderFilters(RAS_ICanvas* canvas);
- void EnableFilter(RAS_2DFILTER_MODE mode, int pass, STR_String& text, short tflag);
+ void EnableFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFILTER_MODE mode, int pass, STR_String& text);
};
#endif
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_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h
index 781f90d4124..54a663ba111 100644
--- a/source/gameengine/Rasterizer/RAS_IRenderTools.h
+++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h
@@ -185,7 +185,7 @@ public:
virtual
void
- Update2DFilter(RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text, short textureflag)=0;
+ Update2DFilter(vector<STR_String>& propNames, void* gameObj, RAS_2DFilterManager::RAS_2DFILTER_MODE filtermode, int pass, STR_String& text)=0;
virtual
void
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/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript
index f077833b850..e6bc657ed6d 100644
--- a/source/gameengine/Rasterizer/SConscript
+++ b/source/gameengine/Rasterizer/SConscript
@@ -7,7 +7,8 @@ if env['WITH_BF_GLEXT'] == 1:
env['CPPFLAGS'].append('-DWITH_GLEXT')
-incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include'
+incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions'
+incs += ' ' + env['BF_PYTHON_INC']
if env['OURPLATFORM']=='win32-vc':
cflags = []
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) {