svn merge -r 15292:15392 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorAndre Susano Pinto <andresusanopinto@gmail.com>
Mon, 30 Jun 2008 22:57:52 +0000 (22:57 +0000)
committerAndre Susano Pinto <andresusanopinto@gmail.com>
Mon, 30 Jun 2008 22:57:52 +0000 (22:57 +0000)
144 files changed:
extern/libredcode/debayer.c
intern/iksolver/intern/IK_QTask.h
intern/moto/include/MT_random.h
intern/moto/intern/MT_random.cpp
projectfiles_vc7/gameengine/gamelogic/SCA_GameLogic.vcproj
projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
release/scripts/DirectX8Exporter.py
release/scripts/animation_bake_constraints.py [new file with mode: 0644]
release/scripts/bpymodules/BPyArmature.py
release/scripts/c3d_import.py [new file with mode: 0644]
source/blender/blenkernel/BKE_ipo.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/sca.c
source/blender/blenkernel/intern/text.c
source/blender/blenlib/BLI_arithb.h
source/blender/blenlib/intern/arithb.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/IMB_anim.h
source/blender/imbuf/intern/anim.c
source/blender/include/BIF_butspace.h
source/blender/include/BIF_interface.h
source/blender/include/BIF_oops.h
source/blender/include/butspace.h
source/blender/include/transform.h
source/blender/makesdna/DNA_actuator_types.h
source/blender/makesdna/DNA_controller_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_sensor_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/nodes/intern/CMP_nodes/CMP_math.c
source/blender/python/api2_2x/CurNurb.c
source/blender/python/api2_2x/Lamp.c
source/blender/python/api2_2x/Mathutils.c
source/blender/python/api2_2x/doc/Curve.py
source/blender/render/intern/source/pipeline.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_logic.c
source/blender/src/buttons_scene.c
source/blender/src/drawaction.c
source/blender/src/drawview.c
source/blender/src/editaction.c
source/blender/src/editfont.c
source/blender/src/editmesh_mods.c
source/blender/src/editobject.c
source/blender/src/editseq.c
source/blender/src/editsima.c
source/blender/src/interface.c
source/blender/src/oops.c
source/blender/src/poseobject.c
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/transform.c
source/blender/src/transform_constraints.c
source/blender/src/transform_generics.c
source/blender/src/transform_snap.c
source/blender/src/view.c
source/creator/creator.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/BL_ActionActuator.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_ShapeDeformer.cpp
source/gameengine/Converter/BL_ShapeDeformer.h
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.h
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Converter/KX_ConvertControllers.cpp
source/gameengine/Converter/KX_ConvertSensors.cpp
source/gameengine/Expressions/Value.cpp
source/gameengine/Expressions/Value.h
source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
source/gameengine/GameLogic/SCA_2DFilterActuator.h
source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
source/gameengine/GameLogic/SCA_AlwaysSensor.h
source/gameengine/GameLogic/SCA_IActuator.cpp
source/gameengine/GameLogic/SCA_IActuator.h
source/gameengine/GameLogic/SCA_IController.cpp
source/gameengine/GameLogic/SCA_IController.h
source/gameengine/GameLogic/SCA_IObject.cpp
source/gameengine/GameLogic/SCA_IObject.h
source/gameengine/GameLogic/SCA_ISensor.cpp
source/gameengine/GameLogic/SCA_ISensor.h
source/gameengine/GameLogic/SCA_JoystickSensor.cpp
source/gameengine/GameLogic/SCA_JoystickSensor.h
source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
source/gameengine/GameLogic/SCA_KeyboardSensor.h
source/gameengine/GameLogic/SCA_LogicManager.cpp
source/gameengine/GameLogic/SCA_MouseSensor.cpp
source/gameengine/GameLogic/SCA_MouseSensor.h
source/gameengine/GameLogic/SCA_NANDController.cpp [new file with mode: 0644]
source/gameengine/GameLogic/SCA_NANDController.h [new file with mode: 0644]
source/gameengine/GameLogic/SCA_NORController.cpp [new file with mode: 0644]
source/gameengine/GameLogic/SCA_NORController.h [new file with mode: 0644]
source/gameengine/GameLogic/SCA_PropertySensor.cpp
source/gameengine/GameLogic/SCA_PropertySensor.h
source/gameengine/GameLogic/SCA_PythonController.cpp
source/gameengine/GameLogic/SCA_PythonController.h
source/gameengine/GameLogic/SCA_RandomSensor.cpp
source/gameengine/GameLogic/SCA_RandomSensor.h
source/gameengine/GameLogic/SCA_XNORController.cpp [new file with mode: 0644]
source/gameengine/GameLogic/SCA_XNORController.h [new file with mode: 0644]
source/gameengine/GameLogic/SCA_XORController.cpp [new file with mode: 0644]
source/gameengine/GameLogic/SCA_XORController.h [new file with mode: 0644]
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.h
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_IPhysicsController.h
source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
source/gameengine/Ketsji/KX_MouseFocusSensor.h
source/gameengine/Ketsji/KX_ObjectActuator.cpp
source/gameengine/Ketsji/KX_ObjectActuator.h
source/gameengine/Ketsji/KX_RadarSensor.cpp
source/gameengine/Ketsji/KX_RaySensor.cpp
source/gameengine/Ketsji/KX_RaySensor.h
source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp [new file with mode: 0644]
source/gameengine/Ketsji/KX_SCA_DynamicActuator.h [new file with mode: 0644]
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_StateActuator.cpp [new file with mode: 0644]
source/gameengine/Ketsji/KX_StateActuator.h [new file with mode: 0644]
source/gameengine/Ketsji/KX_SumoPhysicsController.h
source/gameengine/Ketsji/KX_TouchSensor.cpp
source/gameengine/Ketsji/KX_TouchSensor.h
source/gameengine/PyDoc/KX_GameObject.py
source/gameengine/PyDoc/SCA_PythonController.py
source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
source/gameengine/Rasterizer/RAS_2DFilterManager.h
source/gameengine/Rasterizer/RAS_IRenderTools.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_VAOpenGLRasterizer.cpp

index f7f22e1cc545d2991767d20235d7a17a5c12e018..de7bec510cb9a61edd2bfdb3270b7b21e20718a2 100644 (file)
@@ -9,8 +9,6 @@ void redcode_ycbcr2rgb_fullscale(
        int x,y;
        int pix_max = 4096;
        int mask = pix_max - 1;
-       float Kb = 0.0722;
-       float Kr = 0.2126;
        float *o;
 
        for (y = 0; y < height; y++) {
@@ -25,9 +23,9 @@ void redcode_ycbcr2rgb_fullscale(
                        float y2  = (planes[3][i] & mask);
                        float y2p = (planes[3][i_p] & mask);
 
-                       float b_ = cb * (1.0 - Kb)/(pix_max/2);
-                       float r_ = cr * (1.0 - Kr)/(pix_max/2);
-                       float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb);
+                       float b_ = cb /(pix_max/2);
+                       float r_ = cr /(pix_max/2);
+                       float g_ = 0.0;
                
                        float y_[4] = {y1 / pix_max, 
                                       (y2 + y2p)/2 / pix_max, 
@@ -68,8 +66,6 @@ void redcode_ycbcr2rgb_halfscale(
        int x,y;
        int pix_max = 4096;
        int mask = pix_max - 1;
-       float Kb = 0.0722;
-       float Kr = 0.2126;
 
        for (y = 0; y < height; y++) {
                float *o = out + width * (height - y - 1);
@@ -80,9 +76,9 @@ void redcode_ycbcr2rgb_halfscale(
                        float cr  = (planes[2][i] & mask)  - pix_max/2;
                        float y2  = (planes[3][i] & mask);
 
-                       float b_ = cb * (1.0 - Kb)/(pix_max/2);
-                       float r_ = cr * (1.0 - Kr)/(pix_max/2);
-                       float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb);
+                       float b_ = cb /(pix_max/2);
+                       float r_ = cr /(pix_max/2);
+                       float g_ = 0.0;
                        
                        float y = (y1 + y2)/2 / pix_max;
 
@@ -101,8 +97,6 @@ void redcode_ycbcr2rgb_quarterscale(
        int x,y;
        int pix_max = 4096;
        int mask = pix_max - 1;
-       float Kb = 0.0722;
-       float Kr = 0.2126;
 
        for (y = 0; y < height; y += 2) {
                float *o = out + (width/2) * (height/2 - y/2 - 1);
@@ -113,9 +107,9 @@ void redcode_ycbcr2rgb_quarterscale(
                        float cr  = (planes[2][i] & mask)  - pix_max/2;
                        float y2  = planes[3][i] & mask;
 
-                       float b_ = cb * (1.0 - Kb)/(pix_max/2);
-                       float r_ = cr * (1.0 - Kr)/(pix_max/2);
-                       float g_ = (- Kr * r_ - Kb * b_)/(1.0 - Kr - Kb);
+                       float b_ = cb /(pix_max/2);
+                       float r_ = cr /(pix_max/2);
+                       float g_ = 0.0;
                        
                        float y = (y1 + y2)/2 / pix_max;
                        
index c291a0e7e50eb27060e2f034b273c068b1a3065a..4d469d737f8d51466f3b8e0392c771b6f10ebfbe 100644 (file)
@@ -74,7 +74,7 @@ public:
 
        virtual bool PositionTask() const { return false; }
 
-       virtual void Scale(float scale) {}
+       virtual void Scale(float) {}
 
 protected:
        int m_id;
index d7da546cf03b3d9ec6be0b5444808fbcb0ce2bbe..3afe1dd16622271f3ef57ba079d846e86eb97a69 100644 (file)
 
 #include <limits.h>
 
-#define MT_RAND_MAX ULONG_MAX
+#define MT_RAND_MAX UINT_MAX
 
-extern void          MT_srand(unsigned long);
-extern unsigned long MT_rand();
+extern void          MT_srand(unsigned int);
+extern unsigned int  MT_rand();
 
 #endif
 
index 96cb394d3da324bd025e46544d6b3558266e3c52..b8302e093ca8ef1cc15d6d85c7c7818a7c14b7eb 100644 (file)
 #define TEMPERING_SHIFT_T(y)  (y << 15)
 #define TEMPERING_SHIFT_L(y)  (y >> 18)
 
-static unsigned long mt[N]; /* the array for the state vector  */
+static unsigned int mt[N]; /* the array for the state vector  */
 static int mti = N+1; /* mti==N+1 means mt[N] is not initialized */
 
 /* initializing the array with a NONZERO seed */
-void MT_srand(unsigned long seed)
+void MT_srand(unsigned int seed)
 {
     /* setting initial seeds to mt[N] using         */
     /* the generator Line 25 of Table 1 in          */
@@ -91,12 +91,12 @@ void MT_srand(unsigned long seed)
         mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
 }
 
-unsigned long MT_rand()
+unsigned int MT_rand()
 {
-    static unsigned long mag01[2] = { 0x0, MATRIX_A };
+    static unsigned int mag01[2] = { 0x0, MATRIX_A };
     /* mag01[x] = x * MATRIX_A  for x=0,1 */
 
-    unsigned long y;
+    unsigned int y;
 
     if (mti >= N) { /* generate N words at one time */
         int kk;
index 07fcfa64a72436a9d184ca28fd990fa0f9801551..e0405b4d7c73e420d6fa411aacde7897a3b2bbf1 100644 (file)
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_MouseSensor.cpp">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_NANDController.cpp">
+                       </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_NORController.cpp">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ORController.cpp">
                        </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_TimeEventManager.cpp">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_XNORController.cpp">
+                       </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_XORController.cpp">
+                       </File>
                </Filter>
                <Filter
                        Name="Header Files"
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_MouseSensor.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_NANDController.h">
+                       </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_NORController.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_ORController.h">
                        </File>
                        <File
                                RelativePath="..\..\..\source\gameengine\GameLogic\SCA_TimeEventManager.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_XNORController.h">
+                       </File>
+                       <File
+                               RelativePath="..\..\..\source\gameengine\GameLogic\SCA_XORController.h">
+                       </File>
                </Filter>
        </Files>
        <Globals>
index c8173750bdc15687e5b4fba75dbf47c300ddf655..9d5a9f55074877e6aef998625fcd89a6d01b0e93 100644 (file)
                                <File
                                        RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_AddObjectActuator.cpp">
                                </File>
+                               <File
+                                       RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_DynamicActuator.cpp">
+                               </File>
                                <File
                                        RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_EndObjectActuator.cpp">
                                </File>
                                <File
                                        RelativePath="..\..\..\source\gameengine\Ketsji\KX_SoundActuator.cpp">
                                </File>
+                               <File
+                                       RelativePath="..\..\..\source\gameengine\Ketsji\KX_StateActuator.cpp">
+                               </File>
                                <File
                                        RelativePath="..\..\..\source\gameengine\Ketsji\KX_TrackToActuator.cpp">
                                </File>
                                <File
                                        RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_AddObjectActuator.h">
                                </File>
+                               <File
+                                       RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_DynamicActuator.h">
+                               </File>
                                <File
                                        RelativePath="..\..\..\source\gameengine\Ketsji\KX_SCA_EndObjectActuator.h">
                                </File>
                                <File
                                        RelativePath="..\..\..\source\gameengine\Ketsji\KX_SoundActuator.h">
                                </File>
+                               <File
+                                       RelativePath="..\..\..\source\gameengine\Ketsji\KX_StateActuator.h">
+                               </File>
                                <File
                                        RelativePath="..\..\..\source\gameengine\Ketsji\KX_TrackToActuator.h">
                                </File>
index 2ec42057039eb620825cfeebb7f439e532e99e72..01212545f775b63724d81c5dafedab79d89e4447 100644 (file)
@@ -6,9 +6,9 @@
 # Group: 'Export'
 # Tooltip: 'Export to DirectX text file format format for XNA Animation Component Library.'
 """
-__author__ = "minahito (original:Arben (Ben) Omari)"
-__url__ = ("blender", "blenderartists.org", "Adjuster's site http://sunday-lab.blogspot.com/, Author's site http://www.omariben.too.it")
-__version__ = "3.0"
+__author__ = "vertex color exporting feature is added by mnemoto (original:minahito (original:Arben (Ben) Omari))"
+__url__ = ("blender", "elysiun", "Adjuster's site http://sunday-lab.blogspot.com/, Author's site http://www.omariben.too.it","Adjuster's site http://ex.homeunix.net/")
+__version__ = "3.1"
 
 __bpydoc__ = """\
 This script exports a Blender mesh with armature to DirectX 8's text file
@@ -444,6 +444,7 @@ class xExport:
                self.writeMeshMaterialList(obj, mesh, tex)
                self.writeMeshNormals(obj, mesh)
                self.writeMeshTextureCoords(obj, mesh)
+               self.writeMeshVertexColors(obj, mesh)
                self.file.write("  }  // End of the Mesh %s \n" % (obj.name))
                
                                        
@@ -464,6 +465,7 @@ class xExport:
                                self.writeMeshMaterialList(obj, mesh, tex)
                                self.writeMeshNormals(obj, mesh)
                                self.writeMeshTextureCoords(obj, mesh)
+                               self.writeMeshVertexColors(obj, mesh)
                                self.file.write(" }\n")
                                self.file.write("}\n")
                                ind = objs.index(obj)
@@ -1047,6 +1049,32 @@ template SkinWeights {\n\
                                                self.file.write(",\n")
 
                        self.file.write("}  //End of MeshTextureCoords\n")
+
+       #***********************************************
+       #MESH VORTEX COLORS
+       #***********************************************
+       def writeMeshVertexColors(self, name, mesh):
+               if mesh.hasVertexColours():
+                       self.file.write("MeshVertexColors {\n")
+                       #VERTICES NUMBER
+                       numvert = reduce( lambda i,f: len(f)+i, mesh.faces, 0)
+                       self.file.write("%d;\n" % (numvert))
+                       #VERTEX COLORS
+                       
+                       vcounter =0
+                       for f in mesh.faces:
+                               col = f.col
+                               for i,c in enumerate(col):
+                                       # Note vcol alpha has no meaning
+                                       self.file.write("%d;%f;%f;%f;%f;" % (vcounter,c.r/255.0, c.g/255.0, c.b/255.0, 1.0)) # c.a/255.0))
+                                       vcounter+=1
+                                       if vcounter == numvert :
+                                               self.file.write(";\n")
+                                       else :
+                                               self.file.write(",\n")
+
+                       self.file.write("}  //End of MeshVertexColors\n")
+
 #***********************************************#***********************************************#***********************************************
        #***********************************************
        #FRAMES
diff --git a/release/scripts/animation_bake_constraints.py b/release/scripts/animation_bake_constraints.py
new file mode 100644 (file)
index 0000000..130e93d
--- /dev/null
@@ -0,0 +1,800 @@
+#!BPY
+
+"""
+Name: 'Bake Constraints'
+Blender: 246
+Group: 'Animation'
+Tooltip: 'Bake a Constrained object/rig to IPOs'
+Fillename: 'Bake_Constraint.py'
+"""
+
+__author__ = "Roger Wickes (rogerwickes(at)yahoo.com)"
+__script__ = "Bake Constraints"
+__version__ = "0.6"
+__url__ = ["Communicate problems and errors, http://www.blenderartists.com/forum/private.php?do=newpm to PapaSmurf"]
+__email__= ["Roger Wickes, rogerwickes@yahoo.com", "scripts"]
+__bpydoc__ = """\
+
+bake_constraints
+
+This script bakes the real-world LocRot of an object (the net effect of any constraints - 
+(Copy, Limit, Track, Follow, - that affect Location, Rotation)
+(usually one constrained to match another's location and/or Tracked to another)
+and creates a clone with a set of Ipo Curves named Ipo<objname>
+These curves control a non-constrained object and thus make it mimic the constrained object
+Actions can be then be edited without the need for the drivers/constraining objects
+
+Developed for use with MoCap data, where a bone is constrained to point at an empty
+moving through space and time. This records the actual locrot of the armature
+so that the motion can be edited, reoriented, scaled, and used as NLA Actions
+
+see also wiki Scripts/Manual/ Sandbox/Animation/Bake_Constraints (tbd)
+
+Usage:<br>
+ - Select the reference Object(s) you want to bake <br>
+ - Set the frame range to bake in the Anim Panel <br>
+ - Set the test code (if you want a self-test) in the RT field in the Anim Panel <br>
+               -- Set RT:1 in the Anim panel to create a test armature <br>
+<br>
+ - Run the script    <br>
+ - The clone copy of the object is created and it has an IPO curve assigned to it. 
+ - The clone shadows the object by an offset locrot (see usrDelta)
+ - That Ipo has Location and Rotation curves that make the shadow mimic the movement of the selected object, 
+                but without using constraints. Bones move identically in relation to the armature as the reference object
+
+       
+Version History:
+               0.1: bakes Loc Rot for a constrained object
+               0.2: bakes Loc and Rot for the bones within Armature object
+               0.3: UI for setting options
+               0.3.1 add manual to script library
+               0.4: bake multiple objects
+               0.5: root bone worldspace rotation
+               0.6: re-integration with BPyArmature
+               
+License, Copyright, and Attribution:
+       by Roger WICKES  May 2008, released under Blender Artistic Licence to Public Domain
+               feel free to add to any Blender Python Scripts Bundle.
+ Thanks to Jean-Baptiste PERIN, IdeasMan42 (Campbell Barton?), Basil_Fawlty/Cage_drei (Andrew Cruse)
+ much lifted/learned from blender.org/documentation/245PytonDoc and wiki
+ some modules based on c3D_Import.py, PoseLib16.py and IPO/Armature code examples e.g. camera jitter
+
+Pseudocode (planned versions):
+       Initialize
+       If at least one object is selected
+               For each selected object,
+                       create a shadow object
+                       remove any constraints on the clone
+                       create or reset an ipo curve named like the object
+                       for each frame
+                                set the clone's locrot key based on the reference object
+                       if it's an armature,
+                                       create an action (which is an Ipo for each bone)
+                                       for each frame of the animation
+                                               for each bone in the armature
+                                                       set the key
+       Else you're a smurf
+
+Test Conditions and Regressions:
+       1. (v0.1) Non-armatures (the cube), with ipo curve and constraints at the object level
+       2. armatures, with ipo curve and constraints at the object level
+       3. armatures, with bones that have ipo curves and constraints
+       
+Naming conventions:
+       arm = a specific objec type armature
+       bone = bones that make up the skeleton of an armature
+
+       ob = object, an instance of an object type
+       ebone = edit bone, a bone in edit mode
+       pbone = pose bone, a posed bone in an object
+       tst = testing, self-test routines
+       usr = user-entered or designated stuff  
+
+Pattern Notes (let me know if I've violated any):
+       Bergin Starting,Designing, Programming, Coding
+       Bergin 23 Indent for Structure - I don't like only 2, but the editor is set up that way
+       Bergin 26 Be Spacey Not Tabby - personal frustraion here. workaround is to Format->convert to whitespace
+       Bergin 27 Consistent Capitalization - except Blender, because I love it.
+       Bergin 28 Name Your Constants - not for those I plan on making variable
+       Python 01 Return Everything - I made this one up, all functions and methods end in return
+               even though it is decoration in Python, it helps Python throw an indentation error for typing mistakes
+       Wickes 01 Decorate Your Code - for visual appeal and to ease maintenance, include separators like ######### 
+               to visually distinquish and separate functions, making it quicker to scan through code for methods
+       Wickes 02 Whitespace helps readability - include blanks around = # and lines (after def, after return) to make it stand out and pretty
+
+"""
+########################################
+
+import Blender
+from   Blender import *
+from   Blender.Mathutils import *
+import struct
+import string
+import bpy
+import BPyMessages
+import BPyArmature
+# reload(BPyArmature)
+from   BPyArmature import getBakedPoseData
+
+Vector= Blender.Mathutils.Vector
+Euler= Blender.Mathutils.Euler
+Matrix= Blender.Mathutils.Matrix #invert() function at least
+RotationMatrix = Blender.Mathutils.RotationMatrix
+TranslationMatrix= Blender.Mathutils.TranslationMatrix
+Quaternion = Blender.Mathutils.Quaternion
+Vector = Blender.Mathutils.Vector
+POSE_XFORM= [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT]
+
+#=================
+# Global Variables
+#=================
+
+# set senstitivity for displaying debug/console messages. 0=none, 100=max
+# then call debug(num,string) to conditionally display status/info in console window
+MODE=Blender.Get('rt')  #execution mode: 0=run normal, x=self-test (test error trapping etc)
+DEBUG=100   #how much detail on internal processing for big brother to see
+BATCH=False #called from command line? is someone there? Would you like some cake?
+
+#there are two coordinate systems, the real, or absolute 3D space,
+# and the local relative to a parent.
+COORDINATE_SYSTEMS = ['local','real']
+COORD_LOCAL = 0
+COORD_REAL = 1
+
+# User Settings - Change these options manually or via GUI (future TODO)
+usrCoord = COORD_REAL # what the user wants
+usrParent = False # True=keep parent (if exists), False = breakaway (usually with Real)
+usrFreeze = 2 #2=yes, 0=no. Freezes shadow object in place at current frame as origin
+       #TODO - i wonder if usrFreeze means we should set Delta to the the difference between the original object and parent?
+# delta is amount to offset/change from the reference object. future set in a ui, so technically not a constant
+usrDelta = [10,10,0,0,0,0] #order specific - Loc xyz Rot xyz
+usrACTION = True # Offset baked Action frames to start at frame 1
+usrBAKEobjIPO = False # bake the object Ipo? it is useless for MoCap, as we only want the Action, and the Object does not move
+
+CURFRAME = 'curframe' #keyword to use when getting the frame number that the scene is presently on
+ARMATURE = 'Armature' #en anglais
+BONE_SPACES = ['ARMATURESPACE','BONESPACE']
+               # 'ARMATURESPACE' - this matrix of the bone in relation to the armature
+               # 'BONESPACE' - the matrix of the bone in relation to itself
+
+#Ipo curves created are prefixed with a name, like Ipo_ or Bake_ followed by the object/bone name
+#bakedArmName = "b." #used for both the armature class and object instance
+#ipoObjectNamePrefix= ""
+#ipoBoneNamePrefix  = ""
+# for example, if on entry an armature named Man was selected, and the object prefix was "a."
+#  on exit an armature and an IPO curve named a.Man exists for the object as a whole
+# if that armature had bones (spine, neck, arm) and the bone prefix was "a."
+#  the bones and IPO curves will be (a.spine, a.neck, a.arm)
+
+R2D = 18/3.1415  # radian to grad
+BLENDER_VERSION = Blender.Get('version')
+
+# Gets the current scene, there can be many scenes in 1 blend file. 
+scn = Blender.Scene.GetCurrent()
+
+#=================
+# Methods
+#=================
+########################################
+def debug(num,msg): #use log4j or just console here.
+       
+       if DEBUG >= num:
+               if BATCH == False:
+                       print 'debug:             '[:num/10+7]+msg
+               #TODO: else write out to file (runs faster if it doesnt have to display details)
+       return
+
+########################################
+def error(str):
+       debug(0,'ERROR: '+str)
+       if BATCH == False:
+               Draw.PupMenu('ERROR%t|'+str)
+       return
+
+########################################
+def getRenderInfo():
+       context=scn.getRenderingContext() 
+       staframe = context.startFrame()
+       endframe = context.endFrame()
+       if endframe<staframe: endframe=staframe
+       curframe = Blender.Get(CURFRAME)
+       debug(90,'Scene is on frame %i and frame range is %i to %i' % (curframe,staframe,endframe))
+       return (staframe,endframe,curframe)
+
+########################################
+def sortBones(xbones): #returns a sorted list of bones that should be added,sorted based on parent dependency
+       print ('My suggestion would be:')
+#  while there are bones to add,
+#    look thru the list of bones we need to add
+#      if we have not already added this bone
+#         if it does not have a parent
+#           add it
+#          else, it has a parent
+#           if we already added it's parent
+#               add it now.
+#           else #we need to keep cycling and catch its parent
+#         else it is a root bone
+#           add it
+#       else skip it, it's prego
+#     endfor
+#  endwhile
+       xboneNames=[]
+       for xbone in xbones: xboneNames.append(xbone.name)
+       debug (80,'reference bone order: \n%s' % xboneNames)
+       eboneNames=[]
+       while len(eboneNames) < len(xboneNames):
+               for xbone in xbones:
+                       if not xbone.name in eboneNames:
+                               if not xbone.parent:
+                                       eboneNames.append(xbone.name)
+                               else:
+                                       if xbone.parent.name in eboneNames:
+                                               eboneNames.append(xbone.name)
+                                       #else skip it
+                               #endif
+                       #else prego
+               #endfor
+       #endwhile
+       debug (80,'clone bone order: \n%s' % eboneNames)
+       return eboneNames
+
+########################################
+def dupliArmature(ob): #makes a copy in current scn of the armature used by ob and its bones
+       
+       ob_mat = ob.matrixWorld
+       ob_data = ob.getData()
+       debug(49,'Reference object uses %s' % ob_data)
+       arm_ob = Armature.Get(ob_data.name) #the armature used by the passed object
+       
+       arm = Blender.Armature.New()
+       debug(20,'Cloning Armature %s to create %s' % (arm_ob.name, arm.name))
+       arm.drawType = Armature.STICK #set the draw type
+
+       arm.makeEditable() #enter editmode
+
+       # for each bone in the object's armature,
+       xbones=ob.data.bones.values()
+       usrSpace = 0 #0=armature, 1=local
+       space=[BONE_SPACES[usrSpace]][0] 
+
+       #we have to make a list of bones, then figure out our parents, then add to the arm
+       #when creating a child, we cannot link to a parent if it does not yet exist in our armature 
+       ebones = [] #list of the bones I want to create for my arm
+
+       if BLENDER_VERSION > 245: debug(0,'WARNING: Programmer check for Bone updates in dupliArmature')
+
+       eboneNames = sortBones(xbones)
+
+       i=0
+       # error('bones sorted. continue?')
+       for abone in eboneNames: #set all editable attributes to fully define the bone.
+               for bone in xbones: 
+                       if bone.name == abone: break  # get the reference bone
+               ebone = Armature.Editbone() #throw me a bone, bone-man!
+               ebones.append(ebone) #you're on my list, buddy
+
+               ebone.name = bone.name
+               ebone.headRadius = bone.headRadius
+               ebone.tailRadius = bone.tailRadius
+               ebone.weight = bone.weight
+               ebone.options = bone.options
+               
+               ebone.head = bone.head[space] #dictionary lookups
+               ebone.tail = bone.tail[space]
+               ebone.matrix = bone.matrix[space]
+               ebone.roll = bone.roll[space]
+
+               debug(30,'Generating new %s as child of %s' % (bone,bone.parent))
+               if bone.hasParent(): 
+#      parent=bone.parent.name
+#      debug(100,'looking for %s' % parent)
+#      for parbone in xbones: if parbone.name == parent: break # get the parent bone
+#      ebone.parent = arm.bones[ebones[j].name]
+                       ebone.parent = arm.bones[bone.parent.name]
+#    else:
+#       ebone.parent = None
+               debug(30,'Generating new editbone %s as child of %s' % (ebone,ebone.parent))
+               arm.bones[ebone.name] = ebone # i would have expected an append or add function, but this works
+
+       debug (100,'arm.bones: \n%s' % arm.bones)
+       debug (20,'Cloned %i bones now in armature %s' %(len(arm.bones),arm.name)) 
+
+       myob = scn.objects.new(arm) #interestingly, object must be created before 
+       arm.update()                #armature can be saved
+       debug(40,'dupArm finished %s instanced as object %s' % (arm.name,myob.getName()))
+       print ob.matrix
+       print myob.matrix
+       
+       return myob
+
+def scrub(): # scrubs to startframe
+       staFrame,endFrame,curFrame = getRenderInfo()
+
+       # eye-candy, go from current to start, fwd or back
+       if not BATCH:
+               print "Positioning to start..."
+               frameinc=(staFrame-curFrame)/10
+               if abs(frameinc) >= 1:
+                       for i in range(10):
+                               curFrame+=frameinc
+                               Blender.Set(CURFRAME,curFrame) # computes the constrained location of the 'real' objects
+                               Blender.Redraw()
+       Blender.Set(CURFRAME, staFrame)
+
+########################################
+def bakeBones(ref_ob,arm_ob): #copy pose from ref_ob to arm_ob
+       scrub()
+       staFrame,endFrame,curFrame = getRenderInfo()
+       act = getBakedPoseData(ref_ob, staFrame, endFrame, ACTION_BAKE = True, ACTION_BAKE_FIRST_FRAME = usrACTION) # bake the pose positions of the reference ob to the armature ob
+       arm_ob.action = act
+       scrub()  
+       
+       # user comprehension feature - change action name and channel ipo names to match the names of the bone they drive
+       debug (80,'Renaming each action ipo to match the bone they pose')
+       act.name = arm_ob.name
+       arm_channels = act.getAllChannelIpos()
+       pose= arm_ob.getPose()
+       pbones= pose.bones.values() #we want the bones themselves, not the dictionary lookup
+       print arm_channels.keys()
+       for pbone in pbones:
+               debug (100,'Channel listing for %s: %s' % (pbone.name,arm_channels[pbone.name] ))
+               ipo=arm_channels[pbone.name]
+               ipo.name = pbone.name # since bone names are unique within an armature, the pose names can be the same since they are within an Action
+
+       return
+
+########################################
+def getOrCreateCurve(ipo, curvename): 
+       
+       """
+       Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo
+       Either an ipo curve named C{curvename} exists before the call then this curve is returned,
+       Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned 
+       """
+       try:
+               mycurve = ipo.getCurve(curvename)
+               if mycurve != None:
+                       pass
+               else:
+                       mycurve = ipo.addCurve(curvename)
+       except:
+               mycurve = ipo.addCurve(curvename)
+       return mycurve
+
+########################################
+def eraseCurve(ipo,numCurves): 
+       debug(80,'Erasing %i curves for %' % (numCurves,ipo.GetName()))
+       for i in range(numCurves):
+               nbBezPoints = ipo.getNBezPoints(i)
+               for j in range(nbBezPoints):
+                       ipo.delBezPoint(i)
+       return
+
+########################################
+def resetIPO(ipo):
+       ipoName=ipoObjectNamePrefix + obName
+       debug(40,'Resetting ipo curve named %s' %ipoName)
+       numCurves = ipo.getNcurves() #like LocX, LocY, etc
+       if numCurves > 0:
+               eraseCurve(ipo, numCurves) #erase data if one exists
+       return
+
+########################################
+def resetIPOs(ob): #resets all IPO curvess assocated with an object and its bones
+       debug(30,'Resetting any ipo curves linked to %s' %ob.getName())
+       ipo = ob.getIpo() #may be None
+       ipoName = ipo.getName() #name of the IPO that guides/controls this object
+       debug(70,'Object IPO is %s' %ipoName)
+       try:
+               ipo = Ipo.Get(ipoName)
+       except:
+               ipo = Ipo.New('Object', ipoName)
+       resetIPO(ipo)
+       if ob.getType() == ARMATURE:
+               arm_data=ob.getData()
+               bones=arm_data.bones.values()
+               for bone in bones:
+                       #for each bone: get the name and check for a Pose IPO
+                       debug(10,'Processing '+ bone.name)
+       return
+
+########################################
+def parse(string,delim):       
+       index = string.find(delim) # -1 if not found, else pointer to delim
+       if index+1:  return string[:index]
+       return string
+               
+########################################
+def newIpo(ipoName): #add a new Ipo object to the Blender scene
+       ipo=Blender.Ipo.New('Object',ipoName)
+
+       ipo.addCurve('LocX')
+       ipo.addCurve('LocY')
+       ipo.addCurve('LocZ')
+       ipo.addCurve('RotX')
+       ipo.addCurve('RotY')
+       ipo.addCurve('RotZ')
+       return ipo
+
+########################################
+def makeUpaName(type,name): #i know this exists in Blender somewhere...
+       debug(90,'Making up a new %s name using %s as a basis.' % (type,name))
+       name = (parse(name,'.'))
+       if type == 'Ipo':
+               ipoName = name # maybe we get lucky today
+               ext = 0
+               extlen = 3 # 3 digit extensions, like hello.002
+               success = False
+               while not(success):
+                       try:
+                               debug(100,'Trying %s' % ipoName)
+                               ipo = Ipo.Get(ipoName)
+                               #that one exists if we get here. add on extension and keep trying
+                               ext +=1
+                               if ext>=10**extlen: extlen +=1 # go to more digits if 999 not found
+                               ipoName = '%s.%s' % (name, str(ext).zfill(extlen))
+                       except: # could not find it
+                               success = True
+               name=ipoName 
+       else:
+               debug (0,'FATAL ERROR: I dont know how to make up a new %s name based on %s' % (type,ob))
+               return 
+       return name
+
+########################################
+def createIpo(ob): #create an Ipo and curves and link them to this object      
+       #first, we have to create a unique name
+       #try first with just the name of the object to keep things simple.
+       ipoName = makeUpaName('Ipo',ob.getName()) # make up a name for a new Ipo based on the object name
+
+       debug(20,'Ipo and LocRot curves called %s' % ipoName)
+
+       ipo=newIpo(ipoName)
+
+       ob.setIpo(ipo) #link them
+       return ipo
+
+########################################
+def getLocLocal(ob):
+       key = [
+                       ob.LocX, 
+                       ob.LocY, 
+                       ob.LocZ,
+                       ob.RotX*R2D, #get the curves in this order
+                       ob.RotY*R2D, 
+                       ob.RotZ*R2D
+                       ]
+       return key
+                               
+########################################
+def getLocReal(ob):
+       obMatrix = ob.matrixWorld #Thank you IdeasMan42
+       loc = obMatrix.translationPart()
+       rot = obMatrix.toEuler()
+       key = [
+                       loc.x,
+                       loc.y,
+                       loc.z,
+                       rot.x/10,
+                       rot.y/10,
+                       rot.z/10
+                       ]
+       return key
+
+########################################
+def getLocRot(ob,space):
+       if space in xrange(len(COORDINATE_SYSTEMS)):
+               if space == COORD_LOCAL:
+                       key = getLocLocal(ob)
+                       return key
+               elif space == COORD_REAL:
+                       key = getLocReal(ob)
+                       return key
+               else: #hey, programmers make mistakes too.
+                       debug(0,'Fatal Error: getLoc called with %i' % space)
+       return
+
+########################################
+def getCurves(ipo):
+       ipos = [
+                       ipo[Ipo.OB_LOCX],
+                       ipo[Ipo.OB_LOCY],
+                       ipo[Ipo.OB_LOCZ],
+                       ipo[Ipo.OB_ROTX], #get the curves in this order
+                       ipo[Ipo.OB_ROTY],
+                       ipo[Ipo.OB_ROTZ]
+                       ]
+       return ipos
+                                       
+########################################
+def addPoint(time,keyLocRot,ipos):
+       if BLENDER_VERSION < 245:
+               debug(0,'WARNING: addPoint uses BezTriple')
+       for i in range(len(ipos)):
+               point = BezTriple.New() #this was new with Blender 2.45 API
+               point.pt = (time, keyLocRot[i])
+               point.handleTypes = [1,1]
+
+               ipos[i].append(point)
+       return ipos
+
+########################################
+def bakeFrames(ob,myipo): #bakes an object in a scene, returning the IPO containing the curves
+       myipoName = myipo.getName()
+       debug(20,'Baking frames for scene %s object %s to ipo %s' % (scn.getName(),ob.getName(),myipoName))
+       ipos = getCurves(myipo)
+       #TODO: Gui setup idea: myOffset
+       # reset action to start at frame 1 or at location
+       myOffset=0 #=1-staframe
+       #loop through frames in the animation. Often, there is rollup and the mocap starts late
+       staframe,endframe,curframe = getRenderInfo()
+       for frame in range(staframe, endframe+1):
+               debug(80,'Baking Frame %i' % frame)
+               #tell Blender to advace to frame
+               Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
+               if not BATCH: Blender.Redraw() # no secrets, let user see what we are doing
+                       
+               #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen
+               key = getLocRot(ob,usrCoord) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame
+               key = [a+b for a,b in zip(key, usrDelta)] #offset to the new location
+
+               myframe= frame+myOffset
+               Blender.Set(CURFRAME,myframe)
+               
+               time = Blender.Get('curtime') #for BezTriple
+               ipos = addPoint(time,key,ipos) #add this data at this time to the ipos
+               debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3], key[4], key[5]))
+       # eye-candy - smoothly rewind the animation, showing now how the clone match moves
+       if endframe-staframe <400 and not BATCH:
+               for frame in range (endframe,staframe,-1): #rewind
+                       Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
+                       Blender.Redraw()
+       Blender.Set(CURFRAME,staframe)
+       Blender.Redraw()
+
+       return ipos
+
+########################################
+def duplicateLinked(ob):
+       obType = ob.type
+       debug(10,'Duplicating %s Object named %s' % (obType,ob.getName()))
+       scn.objects.selected = [ob]
+##      rdw: simplified by just duplicating armature. kept code as reference for creating armatures
+##        disadvantage is that you cant have clone as stick and original as octahedron
+##        since they share the same Armature. User can click Make Single User button.      
+##      if obType == ARMATURE: #build a copy from scratch
+##        myob= dupliArmature(ob)
+##      else:
+       Blender.Object.Duplicate() # Duplicate linked, including pose constraints.
+       myobs = Object.GetSelected() #duplicate is top on the list
+       myob = myobs[0]
+       if usrParent == False:
+               myob.clrParent(usrFreeze)     
+       debug(20,'=myob= was created as %s' % myob.getName())
+       return myob
+
+########################################
+def removeConstraints(ob):
+       for const in ob.constraints:
+               debug(90,'removed %s => %s' % (ob.name, const))
+               ob.constraints.remove(const)
+       return
+               
+########################################
+def removeConstraintsOb(ob): # from object or armature
+       debug(40,'Removing constraints from '+ob.getName())
+       if BLENDER_VERSION > 241: #constraints module not available before 242
+               removeConstraints(ob)
+               if ob.getType() == ARMATURE:
+                       pose = ob.getPose()
+                       for pbone in pose.bones.values():
+                               #bone = pose.bones[bonename]
+                               removeConstraints(pbone)
+               #should also check if it is a deflector?
+       return
+
+########################################
+def deLinkOb(type,ob): #remove linkages
+       if type == 'Ipo':
+               success = ob.clearIpo() #true=there was one
+               if success: debug(80,'deLinked Ipo curve to %s' % ob.getName())
+       return
+
+########################################
+def bakeObject(ob): #bakes the core object locrot and assigns the Ipo to a Clone
+       if ob != None:  
+               # Clone the object - duplicate it, clean the clone, and create an ipo curve for the clone
+               myob = duplicateLinked(ob)  #clone it
+               removeConstraintsOb(myob)   #my object is a free man
+               deLinkOb('Ipo',myob)        #kids, it's not nice to share. you've been lied to
+               if usrBAKEobjIPO:
+                       myipo = createIpo(myob)     #create own IPO and curves for the clone object
+                       ipos = bakeFrames(ob,myipo) #bake the locrot for this obj for the scene frames
+
+#  staframe,endframe,curframe = getRenderInfo()
+#  frame = staframe
+#  Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
+#  frame +=1
+#  Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
+#  frame -=1
+#  Blender.Set(CURFRAME,frame) # computes the constrained location of the 'real' objects
+#  if not BATCH: Blender.Redraw()
+#
+       return myob
+               
+########################################
+def bake(ob): #bakes an object of any type
+       
+       debug(30,'Baking %s object %s' % (ob.getType(), ob))
+
+       myob = bakeObject(ob) #creates and bakes the object motion
+
+       if ob.getType() == ARMATURE:
+#      error('Object baked. Continue with bones?')
+                       bakeBones(ob,myob) #go into the bones and copy from -> to in frame range
+       #future idea: bakeMesh (net result of Shapekeys, Softbody, Cloth, Fluidsim,...)
+                               
+       return
+               
+########################################
+def tstCreateArm(): #create a test armature in scene
+       # rip-off from http://www.blender.org/documentation/245PythonDoc/Pose-module.html - thank you!
+
+       debug(0,'Making Test Armature')
+       # New Armature
+       arm_data= Armature.New('myArmature')
+       print arm_data
+       arm_ob = scn.objects.new(arm_data)
+       arm_data.makeEditable()
+
+       # Add 4 bones
+       ebones = [Armature.Editbone(), Armature.Editbone(), Armature.Editbone(), Armature.Editbone()]
+
+       # Name the editbones
+       ebones[0].name = 'Bone.001'
+       ebones[1].name = 'Bone.002'
+       ebones[2].name = 'Bone.003'
+       ebones[3].name = 'Bone.004'
+
+       # Assign the editbones to the armature
+       for eb in ebones:
+               arm_data.bones[eb.name]= eb
+
+       # Set the locations of the bones
+       ebones[0].head= Mathutils.Vector(0,0,0)
+       ebones[0].tail= Mathutils.Vector(0,0,1) #tip
+       ebones[1].head= Mathutils.Vector(0,0,1)
+       ebones[1].tail= Mathutils.Vector(0,0,2)
+       ebones[2].head= Mathutils.Vector(0,0,2)
+       ebones[2].tail= Mathutils.Vector(0,0,3)
+       ebones[3].head= Mathutils.Vector(0,0,3)
+       ebones[3].tail= Mathutils.Vector(0,0,4)
+
+       ebones[1].parent= ebones[0]
+       ebones[2].parent= ebones[1]
+       ebones[3].parent= ebones[2]
+
+       arm_data.update()
+       # Done with editing the armature
+
+       # Assign the pose animation
+       arm_pose = arm_ob.getPose()
+
+       act = arm_ob.getAction()
+       if not act: # Add a pose action if we dont have one
+               act = Armature.NLA.NewAction()
+               act.setActive(arm_ob)
+
+       xbones=arm_ob.data.bones.values()
+       pbones = arm_pose.bones.values()
+
+       frame = 1
+       for pbone in pbones: # set bones to no rotation
+                                       pbone.quat[:] = 1.000,0.000,0.000,0.0000
+                                       pbone.insertKey(arm_ob, frame, Object.Pose.ROT)
+
+       # Set a different rotation at frame 25
+       pbones[0].quat[:] = 1.000,0.1000,0.2000,0.20000
+       pbones[1].quat[:] = 1.000,0.6000,0.5000,0.40000
+       pbones[2].quat[:] = 1.000,0.1000,0.3000,0.40000
+       pbones[3].quat[:] = 1.000,-0.2000,-0.3000,0.30000
+
+       frame = 25
+       for i in xrange(4):
+               pbones[i].insertKey(arm_ob, frame, Object.Pose.ROT)
+
+       pbones[0].quat[:] = 1.000,0.000,0.000,0.0000
+       pbones[1].quat[:] = 1.000,0.000,0.000,0.0000
+       pbones[2].quat[:] = 1.000,0.000,0.000,0.0000
+       pbones[3].quat[:] = 1.000,0.000,0.000,0.0000
+
+       frame = 50      
+       for pbone in pbones: # set bones to no rotation
+               pbone.quat[:] = 1.000,0.000,0.000,0.0000
+               pbone.insertKey(arm_ob, frame, Object.Pose.ROT)
+
+       return arm_ob
+
+########################################
+def tstMoveOb(ob): # makes a simple LocRot animation of object in the scene
+       anim = [
+               #Loc      Rot/10
+               #
+               ( 0,0,0, 0, 0, 0), #frame 1 origin
+               ( 1,0,0, 0, 0, 0), #frame 2
+               ( 1,1,0, 0, 0, 0),
+               ( 1,1,1, 0, 0, 0),
+               ( 1,1,1,4.5,  0,  0),
+               ( 1,1,1,4.5,4.5,  0),
+               ( 1,1,1,4.5,4.5,4.5)
+               ]
+       space = COORD_LOCAL
+       ipo = createIpo(ob) #create an Ipo and curves for this object
+       ipos = getCurves(ipo)
+       
+       # span this motion over the currently set anim range
+       # to set points, i need time but do not know how it is computed, so will have to advance the animation
+       staframe,endframe,curframe = getRenderInfo()
+
+       frame = staframe #x position of new ipo datapoint. set to staframe if you want a match
+       frameDelta=(endframe-staframe)/(len(anim)) #accomplish the animation in frame range
+       for key in anim: #effectively does a getLocRot()
+               #tell Blender to advace to frame
+               Blender.Set('curframe',frame) # computes the constrained location of the 'real' objects
+               time = Blender.Get('curtime')
+
+               ipos = addPoint(time,key,ipos) #add this data at this time to the ipos
+
+               debug(100,'%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f' % (ipo.name, frame, time, key[0], key[1], key[2], key[3], key[4], key[5]))
+               frame += frameDelta
+       Blender.Set('curframe',curframe) # reset back to where we started
+       return
+#=================
+# Program Template
+#=================
+########################################
+def main():
+       # return code set via rt button in Blender Buttons Scene Context Anim panel
+       
+       if MODE == 1: #create test armature #1
+               ob = tstCreateArm()      # make test arm and select it
+               tstMoveOb(ob)
+               scn.objects.selected = [ob]
+
+       obs = Blender.Object.GetSelected() #scn.objects.selected
+       debug(20,'Baking %i objects' % len(obs))
+
+       if len(obs) >= 1:   # user might have multiple objects selected
+               for ob in obs:
+                       bake(ob)
+       else:
+               error('Please select at least one object')
+       return
+
+########################################
+def benchmark(): # This lets you benchmark (time) the script's running duration 
+       
+       Window.WaitCursor(1) 
+       t = sys.time() 
+       debug(60,'%s began at %.0f' %(__script__,sys.time()))
+
+       # Run the function on the active scene
+       in_editmode = Window.EditMode()
+       if in_editmode: Window.EditMode(0)
+
+       main() 
+
+       if in_editmode: Window.EditMode(1)
+       
+       # Timing the script is a good way to be aware on any speed hits when scripting 
+       debug(60,'%s Script finished in %.2f seconds' % (__script__,sys.time()-t) )
+       Window.WaitCursor(0) 
+       return
+
+########################################
+# This lets you can import the script without running it 
+if __name__ == '__main__': 
+       debug(0, "------------------------------------")
+       debug(0, '%s %s Script begins with mode=%i debug=%i batch=%s version=%i' % (__script__,__version__,MODE,DEBUG,BATCH,BLENDER_VERSION))
+
+       benchmark()
index d0b41dc35c5f7d7288d0a7d54c2017ac6b5d17bd..63df02d080ca8672e9c82fc76b74405d0c24f1a0 100644 (file)
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# Version History:
+#   1.0 original release bakes an armature into a matrix
+#   1.1 optional params (ACTION_BAKE, ACTION_BAKE_FIRST_FRAME, direct function to key and return the Action
 
 import Blender
+from Blender import sys
 import bpy
-def getBakedPoseData(ob_arm, start_frame, end_frame):
+def getBakedPoseData(ob_arm, start_frame, end_frame, ACTION_BAKE = False, ACTION_BAKE_FIRST_FRAME = True):
        '''
        If you are currently getting IPO's this function can be used to
-       return a list of frame aligned bone dictionary's
+       ACTION_BAKE==False: return a list of frame aligned bone dictionary's
+       ACTION_BAKE==True: return an action with keys aligned to bone constrained movement
+       if ACTION_BAKE_FIRST_FRAME is not supplied or is true: keys begin at frame 1
        
        The data in these can be swaped in for the IPO loc and quat
        
@@ -77,7 +83,13 @@ def getBakedPoseData(ob_arm, start_frame, end_frame):
        
        # --------------------------------- Main loop to collect IPO data
        frame_index = 0
+       NvideoFrames= end_frame-start_frame
        for current_frame in xrange(start_frame, end_frame+1):
+               if   frame_index==0: start=sys.time()
+               elif frame_index==15: print NvideoFrames*(sys.time()-start),"seconds estimated..." #slows as it grows *3
+               elif frame_index >15:
+                       percom= frame_index*100/NvideoFrames
+                       print "Frame %i Overall %i percent complete\r" % (current_frame, percom),
                ob_arm.action = backup_action
                #pose.update() # not needed
                Blender.Set('curframe', current_frame)
@@ -88,9 +100,7 @@ def getBakedPoseData(ob_arm, start_frame, end_frame):
                
                for index, parent_index, bone_name, rest_bone, rest_matrix, rest_matrix_inv, pose_bone, ipo in armature_bone_data:
                        matrix= pose_bone.poseMatrix
-                       
                        parent_bone= rest_bone.parent
-                       
                        if parent_index != -1:
                                parent_pose_matrix =            armature_bone_data[parent_index][6].poseMatrix
                                parent_bone_matrix_inv =        armature_bone_data[parent_index][5]
@@ -98,40 +108,45 @@ def getBakedPoseData(ob_arm, start_frame, end_frame):
                                rest_matrix=                            rest_matrix * parent_bone_matrix_inv
                        
                        matrix=matrix * rest_matrix.copy().invert()
-                       
                        pose_bone.quat= matrix.toQuat()
                        pose_bone.loc=  matrix.translationPart()
-                       pose_bone.insertKey(ob_arm, 1, POSE_XFORM) # always frame 1
-                       
-                       # THIS IS A BAD HACK! IT SUCKS BIGTIME BUT THE RESULT ARE NICE
-                       # - use a temp action and bake into that, always at the same frame
-                       #   so as not to make big IPO's, then collect the result from the IPOs
+                       if ACTION_BAKE==False:
+                               pose_bone.insertKey(ob_arm, 1, POSE_XFORM) # always frame 1
+        
+                               # THIS IS A BAD HACK! IT SUCKS BIGTIME BUT THE RESULT ARE NICE
+                               # - use a temp action and bake into that, always at the same frame
+                               #   so as not to make big IPO's, then collect the result from the IPOs
                        
-                       # Now get the data from the IPOs
-                       if not ipo:     ipo = armature_bone_data[index][7] = new_action.getChannelIpo(bone_name)
+                               # Now get the data from the IPOs
+                               if not ipo:     ipo = armature_bone_data[index][7] = new_action.getChannelIpo(bone_name)
                        
-                       loc = Vector()
-                       quat  = Quaternion()
+                               loc = Vector()
+                               quat  = Quaternion()
                        
-                       for curve in ipo:
-                               val = curve.evaluate(1)
-                               curve_name= curve.name
-                               if   curve_name == 'LocX':  loc[0] = val
-                               elif curve_name == 'LocY':  loc[1] = val
-                               elif curve_name == 'LocZ':  loc[2] = val
-                               elif curve_name == 'QuatW': quat[3]  = val
-                               elif curve_name == 'QuatX': quat[0]  = val
-                               elif curve_name == 'QuatY': quat[1]  = val
-                               elif curve_name == 'QuatZ': quat[2]  = val
+                               for curve in ipo:
+                                       val = curve.evaluate(1)
+                                       curve_name= curve.name
+                                       if   curve_name == 'LocX':  loc[0] = val
+                                       elif curve_name == 'LocY':  loc[1] = val
+                                       elif curve_name == 'LocZ':  loc[2] = val
+                                       elif curve_name == 'QuatW': quat[3]  = val
+                                       elif curve_name == 'QuatX': quat[0]  = val
+                                       elif curve_name == 'QuatY': quat[1]  = val
+                                       elif curve_name == 'QuatZ': quat[2]  = val
                        
-                       bake_data[frame_index][bone_name] = loc, quat
-                       
-               
+                               bake_data[frame_index][bone_name] = loc, quat
+                       else:
+                               if ACTION_BAKE_FIRST_FRAME: pose_bone.insertKey(ob_arm, frame_index+1,  POSE_XFORM)
+                               else:           pose_bone.insertKey(ob_arm, current_frame , POSE_XFORM)
                frame_index+=1
-       
+       print "\nBaking Complete."
        ob_arm.action = backup_action
-       Blender.Set('curframe', backup_frame)
-       return bake_data
+       if ACTION_BAKE==False:
+               Blender.Set('curframe', backup_frame)
+               return bake_data
+       elif ACTION_BAKE==True:
+               return new_action
+       else: print "ERROR: Invalid ACTION_BAKE %i sent to BPyArmature" % ACTION_BAKE
 
 
 
diff --git a/release/scripts/c3d_import.py b/release/scripts/c3d_import.py
new file mode 100644 (file)
index 0000000..d67d562
--- /dev/null
@@ -0,0 +1,1237 @@
+#!BPY
+
+"""
+Name: 'Motion Capture  (.c3d)...'
+Blender: 246
+Group: 'Import'
+Tooltip: 'Import a C3D Motion Capture file'
+"""
+__script__ = "C3D Motion Capture file import"
+__author__ = " Jean-Baptiste PERIN, Roger D. Wickes (rogerwickes@yahoo.com)"
+__version__ = "0.8"
+__url__ = ["Communicate problems and errors, BlenderArtists.org, Python forum"]
+__email__= ["rogerwickes@yahoo.com", "c3d script"]
+__bpydoc__ = """\
+c3d_import.py v0.8
+
+Script loading Graphics Lab Motion Capture file,  
+Usage:<br>
+ - Run the script <br>
+ - Choose the file to open<br>
+ - Press Import C3D button<br>
+
+Version History:
+ 0.4: PERIN Released under Blender Artistic Licence
+ 0.5: WICKES used marker names, fixed 2.45 depricated call
+ 0.6: WICKES creates armature for each subject
+ 0.7: WICKES constrains armature to follow the empties (markers). Verified for shake hands s
+ 0.8: WICKES resolved DEC support issue
+"""
+
+#----------------------------------------------
+# (c) Jean-Baptiste PERIN  december 2005, released under Blender Artistic Licence
+#    for the Blender 2.40 Python Scripts Bundle.
+#----------------------------------------------
+
+######################################################
+# This script imports a C3D file into blender. 
+# Loader is based on MATLAB C3D loader from
+# Alan Morris, Toronto, October 1998
+# Jaap Harlaar, Amsterdam, april 2002
+######################################################
+
+import string
+import Blender
+from Blender import *
+import bpy
+import struct
+import BPyMessages
+Vector= Blender.Mathutils.Vector
+Euler= Blender.Mathutils.Euler
+Matrix= Blender.Mathutils.Matrix
+RotationMatrix = Blender.Mathutils.RotationMatrix
+TranslationMatrix= Blender.Mathutils.TranslationMatrix
+
+#=================
+# Global Variables, Constants, Defaults, and Shorthand References
+#=================
+# set senstitivity for displaying debug/console messages. 0=few, 100=max, including clicks at major steps
+# debug(num,string) to conditionally display status/info in console window
+DEBUG=Blender.Get('rt')
+
+# marker sets known in the world
+HUMAN_CMU= "HumanRTKm.mkr" # The Human Real-Time capture marker set used by CMU
+HUMAN_CMU2="HumanRT.mkr" # found in another file, seems same as others in that series
+MARKER_SETS = [ HUMAN_CMU, HUMAN_CMU2 ] # marker sets that this program supports (can make an armature for)
+XYZ_LIMIT= 10000 #max value for coordinates if in integer format
+
+# what layers to put stuff on in scene. 1 is selected, so everything goes there
+# selecting only layer 2 shows only the armature moving, 12 shows only the empties
+LAYERS_ARMOB= [1,2]
+LAYERS_MARKER=[1,12]
+CLEAN=True # Should program ignore markers at (0,0,0) and beyond the outer limits?
+
+scn = Blender.Scene.GetCurrent()
+# Why on earth would you rename a scene when importing data??? - Campbell
+# scn.name="MoCap" #may want this enterable or derived based on motion being analyzed
+#TODO: ultimately, a library of motions to append from means you need good naming of things
+
+BCS=Blender.Constraint.Settings # shorthand dictionary - define with brace, reference with bracket
+trackto={"+x":BCS.TRACKX, "+y":BCS.TRACKY, "+z":BCS.TRACKZ, "-x":BCS.TRACKNEGX, "-y":BCS.TRACKNEGY, "-z":BCS.TRACKNEGZ}
+trackup={"x":BCS.UPX, "y":BCS.UPY, "z":BCS.UPZ}
+
+#=============================#
+# Classes 
+#=============================#
+class Marker:
+       def __init__(self, x, y, z):
+               self.x=0.0
+               self.y=0.0
+               self.z=0.0
+
+       def __repr__(self): #report on self, as in if just printed
+               return str("[x = "+str(self.x) +" y = " + str(self.y)+" z = "+ str(self.z)+"]")
+
+class ParameterGroup:
+       def __init__(self, nom, description, parameter):
+               self.name = nom
+               self.description = description
+               self.parameter = parameter
+
+       def __repr__(self):
+               return self.name, " ", self.description, " ", self.parameter
+
+class Parameter:
+       def __init__(self, name, datatype, dim, data, description):
+               self.name = name
+               self.datatype = datatype
+               self.dim = dim
+               self.data = data
+               self.description = description
+               def __repr__(self):
+                       return self.name, " ", self.description, " ", self.dim
+
+class MyVector:
+       def __init__(self, fx,fy,fz):
+               self.x=fx
+               self.y=fy
+               self.z=fz
+
+class Mybone:
+       "information structure for bone generation and posing"
+       def __init__(self, name,vec,par,head,tail,const):
+               self.name=name      # name of this bone. must be unique within armature
+               self.vec=vec         # edit bone vector it points
+               self.parent=par     # name of parent bone to locate head and form a chain
+               self.headMark=head  # list of 0+ markers where the head of this non-parented bone should be placed
+               self.tailMark=tail  # list of 0+ markers where the tip should be placed
+               self.const=const    # list of 0+ constraint tuples to control posing
+               self.head=MyVector(0,0,0) #T-pose location
+               self.tail=MyVector(0,0,0)
+       def __repr__(self):
+               return '[Mybone "%s"]' % self.name
+
+
+#=============================#
+# functions/modules 
+#=============================#
+def error(str):
+       Draw.PupMenu('ERROR%t|'+str)
+       return
+def status(str):
+       Draw.PupMenu('STATUS%t|'+str+"|Continue?")
+       return
+def debug(num,msg): #use log4j or just console here.
+       if DEBUG >= num:
+                                       print 'debug:', (' '*num), msg
+       #TODO: if level 0, make a text file in Blender file to record major stuff
+       return
+
+def names(ob): return ob.name
+
+
+#########
+# Cette fonction renvoie la liste des empties
+# in  : 
+# out : emp_list (List of Object) la liste des objets de type "Empty"
+#########
+def getEmpty(name):
+       obs = [ob for ob in scn.objects if ob.type=="Empty" and ob.name==name]
+       if len(obs)==0:
+               return None
+       elif len(obs)==1:
+               return obs[0]
+       else:
+               error("FATAL ERROR: %i empties %s in file" % (len(obs),ob[0]))
+#########
+# Cette fonction renvoie un empty 
+# in  : objname : le nom de l'empty recherche
+# out : myobj : l'empty cree ou retrouve
+#########
+def GetOrCreateEmpty(objname):
+       myobj= getEmpty(objname)
+       if myobj==None: 
+               myobj = scn.objects.new("Empty",objname)
+               myobj.layers= LAYERS_MARKER
+               debug(50,'Marker/Empty created %s' %  myobj)
+       return myobj
+
+def GetOrCreateCurve(ipo, curvename):
+       """
+       Retrieve or create a Blender Ipo Curve named C{curvename} in the C{ipo} Ipo
+
+       >>> import mylib 
+
+       >>> lIpo = GetOrCreateIPO("Une IPO")
+       >>> laCurve = GetOrCreateCurve(lIpo, "RotX")
+
+       Either an ipo curve named C{curvename} exists before the call then this curve is returned,
+       Or such a curve doesn't exist before the call .. then it is created into the c{ipo} Ipo and returned 
+
+       @type  ipo: Blender Ipo
+       @param ipo: the Ipo in which the curve must be retrieved or created.
+       @type  curvename: string
+       @param curvename: name of the IPO.
+       @rtype:   Blender Curve
+       @return:  a Blender Curve named C{curvename} in the C{ipo} Ipo 
+       """
+       try:
+               mycurve = ipo.getCurve(curvename)
+               if mycurve != None:
+                       pass
+               else:
+                       mycurve = ipo.addCurve(curvename)
+       except:
+               mycurve = ipo.addCurve(curvename)
+       return mycurve
+
+def eraseIPO (objectname):
+       object = Blender.Object.Get(objectname)
+       lIpo = object.getIpo()
+       if lIpo != None:
+               nbCurves = lIpo.getNcurves()
+               for i in range(nbCurves):
+                       nbBezPoints = lIpo.getNBezPoints(i)
+                       for j in range(nbBezPoints):
+                               lIpo.delBezPoint(i)
+
+def comp_loc(emptyNameList):
+       myloc=Vector(0,0,0)
+       for emName in emptyNameList:
+               myobj = Blender.Object.Get(emName)
+               for i in range(3):
+                       myloc[i]= myloc[i]+(myobj.loc[i]/len(emptyNameList)) #take the average loc of all marks
+       return myloc
+
+def comp_len(head, tail): # computes the length of a bone
+       headvec=comp_loc(head)
+       tailvec=comp_loc(tail)
+       netvec=headvec-tailvec
+       return netvec.length
+
+def createHumanCMU(): # human bone structure, makes a node set for CMU MoCap Lab
+       # order of bones: "spine","chest","neck","head",...face toward you in front view
+       # pose constraints are tuples of (type,target,influence,other-as-needed)
+       # constraint stack order is important. for proper bone pointing and orinetation:
+       #  IK, then TT +YZ in world space. then LR XZ to 0 in world space, this points the bone, twists it, but then
+       # limits the rotation to the sidebar enpty with the Z facing it, and Y pointing along the bone.
+       nodes=[]        # bonename, vector, parent, head targets, tail targets, constraint list
+       for i in range(23): nodes.append(Mybone("name","vec","par",[],[],[]))
+       nodes[0]= Mybone("root", "-Y","",["RBWT", "LBWT"],["RFWT", "LFWT", "RBWT", "LBWT"],[("LOC","RBWT",1.0),("LOC","LBWT",0.5),("IK","RFWT",1.0),("IK","LFWT",0.5),("TT","RBWT",1,"+YZ"),("LR","XZ",1)])
+       nodes[1]= Mybone("spine","+Z","root",[],["STRN","T10"],[("IK","STRN",1.0),("IK","T10",0.5),("TT","STRN",1,"+YZ"),("LR","XZ",1)])
+       nodes[2]= Mybone("chest","+Z","spine",[],["CLAV","C7"],[("IK","CLAV",1.0),("IK","C7",0.5),("TT","CLAV",1,"+YZ"),("LR","XZ",1)])
+       nodes[3]= Mybone("neck", "+Z","chest",[],["RBHD","LBHD"],[("IK","RBHD",1.0),("IK","LBHD",0.5),("TT","LBHD",1,"+YZ"),("LR","XZ",1)])
+       nodes[4]= Mybone("head" ,"-Y","neck",[],["RFHD","LFHD"],[("IK","RFHD",1.0),("IK","LFHD",0.5),("TT","LFHD",1,"+YZ"),("LR","XZ",1)])
+       
+       nodes[5]= Mybone("shoulder.R","-X","chest",[],["RSHO"],[("IK","RSHO",1.0)])
+       nodes[6]= Mybone("toparm.R",  "-X","shoulder.R",[],["RELB"],[("IK","RELB",1.0),("TT","RUPA",1,"+YZ"),("LR","XZ",1)])
+       nodes[7]= Mybone("lowarm.R",  "-X","toparm.R",[],["RWRA","RWRB"],[("IK","RWRA",1.0),("IK","RWRB",0.5),("TT","RFRM",1,"+YZ"),("LR","XZ",1)])
+       nodes[8]= Mybone("hand.R",    "-X","lowarm.R",[],["RFIN"],[("IK","RFIN",1.0),("TT","RWRA",1,"+YZ"),("LR","XZ",1)])  #missing ,"RTHM"
+
+       nodes[9]= Mybone("hip.R",   "-X","root",[],["RFWT","RBWT"],[("IK","RFWT",1.0),("IK","RBWT",0.5)])
+       nodes[10]=Mybone("topleg.R","-Z","hip.R",[],["RKNE"],[("IK","RKNE",1),("TT","RTHI",1,"+YZ"),("LR","XZ",1)])
+       nodes[11]=Mybone("lowleg.R","-Z","topleg.R",[],["RANK","RHEE"],[("IK","RHEE",1.0),("TT","RSHN",1,"+YZ"),("LR","XZ",1)])
+       nodes[12]=Mybone("foot.R",  "-Y","lowleg.R",[],["RTOE","RMT5"],[("IK","RTOE",1.0),("IK","RMT5",0.2),("TT","RMT5",1,"+YZ")])
+       nodes[13]=Mybone("toes.R",  "-Y","foot.R",[],["RTOE"],[("IK","RTOE",1.0)])
+       
+       nodes[14]=Mybone("shoulder.L","+X","chest",[],["LSHO"],[("IK","LSHO",1.0)])
+       nodes[15]=Mybone("toparm.L",  "+X","shoulder.L",[],["LELB"],[("IK","LELB",1.0),("TT","LUPA",1,"+YZ"),("LR","XZ",1)])
+       nodes[16]=Mybone("lowarm.L",  "+X","toparm.L",[],["LWRA","LWRB"],[("IK","LWRA",1.0),("IK","LWRB",0.5),("TT","LFRM",1,"+YZ"),("LR","XZ",1)])
+       nodes[17]=Mybone("hand.L",    "+X","lowarm.L",[],["LFIN"],[("IK","LFIN",1.0),("TT","RWRA",1,"+YZ"),("LR","XZ",1)]) #missing ,"LTHM"
+       
+       nodes[18]=Mybone("hip.L",   "+X","root",[],["LFWT","LBWT"],[("IK","LFWT",1.0),("IK","LBWT",0.5)])
+       nodes[19]=Mybone("topleg.L","-Z","hip.L",[],["LKNE"],[("IK","LKNE",1),("TT","LTHI",1,"+YZ"),("LR","XZ",1)])
+       nodes[20]=Mybone("lowleg.L","-Z","topleg.L",[],["LANK","LHEE"],[("IK","LHEE",1.0),("TT","LSHN",1,"+YZ"),("LR","XZ",1)])
+       nodes[21]=Mybone("foot.L",  "-Y","lowleg.L",[],["LTOE","LMT5"],[("IK","LTOE",1.0),("IK","LMT5",0.2),("TT","LMT5",1,"+YZ"),("LR","XZ",1)])
+       nodes[22]=Mybone("toes.L",  "-Y","foot.L",[],["LTOE"],[("IK","LTOE",1.0)])
+       return nodes
+
+def createNodes(marker_set): # make a list of bone name, parent, edit head loc, edit tail loc, pose constraints
+       #ultimately, I want to read in an XML file here that specifies the node trees for various marker sets
+       if   marker_set==HUMAN_CMU:  nodes= createHumanCMU() #load up and verify the file has the CMU marker set
+       elif marker_set==HUMAN_CMU2: nodes= createHumanCMU()
+       else: nodes=[]
+       return nodes
+def findEntry(item,list):
+       for i in range(len(list)):
+               if item==list[i]: break
+       debug(100,"findEtnry %s is %i in list of %i items" % (item,i,len(list)))
+       return i
+def makeNodes(prefix, markerList, empties, marker_set): #make sure the file has the nodes selected
+       nodes= createNodes(marker_set)  # list has generic marker names; replace them with the actual object names created
+       #each entry in markerlist has a corresponding entry in empties in the same order
+       errList=[]
+       for i in range(len(nodes)):
+               node= nodes[i]
+               debug(60,"Adapting node %s to prefix %s" % (node,prefix))
+
+               #replace generic head markers with actual empty names
+               for im in range(len(node.headMark)):
+                       marker= node.headMark[im]
+                       mark= prefix+marker
+                       imn= findEntry(mark,markerList)
+                       if imn < len(markerList):
+                               debug(90,"Adapating head marker %s to %s" % (marker,empties[imn].name))
+                               nodes[i].headMark[im]= empties[imn].name
+                       else: errList.append([node.name,"head location",mark,node,2])
+               #replace generic tail markers with actual empty names
+               for im in range(len(node.tailMark)):
+                       marker= node.tailMark[im]
+                       mark= prefix+marker
+                       imn= findEntry(mark,markerList)
+                       if imn < len(markerList):
+                               debug(90,"Adapating  marker %s to %s" % (marker,empties[imn].name))
+                               nodes[i].tailMark[im]= empties[imn].name
+                       else: errList.append([node.name,"tail location",mark,node,2])
+                       
+               #replace generic constraint markers (if the constraint references a marker) with empty name
+               for im in range(len(node.const)):
+                       const=node.const[im]
+                       if const[0] in ("LOC","IK","TT"):
+                               marker=const[1]
+                               mark= prefix+marker
+                               imn= findEntry(mark,markerList)
+                               if imn < len(markerList):
+                                       debug(90,"Adapating %s constraint marker %s to %s" % (const[0],marker,empties[imn].name))
+                                       if const[0] in ("IK","LR","LOC"):
+                                               nodes[i].const[im]=(const[0], empties[imn].name, const[2])
+                                       else: nodes[i].const[im]=(const[0], empties[imn].name, const[2], const[3])
+                               else: errList.append([node.name,const[0]+" constraint",mark,node,4])
+                       
+       if errList!=[]: #we have issues. 
+               for err in errList:
+                       debug(0,"Bone "+err[0]+" specifies "+err[2]+" as "+err[1]+"which was not specified in file.")
+                       #need a popup here to ignore/cleanup node tree, or add the marker(?) or abort
+                       usrOption= 1
+                       if usrOption==0: #ignore this marker (remove it)
+                               for node in nodes: #find the bone in error
+                                       if node.name==err[0]:
+                                               print "Before",node
+                                               if err[3] in range(2,3):
+                                                       node[err[3]].remove(err[2]) #find the marker in error and remove it
+                                               elif err[3]==4: #find the constraint and remove it
+                                                       for const in node.const:
+                                                               if const[1]==err[2]: node.const.remove(const)
+                                               print "After",node
+                       elif usrOption==1: #add these markers as static empties, and user will automate them later
+                               #and the bones will be keyed to them, so it will all be good.
+                               #file may have just mis-named the empty, or the location can be derived based on other markers
+                               em= GetOrCreateEmpty(err[2])
+                       else: abort() #abend
+                       if DEBUG==100: status("Nodes Updated")
+       return nodes #nodes may be updated
+
+def makeBones(arm,nodes): 
+       debug(20,"Making %i edit bones" % len(nodes))
+       for node in nodes:
+               bone= Blender.Armature.Editbone()
+               bone.name= node.name
+               arm.bones[bone.name]= bone #add it to the armature
+               debug(50,"Bone added: %s" % bone)
+               if bone.name <> node.name:
+                       debug(0,"ERROR: duplicate node % name specified" % node.name)
+                       node.name= bone.name #you may not get what you asked for
+               if node.parent!="": #parent
+                       debug(60,"Bone parent: %s"%node.parent)
+                       bone.parent= arm.bones[node.parent]
+                       bone.options = [Armature.CONNECTED]
+               #compute head = average of the reference empties
+               if node.headMark==[]: # no head explicitly stated, must be tail of parent
+                       for parnode in nodes:
+                               if node.parent==parnode.name: break
+                       node.headMark= parnode.tailMark
+                       node.head= parnode.tail
+               else: node.head= comp_loc(node.headMark) #node head is specified, probably only for root.
+
+               bone.head= node.head
+               debug(60,"%s bone head: (%0.2f, %0.2f, %0.2f)" % (bone.name,bone.head.x, bone.head.y, bone.head.z))
+               mylen=comp_len(node.headMark,node.tailMark) # length of the bone as it was recorded for that person
+               # for our T position, compute the bone length, add it to the head vector component to get the tail
+               if node.vec[0]=="-": mylen=-mylen
+               debug(80,"Bone vector %s length %0.2f" %(node.vec,mylen))
+               node.tail= Vector(node.head)
+               myvec=node.vec[1].lower()
+               if   myvec=="x": node.tail.x+=mylen
+               elif myvec=="y": node.tail.y+=mylen
+               elif myvec=="z": node.tail.z+=mylen
+               else:
+                       debug(0,"%s %s %s %s" % (node.vec,myvec,node.vec[0],node.vec[1]))
+                       error("ERROR IN BONE SPEC ")
+               bone.tail= node.tail
+               debug(60,"Bone tail: (%i,%i,%i)" %(bone.tail.x, bone.tail.y, bone.tail.z))
+       #Armature created in the T postion, but with bone lengths to match the marker set and subject
+               #when this is constrained to the markers, the recorded action will be relative to a know Rotation
+               #so that all recorded actions should be interchangeable. wooot!
+               #Only have to adjust starting object loc when matching up actions.
+       return #arm #updated
+
+def makeConstLoc(pbone,const):
+       const_new= pbone.constraints.append(Constraint.Type.COPYLOC)
+       const_new.name = const[0]+"-"+const[1]
+       const_target=Blender.Object.Get(const[1])
+       const_new[BCS.TARGET]= const_target
+       const_new.influence = const[2]
+       return
+                               
+def makeConstLimRot(pbone,const):
+       const_new= pbone.constraints.append(Constraint.Type.LIMITROT)
+       const_new.name = const[0]+"-"+const[1]
+       for axis in const[1]:
+               if axis.lower()=="x": const_new[BCS.LIMIT] |= BCS.LIMIT_XROT #set
+               if axis.lower()=="y": const_new[BCS.LIMIT] |= BCS.LIMIT_YROT #set
+               if axis.lower()=="z": const_new[BCS.LIMIT] |= BCS.LIMIT_ZROT #set
+       const_new[BCS.OWNERSPACE]= BCS.SPACE_LOCAL
+       const_new.influence = const[2]
+       # fyi, const[Constraint.Settings.LIMIT] &= ~Constraint.Settings.LIMIT_XROT #reset
+       return
+                               
+def makeConstIK(prefix,pbone,const):
+       #Blender 246 only supports one IK Solver per bone, but we might want many,
+       #  so we need to create a reference empty named after the bone
+       #  that floats between the markers, so the bone can point to it as a singularity
+       myob= GetOrCreateEmpty(prefix+pbone.name)
+       # note that this empty gets all the IK constraints added on
+       myconst= myob.constraints.append(Constraint.Type.COPYLOC)
+       myconst.name=const[0]+"-"+const[1]
+       myconst[Constraint.Settings.TARGET]= Blender.Object.Get(const[1])
+       myconst.influence = const[2]
+       
+       #point the bone once to the empty via IK
+       success=False
+       for myconst in pbone.constraints:
+               if myconst.type == Constraint.Type.IKSOLVER: success=True
+       if not(success): #add an IK constraint to the bone to point to the empty
+               #print pbone
+               myconst= pbone.constraints.append(Constraint.Type.IKSOLVER)
+               myconst.name = const[1]
+               myconst[BCS.TARGET]= myob
+               myconst.influence = const[2]
+               #const_new[Constraint.Settings.BONE]= ?
+               myconst[BCS.CHAINLEN]= 1
+               myconst[BCS.USETIP]= True
+               myconst[BCS.STRETCH]= False
+               return
+                                       
+def makeConstTT(pbone,const):
+       myconst= pbone.constraints.append(Constraint.Type.TRACKTO)
+       myconst.name=const[0]+"-"+const[1]
+       debug(70,"%s %s" % (myconst,const[3]))
+       myob= GetOrCreateEmpty(const[1])
+       myconst[BCS.TARGET]= myob
+       myconst.influence = const[2]
+       #const[3] is the Track and the thrird char is the Up indicator
+       myconst[BCS.TRACK]= trackto[const[3][0:2].lower()]
+       myconst[BCS.UP]=trackup[const[3][2].lower()]#up direction
+       myconst[BCS.OWNERSPACE]= BCS.SPACE_LOCAL
+       myconst[BCS.TARGETSPACE]= [BCS.SPACE_LOCAL]
+       if const[3][1]==const[3][2]: debug(0,"WARNING: Track To axis and up axis should not be the same. Constraint is INACTIVE")
+       return
+
+def makePoses(prefix,arm_ob,nodes): # pose this armature object based on node requirements
+       #this is constraint-based posing, not hard-keyed posing.
+       #we do constraint-based first so that user can adjust the constraints, possibly smooth/tweak motion
+       #  add additional bones or referneces/constraints, before baking to hard keyframes
+
+       pose= arm_ob.getPose()
+       debug(0,"Posing %s %s" % (arm_ob, pose))
+       for node in nodes:
+               debug(30, "examining %s" %node)
+               if len(node.const)>0: #constraints for this bone are desired
+                       pbone = pose.bones[node.name]
+                       debug(40,"Posing bone %s" %pbone)
+                       for const in node.const:
+                               debug(50,"Constraining %s by %s" %(pbone,const))
+                               if   const[0]=="LOC":makeConstLoc(pbone,const)
+                               elif const[0]=="IK": makeConstIK(prefix,pbone,const)
+                               elif const[0]=="LR": makeConstLimRot(pbone,const)  
+                               elif const[0]=="TT": makeConstTT(pbone,const)
+                               else: 
+                                       error("FATAL: constraint %s not supported" %const[0])
+                                       break
+       debug(10, "Posing complete. Cycling pose and edit mode")
+       pose.update()
+       return
+
+def make_arm(subject,prefix,markerList, emptyList,marker_set):
+       debug(10,"**************************")
+       debug(00, "**** Making Armature for %s..." % subject)
+       debug(10, "**************************")
+       # copied from bvh import bvh_node_dict2armature; trying to use similar process for further integtration down the road
+       # Add the new armature,
+       
+       nodes= makeNodes(prefix, markerList, emptyList, marker_set) #assume everyone in file uses the same mocap suit
+       # each person in the file may be different height, so each needs their own new armature to match marker location
+
+##  obs= Blender.Object.Get()
+##  success=False
+##  for ob in obs:
+##    if ob.name==subject:
+##      success=True
+##  if success:
+##    menu="Human Armature already exists for this subject."
+##    menu+="%t|Create another in this scene"
+##    menu+="%l|Start a new scene"
+##    menu+="%l|Use this armature"
+##    menusel= Draw.PupMenu(menu)
+       
+       arm= Blender.Armature.New(subject) #make an armature.
+       debug(10,"Created Armature %s" % arm)
+       # Put us into editmode
+       arm.makeEditable()
+       arm.drawType = Armature.OCTAHEDRON
+       makeBones(arm,nodes)
+       scn = Blender.Scene.GetCurrent() #add it to the current scene. could create new scenes here as yaf
+       arm_ob= scn.objects.new(arm) #instance it in the scene. this is the new way for 2.46 to instance objects
+       arm_ob.name= subject #name it something like the person it represents
+       arm_ob.layers= LAYERS_ARMOB
+       debug(20,"Instanced Armature %s" % arm_ob)
+       arm.update() #exit editmode. Arm must be instanced as an object before you can save changes or pose it
+       Blender.Redraw() # show the world
+       if DEBUG==100: status("T-Bones made.")
+
+       makePoses(prefix,arm_ob,nodes) #constrain arm_ob with these markers
+       
+       scn.update(1) #make everyone behave themselves in the scene, and respect the new constraints
+       return arm_ob
+
+def setupAnim(StartFrame, EndFrame, VideoFrameRate):
+       debug(100, 'VideoFrameRate is %i' %VideoFrameRate)
+       if VideoFrameRate<1: VideoFrameRate=1
+       if VideoFrameRate>120: VideoFrameRate=120
+       # set up anim panel for them
+       context=scn.getRenderingContext() 
+       context.startFrame(StartFrame)
+       context.endFrame(EndFrame)
+       context.framesPerSec(int(VideoFrameRate))
+       Blender.Set("curframe",StartFrame)
+       Blender.Redraw()
+       return
+
+def makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers):
+       debug(10, "**************************")
+       debug(00, "*** Making Cloud Formation")
+       debug(10, "**************************")
+       empties=[]
+       ipos=[]
+       curvesX=[]
+       curvesY=[]
+       curvesZ=[]
+       debug(0, "%i Markers (empty cloud) will be put on layers %s" % (Nmarkers,LAYERS_MARKER))
+       # Empty Cloud formation
+       for i in range(Nmarkers):
+               debug(100,"%i marker %s"%(i, markerList[i]))
+               emptyname = markerList[i] # rdw: to use meaningful names from Points parameter
+               em= GetOrCreateEmpty(emptyname) #in this scene
+               #make a list of the actual empty
+               empties.append(em)
+               #assign it an ipo with the loc xyz curves
+               lipo = Ipo.New("Object",em.name)
+               ipos.append(lipo)
+               curvesX.append(GetOrCreateCurve(ipos[i],'LocX'))
+               curvesY.append(GetOrCreateCurve(ipos[i],'LocY'))
+               curvesZ.append(GetOrCreateCurve(ipos[i],'LocZ'))
+               empties[i].setIpo(ipos[i])
+       debug(30,"Cloud of %i empties created." % len(empties))
+       NvideoFrames= EndFrame-StartFrame+1
+       debug(10, "**************************")
+       debug(00, "**** Calculating Marker Ipo Curves over %i Frames ..." % NvideoFrames)
+       debug(10, "**************************")
+       err= index=0 #number of errors, logical frame
+       for frame in range(StartFrame,EndFrame+1):
+               if   index==0:   start=sys.time()
+               elif index==100:
+                       tmp=(NvideoFrames-100)*(sys.time()-start)/6000
+                       debug(0,"%i minutes process time estimated" % tmp)
+               elif index >100: print index*100/(NvideoFrames-1),"% complete\r",
+               for i in range(Nmarkers):
+                       if Markers[index][i].z < 0: Markers[index][i].z= -Markers[index][i].z
+                       success=True
+                       if CLEAN:   #check for good data
+                               # C3D marker decoding may have coordinates negative (improper sign bit decoding?)
+                               myX= abs(Markers[index][i].x)
+                               myY= abs(Markers[index][i].y)
+                               myZ= Markers[index][i].z
+                               if myX > 10000 or myY > 10000 or myZ > 10000: success=False
+                               if myX <.01 and myY <.01 and myZ <.01: success=False # discontinuity in marker tracking (lost marker)
+                       
+                       if success:
+                               curvesX[i].append((frame, Markers[index][i].x)) #2.46 knot method
+                               curvesY[i].append((frame, Markers[index][i].y))
+                               curvesZ[i].append((frame, Markers[index][i].z))
+                               if frame==StartFrame: debug(40, "%s loc frame %i: (%0.2f, %0.2f, %0.2f)" % (markerList[i],frame,Markers[index][i].x,Markers[index][i].y,Markers[index][i].z))
+                       else:
+                               err+=1 # some files have thousands...
+                               #debug(30,"Point ignored for marker:%s frame %i: (%i, %i, %i)" %       (markerList[i],frame,Markers[index][i].x,Markers[index][i].y,Markers[index][i].z))
+               index += 1
+       debug(70, "%i points ignored across all markers and frames. Recalculating..." % err)
+
+       for i in range(Nmarkers):
+               curvesX[i].Recalc()
+               curvesY[i].Recalc()
+               curvesZ[i].Recalc()
+       Blender.Set('curframe', StartFrame)
+       Blender.Redraw()
+       if DEBUG==100: status("Clound formed")
+       return empties
+
+def getNumber(str, length):
+               if length==2: # unsigned short
+                       return struct.unpack('H',str[0:2])[0], str[2:]
+               sum = 0
+               for i in range(length):
+                               #sum = (sum << 8) + ord(str[i]) for big endian
+                               sum = sum + ord(str[i])*(2**(8*i))
+               return sum, str[length:]
+def unpackFloat(chunk,proctype):
+               #print proctype
+               myvar=chunk[0:4]
+               if   proctype==2: #DEC-VAX
+                       myvar=chunk[2:4]+chunk[0:2] #swap lo=hi word order pair
+               return struct.unpack('f',myvar[0:4])[0]
+               
+def getFloat(chunk,proctype):
+               return unpackFloat(chunk, proctype), chunk[4:]
+def parseFloat(chunk,ptr,proctype):
+       return unpackFloat(chunk[ptr:ptr+4], proctype), ptr+4
+
+def load_c3d(FullFileName):
+# Input:        FullFileName - file (including path) to be read
+#
+# Variable:
+# Markers            3D-marker data [Nmarkers x NvideoFrames x Ndim(=3)]
+# VideoFrameRate     Frames/sec
+# AnalogSignals      Analog signals [Nsignals x NanalogSamples ]
+# AnalogFrameRate    Samples/sec
+# Event              Event(Nevents).time ..value  ..name
+# ParameterGroup     ParameterGroup(Ngroups).Parameters(Nparameters).data ..etc.
+# CameraInfo         MarkerRelated CameraInfo [Nmarkers x NvideoFrames]
+# ResidualError      MarkerRelated ErrorInfo  [Nmarkers x NvideoFrames]
+
+       Markers=[];
+       VideoFrameRate=120;
+       AnalogSignals=[];
+       AnalogFrameRate=0;
+       Event=[];
+       ParameterGroups=[];
+       CameraInfo=[];
+       ResidualError=[];
+
+       debug(10, "*********************")
+       debug(10, "**** Opening File ***")
+       debug(10, "*********************")
+
+       #ind=findstr(FullFileName,'\');
+       #if ind>0, FileName=FullFileName(ind(length(ind))+1:length(FullFileName)); else FileName=FullFileName; end
+       debug(0, "FileName = " + FullFileName)
+       fid=open(FullFileName,'rb'); # native format (PC-intel). ideasman says maybe rU
+       content = fid.read();
+       content_memory = content
+       #Header  section
+       NrecordFirstParameterblock, content = getNumber(content,1)     # Reading record number of parameter section
+
+       key, content = getNumber(content,1)
+       if key!=80:
+               error('File: does not comply to the C3D format')
+               fid.close()
+               return
+       #Paramter section
+       content = content[512*(NrecordFirstParameterblock-1)+1:] # first word ignored
+       #file format spec says that  3rd byte=NumberofParmaterRecords... but is ignored here.
+       proctype,content =getNumber(content,1)
+       proctype = proctype-83
+       proctypes= ["unknown","(INTEL-PC)","(DEC-VAX)","(MIPS-SUN/SGI)"]
+       
+       if proctype in (1,2): debug(0, "Processor coding %s"%proctypes[proctype])
+       elif proctype==3: debug(0,"Program untested with %s"%proctypes[proctype])
+       else:
+               debug(0, "INVALID processor type %i"%proctype)
+               proctype=1
+               debug(0,"OVERRIDE processor type %i"%proctype)
+
+       #if proctype==2,
+       #    fclose(fid);
+       #    fid=fopen(FullFileName,'r','d'); % DEC VAX D floating point and VAX ordering
+       #end
+       debug(10, "***********************")
+       debug(00, "**** Reading Header ***")
+       debug(10, "***********************")
+
+       # ###############################################
+       # ##                                           ##
+       # ##    read header                            ##
+       # ##                                           ##
+       # ###############################################
+
+       #%NrecordFirstParameterblock=fread(fid,1,'int8');     % Reading record number of parameter section
+       #%key1=fread(fid,1,'int8');                           % key = 80;
+
+       content = content_memory
+ #fseek(fid,2,'bof');
+       content = content[2:]
+
+       #
+       Nmarkers, content=getNumber(content, 2)
+       NanalogSamplesPerVideoFrame, content = getNumber(content, 2)
+       StartFrame,  content = getNumber(content, 2)
+       EndFrame,  content = getNumber(content, 2)
+       MaxInterpolationGap,  content = getNumber(content, 2)
+
+       Scale, content = getFloat(content,proctype)
+       
+       NrecordDataBlock,  content = getNumber(content, 2)
+       NanalogFramesPerVideoFrame,  content = getNumber(content, 2)
+
+       if NanalogFramesPerVideoFrame > 0:
+               NanalogChannels=NanalogSamplesPerVideoFrame/NanalogFramesPerVideoFrame
+       else:
+               NanalogChannels=0
+
+       VideoFrameRate, content = getFloat(content,proctype)
+
+       AnalogFrameRate=VideoFrameRate*NanalogFramesPerVideoFrame
+       NvideoFrames = EndFrame - StartFrame + 1
+
+       debug(0, "Scale= %0.2f" %Scale)
+       debug(0, "NanalogFramesPerVideoFrame= %i" %NanalogFramesPerVideoFrame)
+       debug(0, "Video Frame Rate= %i" %VideoFrameRate)
+       debug(0, "AnalogFrame Rate= %i"%AnalogFrameRate)
+       debug(0, "# markers= %i" %Nmarkers)
+       debug(0, "StartFrame= %i" %StartFrame)
+       debug(0, "EndFrame= %i" %EndFrame)
+       debug(0, "# Video Frames= %i" %NvideoFrames)
+       
+       if Scale>0:
+               debug(0, "Marker data is in integer format")
+               if Scale>(XYZ_LIMIT/32767):
+                       Scale=XYZ_LIMIT/32767.0
+                       debug(0, "OVERRIDE: Max coordinate is %i, Scale changed to %0.2f" % (XYZ_LIMIT,Scale))
+       else: debug(0, "Marker data is in floating point format")
+       if VideoFrameRate<1 or VideoFrameRate>120:
+               VideoFrameRate= 120
+               debug(0, "OVERRIDE Video Frame Rate= %i" %VideoFrameRate)
+       if proctype not in (1,2): # Intel, DEC are known good
+               debug(0, "OVERRIDE|Program not tested with this encoding. Set to Intel")
+               proctype= 1
+
+       debug(10, "***********************")
+       debug(10, "**** Reading Events ...")
+       debug(10, "***********************")
+
+       content = content_memory
+       content = content[298:] #bizarre .. ce devrait ĂȘtre 150 selon la doc rdw skips first 299 bytes?
+
+       EventIndicator,  content = getNumber(content, 2)
+       EventTime=[]
+       EventValue=[]
+       EventName=[]
+
+       debug(0, "Event Indicator = %i" %EventIndicator)
+       if EventIndicator==12345: #rdw: somehow, this original code seems fishy, but I cannot deny it.
+               Nevents,  content = getNumber(content, 2)
+               debug(0, "Nevents= %i" %Nevents)
+               content = content[2:]
+               if Nevents>0:
+                       for i in range(Nevents):
+                               letime, content = getFloat(content,proctype)
+                               EventTime.append(letime)
+                       content = content_memory
+                       content = content[188*2:]
+                       for i in range(Nevents):
+                               lavalue, content = getNumber(content, 1)
+                               EventValue.append(lavalue)
+                       content = content_memory
+                       content = content[198*2:]
+                       for i in range(Nevents):
+                               lenom = content[0:4]
+                               content = content[4:]
+                               EventName.append(lenom)
+
+       debug(00, "***************************")
+       debug(00, "**** Reading Parameters ...")
+       debug(10, "***************************")
+       subjects=[]  # a name would be nice, but human will do
+       prefixes=[] # added on to mocap marker names, one for each subject
+       marker_subjects = [] # hopefully will be specified in the file and known to this program
+       markerList=[]
+       ParameterGroups = []
+       ParameterNumberIndex = []
+       
+       content = content_memory
+       content = content[512*(NrecordFirstParameterblock-1):] 
+
+       dat1, content = getNumber(content, 1)
+       key2, content = getNumber(content, 1)
+
+       NparameterRecords, content = getNumber(content, 1)
+       debug(100, "NparameterRecords=%i"%NparameterRecords)
+       proctype,content =getNumber(content,1)
+       proctype = proctype-83                 # proctype: 1(INTEL-PC); 2(DEC-VAX); 3(MIPS-SUN/SGI)
+
+       for i in range(NparameterRecords):
+               leparam = ParameterGroup(None, None, [])
+               ParameterGroups.append(leparam)
+               ParameterNumberIndex.append(0)
+       #
+       Ncharacters, content = getNumber(content, 1)
+       if Ncharacters>=128:
+               Ncharacters = -(2**8)+(Ncharacters)
+       GroupNumber, content = getNumber(content, 1)
+       if GroupNumber>=128:
+               GroupNumber = -(2**8)+(GroupNumber)
+       debug(80,"GroupNumber = %i, Nchar=%i" %(GroupNumber,Ncharacters))
+
+       while Ncharacters > 0:
+               if GroupNumber<0:
+                       GroupNumber=abs(GroupNumber)
+                       GroupName = content[0:Ncharacters]
+                       content = content[Ncharacters:]
+                       #print "Group Number = ", GroupNumber
+                       ParameterGroups[GroupNumber].name = GroupName
+                       #print "ParameterGroupName =", GroupName
+                       offset, content = getNumber(content, 2)
+                       deschars, content = getNumber(content, 1)
+                       GroupDescription = content[0:deschars]
+                       content = content[deschars:]
+                       ParameterGroups[GroupNumber].description = GroupDescription
+                       #
+                       ParameterNumberIndex[GroupNumber]=0
+                       content = content[offset-3-deschars:]
+               else:
+                       
+                       ParameterNumberIndex[GroupNumber]=ParameterNumberIndex[GroupNumber]+1
+                       ParameterNumber=ParameterNumberIndex[GroupNumber]
+                       #print "ParameterNumber=", ParameterNumber
+                       ParameterGroups[GroupNumber].parameter.append(Parameter(None, None, [], [], None))
+                       ParameterName = content[0:Ncharacters]
+                       content = content[Ncharacters:]
+                       #print "ParameterName = ",ParameterName 
+                       if len(ParameterName)>0:
+                               ParameterGroups[GroupNumber].parameter[ParameterNumber-1].name=ParameterName
+                       offset, content = getNumber(content, 2)
+                       filepos = len(content_memory)-len(content)
+                       nextrec = filepos+offset-2
+
+                       type, content=getNumber(content, 1)
+                       if type>=128:
+                               type = -(2**8)+type
+                       ParameterGroups[GroupNumber].parameter[ParameterNumber-1].type=type
+
+                       dimnum, content=getNumber(content, 1)
+                       if dimnum == 0:
+                               datalength = abs(type)
+                       else:
+                               mult=1
+                               dimension=[]
+                               for j in range (dimnum):
+                                       ladim, content = getNumber(content, 1)
+                                       dimension.append(ladim)
+                                       mult=mult*dimension[j]
+                                       ParameterGroups[GroupNumber].parameter[ParameterNumber-1].dim.append(dimension[j])
+                               datalength = abs(type)*mult
+
+                       #print "ParameterNumber = ", ParameterNumber, " Group Number = ", GroupNumber
+
+                       if type==-1:
+                               data = ""
+                               wordlength=dimension[0]
+                               if dimnum==2 and datalength>0:
+                                       for j in range(dimension[1]):
+                                               data=string.rstrip(content[0:wordlength])
+                                               content = content[wordlength:]
+                                               ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data.append(data)
+                               elif dimnum==1 and datalength>0:
+                                               data=content[0:wordlength]
+                                               ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data.append(data) # ???
+
+                               myParam=string.rstrip(ParameterName)
+                               myGroup=string.rstrip(GroupName)
+                               msg= "-%s-%s-" % (myGroup,myParam)
+                               if myGroup == "POINT":
+                                       if myParam== "LABELS":
+                                               # named in form of subject:marker.
+                                               # the list "empties" is a corresponding list of actual empty object names that make up the cloud
+                                               markerList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                                               debug(0, "%sLABELS = %i %s" %(msg, len(markerList),markerList)) #list of logical markers from 0 to n corresponding to points
+                                       elif myParam== "LABELS2": #more labels
+                                               # named in form of subject:marker.
+                                               # the list "empties" is a corresponding list of actual empty object names that make up the cloud
+                                               momarkList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                                               markerList+=momarkList
+                                               debug(0, "%sLABELS2 = %i %s" %(msg, len(momarkList),momarkList)) #list of logical markers from 0 to n corresponding to points
+                                       else: debug(70, "%s UNUSED = %s" %(msg,ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data))
+                               elif myGroup in ["SUBJECT", "SUBJECTS"]: #info about the actor
+                                       if myParam in ["NAME", "NAMES"]:
+                                               subjects= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                                               debug(0, "%sNames of Subjects = %s" %(msg, subjects)) # might be useful in naming armatures
+                                               for i in range(len(subjects)):
+                                                       subjects[i]=subjects[i].rstrip()
+                                                       if subjects[i]=="": subjects[i]="Human"
+                                       elif myParam == "LABEL_PREFIXES":
+                                               prefixes = ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                                               debug(0, "%sMarker Prefixes = %s" %(msg, prefixes)) # to xlate marker name to that in file
+                                               for i in range(len(prefixes)):
+                                                       prefixes[i]=prefixes[i].rstrip()
+                                       elif myParam== "MARKER_SETS":
+                                               marker_subjects= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                                               debug(0, "%sMarker Set = %s"%(msg, marker_subjects)) # marker set that each subject was wearing
+                                       elif myParam== "MODEL_PARAM":
+                                               action= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                                               debug(0, "%sModel Paramter = %s"%(msg,action)) # might be a good name for the blender scene
+                                       elif myParam== "LABELS":
+                                               # named in form of subject:marker.
+                                               # the list "empties" is a corresponding list of actual empty object names that make up the cloud
+                                               markerList= ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                                               debug(0, "%sLABELS = %i %s"%(msg, len(markerList),markerList)) #list of logical markers from 0 to n corresponding to points
+                                       else: debug(70, "%sUNUSED = %s"%(msg, ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data))
+                               else:
+                                       debug(70, "%sUNUSED = %s"%(msg, ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data))
+                       elif type == 1:
+                               debug(100,"Block type %i is largely unsupported and untested."%type)
+                               data = []
+                               Nparameters=datalength/abs(type)
+                               debug(100, "Nparameters=%i"%Nparameters)
+                               for i in range(Nparameters):
+                                       ladata,content = getNumber(content, 1)
+                                       data.append(ladata)
+                               ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
+                               #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+
+                               #print "type boolean"
+                       elif type == 2 and datalength>0:
+                               debug(100,"Block type %i is largely unsupported and untested."%type)
+                               data = []
+                               Nparameters=datalength/abs(type)
+                               debug(100, "Nparameters=%i"%Nparameters)
+                               for i in range(Nparameters):
+                                       ladata,content = getNumber(content, 2)
+                                       data.append(ladata)
+                               #ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
+                               if dimnum>1:
+                                       #???? print "arg je comprends pas"
+                                       ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
+                                       #???ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=reshape(data,dimension)
+                               else:
+                                       ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
+                               #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                               #pass
+                               #print "type integer"
+                       elif type == 4 and datalength>0:
+                               debug(100,"Block type %i is largely unsupported and untested."%type)
+                               data = []
+                               Nparameters=datalength/abs(type)
+                               debug(100, "Nparameters=%i"%Nparameters)
+                               for i in range(Nparameters):
+                                       ladata,content = getFloat(content,proctype)  
+                                       data.append(ladata)
+                               if dimnum>1:
+                                       ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
+                                       #print "arg je comprends pas"
+                                       #???ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=reshape(data,dimension)
+                               else:
+                                       ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data=data
+                               #print ParameterGroups[GroupNumber].parameter[ParameterNumber-1].data
+                       else:
+                               debug(100,"Block type %i is largely unsupported and untested."%type)
+                               #print "error"
+                               pass
+                       deschars, content= getNumber(content, 1)
+                       if deschars>0:
+                               description = content[0:deschars]
+                               content = content[deschars:]
+                               ParameterGroups[GroupNumber].parameter[ParameterNumber-1].description=description
+                       
+                       content = content_memory
+                       content = content[nextrec:] 
+
+               Ncharacters,content = getNumber(content, 1)
+               if Ncharacters>=128:
+                       Ncharacters = -(2**8)+(Ncharacters)
+               GroupNumber,content = getNumber(content, 1)
+               if GroupNumber>=128:
+                       GroupNumber = -(2**8)+(GroupNumber)
+               debug(80,"GroupNumber = %i, Nchar=%i" %(GroupNumber,Ncharacters))
+
+       debug(00, "***************************")
+       debug(00, "**** Examining Parameters ...")
+       debug(10, "***************************")
+
+       if len(subjects)==0: subjects=["Test"] #well, somebody got mocapped!
+       for i in range(0, len(subjects)-len(prefixes)): prefixes.append("")
+       for i in range(0, len(subjects)-len(marker_subjects)): marker_subjects.append(subjects[i])
+
+       #make a markerlist if they didn't
+       debug(0, "%i Markers specified, %i marker names supplied" %(Nmarkers,len(markerList)))
+       if len(markerList)==0:
+               debug(0, "File missing any POINT LABELS marker list. Making defaults")
+               #I guess just make cloud of empty.xxx
+       if len(markerList)<Nmarkers:
+               for i in range(len(markerList),Nmarkers): markerList.append("mark."+str(i))
+       #note that they may supply more markers than Nmarkers, extras are usually null or ignored
+       #an idea here to winnow down the marker List is to go through the nodes and see if there are markers
+       # in the list that are not used in constraining the armature, and discard them or set them debug(0,
+       # so that later on in processing we don't bother saving their location, possibly speeding up processing
+       # because we can just skip over their data block.
+       # put this on TODO list since it gets pretty complicated going throuch each marker set and all constraints etc.
+       
+       ## ###############################################
+       ## ##                                           ##
+       ## ##    Initalize Arrays and Allocate Memory
+       ## ##                                           ##
+       ## ###############################################
+       ##  Get the coordinate and analog data
+       #
+
+       content = content_memory
+       content = content[(NrecordDataBlock-1)*512:] 
+       debug(20,"Allocating memory for %i floats" %NvideoFrames*(Nmarkers*3+2))
+       for i in range (NvideoFrames):
+               Markers.append([])
+               ResidualError.append([])
+               CameraInfo.append([])
+               for j in range (Nmarkers):
+                       Markers[i].append(Marker(0.0,0.0,0.0))
+                       ResidualError[i].append(0)
+                       CameraInfo[i].append(0)
+
+       #print Markers
+       #
+       #if Scale < 0
+       #    for i=1:NvideoFrames
+       #        for j=1:Nmarkers
+       #            Markers(i,j,1:3)=fread(fid,3,'float32')'; 
+       #            a=fix(fread(fid,1,'float32'));  
+       #            highbyte=fix(a/256);
+       #            lowbyte=a-highbyte*256; 
+       #            CameraInfo(i,j)=highbyte; 
+       #            ResidualError(i,j)=lowbyte*abs(Scale); 
+       #        end
+       #        waitbar(i/NvideoFrames)
+       #        for j=1:NanalogFramesPerVideoFrame,
+       #            AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=...
+       #                fread(fid,NanalogChannels,'int16')';
+       #        end
+       #    end
+
+       debug(10, "***************************")
+       debug(00, "**** Reading DataBlock of %i Frames...." % NvideoFrames)
+       debug(10, "***************************")
+       residuals= NanalogFramesPerVideoFrame*NanalogChannels*2
+       err=0 #keep track of errors or serious data issues
+       ptr_read = 0
+
+       if Scale < 0.0: # 3D Data - 4-byte Floating-point Format
+               for i in range (NvideoFrames):
+                       if i==0: start=sys.time()
+                       elif i==10:
+                               tmp=(sys.time()-start)*NvideoFrames/600
+                               debug(0,"%i minutes remaining..." % tmp)
+                       else: print "%i percent complete. On Frame %i Points procesed: %i\r" % (i*100/NvideoFrames,i,i*Nmarkers),
+                       for j in range (Nmarkers):
+       
+                               x,ptr_read = parseFloat(content, ptr_read, proctype)
+                               y,ptr_read = parseFloat(content, ptr_read, proctype)
+                               z,ptr_read = parseFloat(content, ptr_read, proctype)
+                               myx= x * -Scale
+                               myy= y * -Scale
+                               myz= z * -Scale
+
+                               if abs(myx)>XYZ_LIMIT or abs(myy)>XYZ_LIMIT or abs(myz)>XYZ_LIMIT:
+                                       err+=1
+                                       if err>100:
+                                               debug(0, "Warning: 100 data points for markers seem way out there")
+                                               debug(0, "data read: (%i, %i, %i)" %(x,y,z))
+                                               debug(0, "Consider revising Scale %0.2f" % Scale)
+                                               debug(0, "which now givs coordinates: (%i, %i, %i)" %(x*Scale,y*Scale,z*Scale))
+                                               err=-0
+                                       if abs(myx)>XYZ_LIMIT: myx= XYZ_LIMIT*myx/abs(myx) #preserve sign
+                                       if abs(myy)>XYZ_LIMIT: myy= XYZ_LIMIT*myy/abs(myy) #preserve sign
+                                       if abs(myz)>XYZ_LIMIT: myz= XYZ_LIMIT*myz/abs(myz) #preserve sign
+                               Markers[i][j].x = myx
+                               Markers[i][j].y = myy
+                               Markers[i][j].z = myz 
+
+                               a,ptr_read = parseFloat(content, ptr_read, proctype)
+                               a = int(a)
+                               highbyte = int(a/256)
+                               lowbyte=a-highbyte*256
+                               CameraInfo[i][j] = highbyte
+                               ResidualError[i][j] = lowbyte*abs(Scale)
+                               #Monitor marker location to ensure data block is being parsed properly
+                               if j==0: debug(90,"Frame %i loc of %s: (%i, %i, %i)" % (i,markerList[j],myx,myy,myz))
+                               if i==0: debug(50, "Initial loc of %s: (%i, %i, %i)" % (markerList[j],myx,myy,myz))
+
+                       ptr_read+=residuals #skip over the following  
+                       #for j in range (NanalogFramesPerVideoFrame):
+                       #  for k in range(NanalogChannels):
+                       #    val, content = getNumber(content, 2)
+                       #    AnalogSignals[j+NanalogFramesPerVideoFrame*(i)][k]=val #??? i-1
+       #else
+       #    for i=1:NvideoFrames
+       #        for j=1:Nmarkers
+       #            Markers(i,j,1:3)=fread(fid,3,'int16')'.*Scale;
+       #            ResidualError(i,j)=fread(fid,1,'int8');
+       #            CameraInfo(i,j)=fread(fid,1,'int8');
+       #        end
+       #        waitbar(i/NvideoFrames)
+       #        for j=1:NanalogFramesPerVideoFrame,
+       #            AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=...
+       #                fread(fid,NanalogChannels,'int16')';
+       #        end
+       #    end
+       #end
+
+       else: #Scale is positive, but should be <1 to scale down, like 0.05
+               two16= -2**16
+               if len(content) < NvideoFrames*(Nmarkers*(6+2)+residuals):
+                       error("%i bytes is not enough data for |%i frames|%i markers|%i residual" %(len(content),NvideoFrames,Nmarkers,residuals))
+               #Note: I really tried to optimize this loop, since it was taking hours to process
+               for i in range(NvideoFrames):
+                       if i==0: start=sys.time()
+                       elif i==10:
+                               tmp=(sys.time()-start)*NvideoFrames/600
+                               debug(0,"%i minutes remaining..." % tmp)
+                       else: print "%i percent complete. On Frame %i Points procesed: %i\r" % (i*100/NvideoFrames,i,i*Nmarkers),
+                               
+                       for j in range(Nmarkers):        
+                               #x, content = getNumber(content,2)
+                               # this is old skool signed int, not but not a short.
+                               x = ord(content[ptr_read+0]) + (ord(content[ptr_read+1])<<8)
+                               if x>32768: x+=two16
+                               y = ord(content[ptr_read+2]) + (ord(content[ptr_read+3])<<8)
+                               if y>32768: y+=two16
+                               z = ord(content[ptr_read+4]) + (ord(content[ptr_read+5])<<8)
+                               if z>32768: z+=two16
+       
+##        
+##        x = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8)
+##        ptr_read+=2
+##        if x > 32768:
+##          x=-(2**16)+(x)
+##        #y, content = getNumber(content,2)
+##        y = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8)
+##        ptr_read+=2
+##        if y > 32768:
+##          y=-(2**16)+(y)
+##        #z, content = getNumber(content,2)
+##        z = ord(content[ptr_read]) + ord(content[ptr_read+1])*(2**8)
+##        ptr_read+=2
+##        if z > 32768:
+##          z=-(2**16)+(z)
+##
+##        print "(%i=%i, %i=%i, %i=%i)" %(x,myx,y,myy,z,myz)
+
+                               # for integers, I changed Scale above to avoid getting impossible numbers       
+                               Markers[i][j].x = x*Scale
+                               Markers[i][j].y = y*Scale
+                               Markers[i][j].z = z*Scale
+
+##        ResidualError[i][j], content = getNumber(content, 1)
+##        CameraInfo[i][j], content = getNumber(content, 1)
+                               #try to improve performance by:
+                               ResidualError[i][j]= ord(content[ptr_read+6])
+                               CameraInfo[i][j]= ord(content[ptr_read+7])
+                               
+                               content= content[ptr_read+8:]
+                               ptr_read=0
+
+                               if j==0: debug(100,"Frame %i loc of %s: %s" % (i,markerList[j],Markers[i][j]))
+                               if i==0: debug(50, "Initial loc of %s: (%s)" % (markerList[j],Markers[i][j]))
+                               
+                       #for j in range (NanalogFramesPerVideoFrame):
+                       #  for k in range(NanalogChannels):
+                       #    val, content = getNumber(content, 2)
+                       #AnalogSignals(j+NanalogFramesPerVideoFrame*(i-1),1:NanalogChannels)=val
+                       ptr_read= residuals # skip over the above
+       print "\ndone with file."
+       fid.close()
+
+       cloud= makeCloud(Nmarkers,markerList,StartFrame,EndFrame,Markers)
+
+       setupAnim(StartFrame, EndFrame,VideoFrameRate)
+
+       debug(10, "**************************")
+       debug(00, "**** Making %i Armatures" % len(subjects))
+       debug(10, "**************************")
+       for i in range(len(subjects)):
+               marker_set= marker_subjects[i]
+               success=False
+               if len(marker_set)>0:
+                               for trymark in MARKER_SETS: 
+                                       if trymark[0:len(marker_set)]==marker_set:
+                                               marker_set=trymark
+                                               success=True
+               if success:
+                       debug(0, "Armature for %s will be put on layers %s" % (subjects[i],LAYERS_ARMOB))
+                       debug(0, "  based on an markers beginning with %s" % prefixes[i])
+                       ob= make_arm(subjects[i],prefixes[i],markerList,cloud,marker_set)
+               else:
+                       debug(00, "Presently, this program can automatically create a constrained armature for marker sets %s" % MARKER_SETS)
+                       debug(00, "%s uses an unknown marker set %s" % (subjects[i],marker_set))
+                       debug(10, "Have a nice day! If you figure out an armature node system for this cloud, please add it to the program.")
+
+       debug(10, "**************************")
+       debug(00, "**** Conclusion")
+       minmax=[0,0,0,0,0,0]
+       for i in range(NvideoFrames):
+                       for j in range(Nmarkers):
+                               if minmax[0]>Markers[i][j].x: minmax[0]=Markers[i][j].x
+                               if minmax[1]>Markers[i][j].y: minmax[1]=Markers[i][j].y
+                               if minmax[2]>Markers[i][j].z: minmax[2]=Markers[i][j].z
+                               if minmax[3]<Markers[i][j].x: minmax[3]=Markers[i][j].x
+                               if minmax[4]<Markers[i][j].y: minmax[4]=Markers[i][j].y
+                               if minmax[5]<Markers[i][j].z: minmax[5]=Markers[i][j].z
+       debug(0,"Markers move in 3D space from (%i,%i,%i) to (%i,%i,%i). "%(minmax[0],minmax[1],minmax[2],minmax[3],minmax[4],minmax[5]))
+       debug(0,"Set your 3D View Properties Clip End and zoom out your display.")
+def my_callback(filename):
+       # processing options UI goes here, eventually
+       Window.WaitCursor(1) 
+       t = sys.time() 
+       load_c3d(filename)
+       # Timing the script is a good way to be aware on any speed hits when scripting 
+       debug(0, '%s file processed in %.2f sec.' % (filename,sys.time()-t))
+       Window.WaitCursor(0)
+                               
+def processFile():
+       # select file and pass a handle to the processor
+       Blender.Window.FileSelector(my_callback, "Import C3D") # makes a window a file selector and processes it
+       #processing contiues while file is being worked
+       
+def main(): 
+       # Display the GUI
+       
+       # Run the  function 
+       processFile()
+
+       #Close files, display stats, cleanup, advice on next steps
+
+# This lets you import the script without running it 
+if __name__ == '__main__': 
+       debug(00, "------------------------------------")
+       debug(00, '%s %s script began at %.0f' % (__script__,__version__,sys.time()))
+       main() 
+       
+
index 922f320134578b1bb39225bb6b49e4330ded83ae..5b209cb8f5b80838d71f4a486618936271e76f05 100644 (file)
 #ifndef BKE_IPO_H
 #define BKE_IPO_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct CfraElem {
        struct CfraElem *next, *prev;
        float cfra;
@@ -111,5 +115,9 @@ float IPO_GetFloatValue(struct Ipo *ipo,
                                                short c,
                                                float ctime);
 
+#ifdef __cplusplus
+};
+#endif
+
 #endif
 
index 05f2e69fce1bb34f2cc66a66e74e1f2900bb8a12..5b96bf110566cecceb0fb21dba124d84ec07a60e 100644 (file)
@@ -350,7 +350,7 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
        pchan->flag= chan->flag;
        
        con= chan->constraints.first;
-       for(pcon= pchan->constraints.first; pcon; pcon= pcon->next) {
+       for(pcon= pchan->constraints.first; pcon; pcon= pcon->next, con= con->next) {
                pcon->enforce= con->enforce;
                pcon->headtail= con->headtail;
        }
index b2557c9c07efb4248381d6016fa347c98183e975..c73279746fb909110661db33a6a12c677b3e2c72 100644 (file)
@@ -857,8 +857,8 @@ void BKE_add_image_extension(char *string, int imtype)
                        extension= ".bmp";
        }
        else if(G.have_libtiff && (imtype==R_TIFF)) {
-               if(!BLI_testextensie(string, ".tif"))
-                       extension= ".tif";
+               if(!BLI_testextensie(string, ".tif") && 
+                       !BLI_testextensie(string, ".tiff")) extension= ".tif";
        }
 #ifdef WITH_OPENEXR
        else if( ELEM(imtype, R_OPENEXR, R_MULTILAYER)) {
index 321d4f1d37e0b23d53c66446a4ff5e7f2dc49706..59eb3837aab9b01b71292961c8b01eb615a77eed 100644 (file)
@@ -1859,7 +1859,7 @@ void set_icu_vars(IpoCurve *icu)
                /* yafray: aperture & focal distance params */
                switch(icu->adrcode) {
                case CAM_LENS:
-                       icu->ymin= 5.0;
+                       icu->ymin= 1.0;
                        icu->ymax= 1000.0;
                        break;
                case CAM_STA:
index 561a97d86463c9d8c03513dc055a3e65d08d87a5..d3cc451c6fc4cdeb12a9011845103d425927117e 100644 (file)
@@ -1424,10 +1424,10 @@ void vertgroup_flip_name (char *name, int strip_number)
 }
 
 static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
-                                  Object *ob,
-       DerivedMesh *dm,
-       int initFlags,
-       int axis)
+               Object *ob,
+               DerivedMesh *dm,
+               int initFlags,
+               int axis)
 {
        int i;
        float tolerance = mmd->tolerance;
@@ -1436,7 +1436,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
        int maxVerts = dm->getNumVerts(dm);
        int maxEdges = dm->getNumEdges(dm);
        int maxFaces = dm->getNumFaces(dm);
-       int vector_size, j, a, b;
+       int vector_size=0, j, a, b;
        bDeformGroup *def, *defb;
        bDeformGroup **vector_def = NULL;
        int (*indexMap)[2];
@@ -1465,7 +1465,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
 
        if (mmd->mirror_ob) {
                float obinv[4][4];
-
+               
                Mat4Invert(obinv, mmd->mirror_ob->obmat);
                Mat4MulMat4(mtx, ob->obmat, obinv);
                Mat4Invert(imtx, mtx);
@@ -1476,16 +1476,16 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                MVert *mv = CDDM_get_vert(result, numVerts);
                int isShared;
                float co[3];
-
+               
                dm->getVert(dm, i, &inMV);
-
+               
                VecCopyf(co, inMV.co);
-
+               
                if (mmd->mirror_ob) {
                        VecMat4MulVecfl(co, mtx, co);
                }
                isShared = ABS(co[axis])<=tolerance;
-
+               
                /* Because the topology result (# of vertices) must be the same if
                * the mesh data is overridden by vertex cos, have to calc sharedness
                * based on original coordinates. This is why we test before copy.
@@ -1493,10 +1493,10 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                DM_copy_vert_data(dm, result, i, numVerts, 1);
                *mv = inMV;
                numVerts++;
-
+               
                indexMap[i][0] = numVerts - 1;
                indexMap[i][1] = !isShared;
-
+               
                if(isShared) {
                        co[axis] = 0;
                        if (mmd->mirror_ob) {
@@ -1508,33 +1508,33 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                } else {
                        MVert *mv2 = CDDM_get_vert(result, numVerts);
                        MDeformVert *dvert = NULL;
-
+                       
                        DM_copy_vert_data(dm, result, i, numVerts, 1);
                        *mv2 = *mv;
-
+                       
                        co[axis] = -co[axis];
                        if (mmd->mirror_ob) {
                                VecMat4MulVecfl(co, imtx, co);
                        }
                        VecCopyf(mv2->co, co);
-
+                       
                        if (mmd->flag & MOD_MIR_VGROUP){
                                dvert = DM_get_vert_data(result, numVerts, CD_MDEFORMVERT);
-
+                               
                                if (dvert)
                                {
                                        for(j = 0; j < dvert[0].totweight; ++j)
                                        {
                                                char tmpname[32];
-
+                                               
                                                if(dvert->dw[j].def_nr < 0 ||
                                                   dvert->dw[j].def_nr >= vector_size)
                                                        continue;
-
+                                               
                                                def = vector_def[dvert->dw[j].def_nr];
                                                strcpy(tmpname, def->name);
                                                vertgroup_flip_name(tmpname,0);
-
+                                               
                                                for(b = 0, defb = ob->defbase.first; defb;
                                                    defb = defb->next, b++)
                                                {
@@ -1547,7 +1547,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                                        }
                                }
                        }
-
+                       
                        numVerts++;
                }
        }
@@ -1555,25 +1555,25 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
        for(i = 0; i < maxEdges; i++) {
                MEdge inMED;
                MEdge *med = CDDM_get_edge(result, numEdges);
-
+               
                dm->getEdge(dm, i, &inMED);
-
+               
                DM_copy_edge_data(dm, result, i, numEdges, 1);
                *med = inMED;
                numEdges++;
-
+               
                med->v1 = indexMap[inMED.v1][0];
                med->v2 = indexMap[inMED.v2][0];
                if(initFlags)
                        med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
-
+               
                if(indexMap[inMED.v1][1] || indexMap[inMED.v2][1]) {
                        MEdge *med2 = CDDM_get_edge(result, numEdges);
-
+                       
                        DM_copy_edge_data(dm, result, i, numEdges, 1);
                        *med2 = *med;
                        numEdges++;
-
+                       
                        med2->v1 += indexMap[inMED.v1][1];
                        med2->v2 += indexMap[inMED.v2][1];
                }
@@ -1582,13 +1582,13 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
        for(i = 0; i < maxFaces; i++) {
                MFace inMF;
                MFace *mf = CDDM_get_face(result, numFaces);
-
+               
                dm->getFace(dm, i, &inMF);
-
+               
                DM_copy_face_data(dm, result, i, numFaces, 1);
                *mf = inMF;
                numFaces++;
-
+               
                mf->v1 = indexMap[inMF.v1][0];
                mf->v2 = indexMap[inMF.v2][0];
                mf->v3 = indexMap[inMF.v3][0];
@@ -1600,15 +1600,15 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                                 || (mf->v4 && indexMap[inMF.v4][1])) {
                        MFace *mf2 = CDDM_get_face(result, numFaces);
                        static int corner_indices[4] = {2, 1, 0, 3};
-
+                       
                        DM_copy_face_data(dm, result, i, numFaces, 1);
                        *mf2 = *mf;
-
+                       
                        mf2->v1 += indexMap[inMF.v1][1];
                        mf2->v2 += indexMap[inMF.v2][1];
                        mf2->v3 += indexMap[inMF.v3][1];
                        if(inMF.v4) mf2->v4 += indexMap[inMF.v4][1];
-
+                       
                        /* mirror UVs if enabled */
                        if(mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V)) {
                                MTFace *tf = result->getFaceData(result, numFaces, CD_MTFACE);
@@ -1622,14 +1622,14 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
                                        }
                                }
                        }
-
+                       
                        /* Flip face normal */
                        SWAP(int, mf2->v1, mf2->v3);
                        DM_swap_face_data(result, numFaces, corner_indices);
-
+                       
                        test_index_face(mf2, &result->faceData, numFaces, inMF.v4?4:3);
                        numFaces++;
-                                }
+               }
        }
 
        if (vector_def) MEM_freeN(vector_def);
@@ -1644,8 +1644,8 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
 }
 
 static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
-                                            Object *ob, DerivedMesh *dm,
-         int initFlags)
+                                           Object *ob, DerivedMesh *dm,
+                                               int initFlags)
 {
        DerivedMesh *result = dm;
 
index f06ef22179596cfe7e0799b4096cbb9ce02f2d78..458171cc2329cd668d67df44d67bf2bff286dc66 100644 (file)
@@ -2596,6 +2596,7 @@ static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemMo
        
        for(ec= lb->first; ec; ec= ec->next) {
                PartDeflect *pd= ec->ob->pd;
+               co = NULL;
                
                if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE 
                        && part->phystype!=PART_PHYS_BOIDS) {
index 92544f1972130631fa2f34ef6e2a88924d3825aa..16ca5d7542db42169204d9b9a537e333c3a03b66 100644 (file)
@@ -465,6 +465,9 @@ void init_actuator(bActuator *act)
     case ACT_PARENT:
         act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
         break;
+       case ACT_STATE:
+        act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
+        break;
        default:
                ; /* this is very severe... I cannot make any memory for this        */
                /* logic brick...                                                    */
index 876547042dcef06c3445545e6d318b93068859d7..53b7bb975a3fac812709970cbbaf7587588dcd3e 100644 (file)
@@ -942,7 +942,8 @@ char *txt_to_buf (Text *text)
        if (!text) return NULL;
        if (!text->curl) return NULL;
        if (!text->sell) return NULL;
-               
+       if (!text->lines.first) return NULL;
+
        linef= text->lines.first;
        charf= 0;
                
index 4d277cf98e1a590cd4117c35b62f43e4bdadf61a..4fa880c36d1744937f05c36d1b27ff7d2229f058 100644 (file)
@@ -374,6 +374,7 @@ void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3
 void tubemap(float x, float y, float z, float *u, float *v);
 void spheremap(float x, float y, float z, float *u, float *v);
 
+int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3]);
 int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
 int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
 int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);
index 322a9e6fd028e037ddf8abf32ef3feace5ce3b84..2084ab3da5faf5c438b9834cb7d0a96bfe75ae40 100644 (file)
@@ -4032,6 +4032,74 @@ int AxialLineIntersectsTriangle(int axis, float p1[3], float p2[3], float v0[3],
        return 1;
 }
 
+/* Returns the number of point of interests
+ * 0 - lines are colinear
+ * 1 - lines are coplanar, i1 is set to intersection
+ * 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively 
+ * */
+int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3])
+{
+       float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
+       float d;
+       
+       VecSubf(c, v3, v1);
+       VecSubf(a, v2, v1);
+       VecSubf(b, v4, v3);
+
+       VecCopyf(dir1, a);
+       Normalize(dir1);
+       VecCopyf(dir2, b);
+       Normalize(dir2);
+       d = Inpf(dir1, dir2);
+       if (d == 1.0f || d == -1.0f) {
+               /* colinear */
+               return 0;
+       }
+
+       Crossf(ab, a, b);
+       d = Inpf(c, ab);
+
+       /* test if the two lines are coplanar */
+       if (d > -0.000001f && d < 0.000001f) {
+               Crossf(cb, c, b);
+
+               VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
+               VecAddf(i1, v1, a);
+               VecCopyf(i2, i1);
+               
+               return 1; /* one intersection only */
+       }
+       /* if not */
+       else {
+               float n[3], t[3];
+               float v3t[3], v4t[3];
+               VecSubf(t, v1, v3);
+
+               /* offset between both plane where the lines lies */
+               Crossf(n, a, b);
+               Projf(t, t, n);
+
+               /* for the first line, offset the second line until it is coplanar */
+               VecAddf(v3t, v3, t);
+               VecAddf(v4t, v4, t);
+               
+               VecSubf(c, v3t, v1);
+               VecSubf(a, v2, v1);
+               VecSubf(b, v4t, v3);
+
+               Crossf(ab, a, b);
+               Crossf(cb, c, b);
+
+               VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
+               VecAddf(i1, v1, a);
+
+               /* for the second line, just substract the offset from the first intersection point */
+               VecSubf(i2, i1, t);
+               
+               return 2; /* two nearest points */
+       }
+} 
+
 int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3])
 {
        return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&
index fa7cbb06139a0d1d186317fd7b991e2343f1a83e..9cfce5e34fa02a0d6298fa6fa79eeeca004b93d6 100644 (file)
@@ -3011,6 +3011,9 @@ static void lib_link_object(FileData *fd, Main *main)
                                        bParentActuator *parenta = act->data; 
                                        parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob);
                                }
+                               else if(act->type==ACT_STATE) {
+                                       /* bStateActuator *statea = act->data; */
+                               }
                                act= act->next;
                        }
 
@@ -3307,11 +3310,19 @@ static void direct_link_object(FileData *fd, Object *ob)
        direct_link_constraints(fd, &ob->constraints);
 
        link_glob_list(fd, &ob->controllers);
+       if (ob->init_state) {
+               /* if a known first state is specified, set it so that the game will start ok */
+               ob->state = ob->init_state;
+       } else if (!ob->state) {
+               ob->state = 1;
+       }
        cont= ob->controllers.first;
        while(cont) {
                cont->data= newdataadr(fd, cont->data);
                cont->links= newdataadr(fd, cont->links);
                test_pointer_array(fd, (void **)&cont->links);
+               if (cont->state_mask == 0)
+                       cont->state_mask = 1;
                cont= cont->next;
        }
 
@@ -7635,6 +7646,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
+
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
index 2595b95bbf0e2fd9b62e28ab34e1c77e6dfd11b0..9f28e13ff7b9d7991f085accc015dc7e76e91f7e 100644 (file)
@@ -715,6 +715,9 @@ static void write_actuators(WriteData *wd, ListBase *lb)
                case ACT_PARENT:
                        writestruct(wd, DATA, "bParentActuator", 1, act->data);
                        break;
+               case ACT_STATE:
+                       writestruct(wd, DATA, "bStateActuator", 1, act->data);
+                       break;
                default:
                        ; /* error: don't know how to write this file */
                }
index 94203bab44798383211790a7c3f8d9e19ab101f1..73ef83393b02234adfda0c77f66974018803ab47 100644 (file)
@@ -149,6 +149,7 @@ typedef enum {
 #define IB_zbuffloat   (1 << 16)
 #define IB_multilayer  (1 << 17)
 #define IB_imginfo             (1 << 18)
+#define IB_animdeinterlace      (1 << 19)
 
 /*
  * The bit flag is stored in the ImBuf.ftype variable.
index 71d3594983329ac3cb0515c9ee1615d0abb1cced..7dc1f966b71b950edb40ac60c6abb97066c6b9c3 100644 (file)
@@ -183,8 +183,9 @@ struct anim {
        AVFormatContext *pFormatCtx;
        AVCodecContext *pCodecCtx;
        AVCodec *pCodec;
-       AVFrame *pFrameRGB;
        AVFrame *pFrame;
+       AVFrame *pFrameRGB;
+       AVFrame *pFrameDeinterlaced;
        struct SwsContext *img_convert_ctx;
        int videoStream;
 #endif
index 87d67f5263b898ada39e8a511bb86faad7c63c9b..720f5b0f7c8d0bc967424642274a1af88d33c5fd 100644 (file)
@@ -600,6 +600,7 @@ static int startffmpeg(struct anim * anim) {
        anim->videoStream = videoStream;
 
        anim->pFrame = avcodec_alloc_frame();
+       anim->pFrameDeinterlaced = avcodec_alloc_frame();
        anim->pFrameRGB = avcodec_alloc_frame();
 
        if (avpicture_get_size(PIX_FMT_BGR32, anim->x, anim->y)
@@ -609,10 +610,20 @@ static int startffmpeg(struct anim * anim) {
                avcodec_close(anim->pCodecCtx);
                av_close_input_file(anim->pFormatCtx);
                av_free(anim->pFrameRGB);
+               av_free(anim->pFrameDeinterlaced);
                av_free(anim->pFrame);
                return -1;
        }
 
+       if (anim->ib_flags & IB_animdeinterlace) {
+               avpicture_fill((AVPicture*) anim->pFrameDeinterlaced, 
+                              MEM_callocN(avpicture_get_size(
+                                                  anim->pCodecCtx->pix_fmt,
+                                                  anim->x, anim->y), 
+                                          "ffmpeg deinterlace"), 
+                              anim->pCodecCtx->pix_fmt, anim->x, anim->y);
+       }
+
        if (pCodecCtx->has_b_frames) {
                anim->preseek = 25; /* FIXME: detect gopsize ... */
        } else {
@@ -638,12 +649,13 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
        AVPacket packet;
        int64_t pts_to_search = 0;
        int pos_found = 1;
+       int filter_y = 0;
 
        if (anim == 0) return (0);
 
        ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0);
 
-       avpicture_fill((AVPicture *)anim->pFrameRGB, 
+       avpicture_fill((AVPicture*) anim->pFrameRGB, 
                       (unsigned char*) ibuf->rect, 
                       PIX_FMT_BGR32, anim->x, anim->y);
 
@@ -722,6 +734,32 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
                        } 
 
                        if(frameFinished && pos_found == 1) {
+                               AVFrame * input = anim->pFrame;
+
+                               /* This means the data wasnt read properly, 
+                                  this check stops crashing */
+                               if (input->data[0]==0 && input->data[1]==0 
+                                   && input->data[2]==0 && input->data[3]==0){
+                                       av_free_packet(&packet);
+                                       break;
+                               }
+
+                               if (anim->ib_flags & IB_animdeinterlace) {
+                                       if (avpicture_deinterlace(
+                                                   (AVPicture*) 
+                                                   anim->pFrameDeinterlaced,
+                                                   (const AVPicture*)
+                                                   anim->pFrame,
+                                                   anim->pCodecCtx->pix_fmt,
+                                                   anim->pCodecCtx->width,
+                                                   anim->pCodecCtx->height)
+                                           < 0) {
+                                               filter_y = 1;
+                                       } else {
+                                               input = anim->pFrameDeinterlaced;
+                                       }
+                               }
+
                                if (G.order == B_ENDIAN) {
                                        int * dstStride 
                                                = anim->pFrameRGB->linesize;
@@ -735,8 +773,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
                                        unsigned char* top;
 
                                        sws_scale(anim->img_convert_ctx,
-                                                 anim->pFrame->data,
-                                                 anim->pFrame->linesize,
+                                                 input->data,
+                                                 input->linesize,
                                                  0,
                                                  anim->pCodecCtx->height,
                                                  dst2,
@@ -793,27 +831,25 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
                                        int i;
                                        unsigned char* r;
                                        
-                                       /* This means the data wasnt read properly, this check stops crashing */
-                                       if (anim->pFrame->data[0]!=0 || anim->pFrame->data[1]!=0 || anim->pFrame->data[2]!=0 || anim->pFrame->data[3]!=0) {
                                                
-                                               sws_scale(anim->img_convert_ctx,
-                                                         anim->pFrame->data,
-                                                         anim->pFrame->linesize,
-                                                         0,
-                                                         anim->pCodecCtx->height,
-                                                         dst2,
-                                                         dstStride2);
+                                       sws_scale(anim->img_convert_ctx,
+                                                 input->data,
+                                                 input->linesize,
+                                                 0,
+                                                 anim->pCodecCtx->height,
+                                                 dst2,
+                                                 dstStride2);
                                        
-                                               /* workaround: sws_scale 
-                                                  sets alpha = 0... */
+                                       /* workaround: sws_scale 
+                                          sets alpha = 0... */
                                        
-                                               r = (unsigned char*) ibuf->rect;
-       
-                                               for (i = 0; i < ibuf->x * ibuf->y;i++){
-                                                       r[3] = 0xff;
-                                                       r+=4;
-                                               }
+                                       r = (unsigned char*) ibuf->rect;
+                                       
+                                       for (i = 0; i < ibuf->x * ibuf->y;i++){
+                                               r[3] = 0xff;
+                                               r+=4;
                                        }
+                                       
                                        av_free_packet(&packet);
                                        break;
                                }
@@ -823,6 +859,10 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
                av_free_packet(&packet);
        }
 
+       if (filter_y && ibuf) {
+               IMB_filtery(ibuf);
+       }
+
        return(ibuf);
 }
 
@@ -834,6 +874,11 @@ static void free_anim_ffmpeg(struct anim * anim) {
                av_close_input_file(anim->pFormatCtx);
                av_free(anim->pFrameRGB);
                av_free(anim->pFrame);
+
+               if (anim->ib_flags & IB_animdeinterlace) {
+                       MEM_freeN(anim->pFrameDeinterlaced->data[0]);
+               }
+               av_free(anim->pFrameDeinterlaced);
                sws_freeContext(anim->img_convert_ctx);
        }
        anim->duration = 0;
@@ -983,6 +1028,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
        char head[256], tail[256];
        unsigned short digits;
        int pic;
+       int filter_y = (anim->ib_flags & IB_animdeinterlace);
 
        if (anim == NULL) return(0);
 
@@ -1040,6 +1086,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
        case ANIM_FFMPEG:
                ibuf = ffmpeg_fetchibuf(anim, position);
                if (ibuf) anim->curposition = position;
+               filter_y = 0; /* done internally */
                break;
 #endif
 #ifdef WITH_REDCODE
@@ -1052,6 +1099,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
 
        if (ibuf) {
                if (anim->ib_flags & IB_ttob) IMB_flipy(ibuf);
+               if (filter_y) IMB_filtery(ibuf);
                sprintf(ibuf->name, "%s.%04d", anim->name, anim->curposition + 1);
                
        }
index cbbd8013c822fac243f475188b6d7f40438cb045..f0b37814947a084f0b7772ff002ded8cdddb35fb 100644 (file)
@@ -99,6 +99,8 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev);
 #define BUTS_ACT_SEL           64
 #define BUTS_ACT_ACT           128
 #define BUTS_ACT_LINK          256
+#define BUTS_SENS_STATE                512
+#define BUTS_ACT_STATE         1024
 
 
 /* buttons grid */
index fbd4e4ecd91b642532bf5e8c32b1bc67ef45637b..3da4466d4d36d056a7ba828cc0a0db7f86bd6e61 100644 (file)
@@ -185,6 +185,7 @@ void uiDrawBlock(struct uiBlock *block);
 void uiGetMouse(int win, short *adr);
 void uiComposeLinks(uiBlock *block);
 void uiSetButLock(int val, char *lockstr);
+uiBut *uiFindInlink(uiBlock *block, void *poin);
 void uiClearButLock(void);
 int uiDoBlocks(struct ListBase *lb, int event, int movemouse_quit);
 void uiSetCurFont(uiBlock *block, int index);
index adeac4f3871ae5dcc31bfaa0ae723b5d82a398e9..2375a918d0ea88c8c065d6401a91fd1a18adb69f 100644 (file)
@@ -43,6 +43,8 @@ struct Camera;
 struct Texture;
 struct Lattice;
 struct bArmature;
+struct Tex;
+
 void add_curve_oopslinks(struct Curve *cu, struct Oops *oops, short flag);
 void add_from_link(struct Oops *from, struct Oops *oops);
 void add_material_oopslinks(struct Material *ma, struct Oops *oops, short flag);
index 7571d64be91a1fe798d0a86e0b639b0c87dd0283..c0542e3f34c17ca11a4bffaa1b89eabdf3258dd6 100644 (file)
@@ -52,6 +52,8 @@ struct Image;
 #define BUTS_ACT_SEL           64
 #define BUTS_ACT_ACT           128
 #define BUTS_ACT_LINK          256
+#define BUTS_SENS_STATE                512
+#define BUTS_ACT_STATE         1024
 
 /* internal */
 
@@ -583,6 +585,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 #define B_SETACTOR             2715
 #define B_SETMAINACTOR         2716
 #define B_SETDYNA              2717
+#define B_SET_STATE_BIT        2718
+#define B_INIT_STATE_BIT       2719
 
 /* *********************** */
 #define B_FPAINTBUTS           2900
index 7d497dc05ec135dfc530f8a3985ebd8c2a197dfe..4e3b80134f9e2487c1daa7188127dbd87727b172 100644 (file)
@@ -102,9 +102,9 @@ typedef struct TransCon {
                          /* Apply function pointer for linear vectorial transformation                */
                          /* The last three parameters are pointers to the in/out/printable vectors    */
     void  (*applySize)(struct TransInfo *, struct TransData *, float [3][3]);
-                         /* Apply function pointer for rotation transformation (prototype will change */
-    void  (*applyRot)(struct TransInfo *, struct TransData *, float [3]);
-                         /* Apply function pointer for rotation transformation (prototype will change */
+                         /* Apply function pointer for size transformation */
+    void  (*applyRot)(struct TransInfo *, struct TransData *, float [3], float *);
+                         /* Apply function pointer for rotation transformation */
 } TransCon;
 
 typedef struct TransDataIpokey {
index a326f5b01d60bac3752e2c8f61eec50bedbfe851..51f03a676e487fefc6f87ad51b1d8c5d15bd6c3c 100644 (file)
@@ -50,6 +50,7 @@ typedef struct bActionActuator {
        short   type, flag;             /* Playback type */                                     
        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   strideaxis;             /* Displacement axis */
@@ -80,7 +81,7 @@ typedef struct bEditObjectActuator {
        char name[32];
        float linVelocity[3]; /* initial lin. velocity on creation */
        short localflag; /* flag for the lin. vel: apply locally   */
-       short pad;
+       short dyn_operation;
 } bEditObjectActuator;
 
 typedef struct bSceneActuator {
@@ -97,7 +98,8 @@ typedef struct bPropertyActuator {
 } bPropertyActuator;
 
 typedef struct bObjectActuator {
-       int flag, type;
+       short flag, type;
+       int   damping;
        float forceloc[3], forcerot[3];
        float loc[3], rot[3];
        float dloc[3], drot[3];
@@ -190,11 +192,13 @@ typedef struct bVisibilityActuator {
 } bVisibilityActuator;
 
 typedef struct bTwoDFilterActuator{
-       char pad[4];
-       /* Tells what type of 2D Filter*/
+       char pad[2];
+       /* bitwise flag for enabling or disabling depth(bit 0) and luminance(bit 1) */
+       short texture_flag;
+       /* Tells what type of 2D Filter */
        short type;
        /* (flag == 0) means 2D filter is activate and
-          (flag != 0) means 2D filter is inactive*/
+          (flag != 0) means 2D filter is inactive */
        short flag;
        int   int_arg;
        /* a float argument */
@@ -208,6 +212,11 @@ typedef struct bParentActuator {
        struct Object *ob;
 } bParentActuator;
 
+typedef struct bStateActuator {
+       int type;                       /* 0=Set, 1=Add, 2=Rem, 3=Chg */
+       unsigned int mask;      /* the bits to change */
+} bStateActuator;
+
 typedef struct bActuator {
        struct bActuator *next, *prev, *mynew;
        short type;
@@ -246,6 +255,7 @@ typedef struct FreeCamera {
 #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
@@ -279,11 +289,14 @@ typedef struct FreeCamera {
 #define ACT_2DFILTER   19
 #define ACT_PARENT      20
 #define ACT_SHAPEACTION 21
+#define ACT_STATE              22
 
 /* actuator flag */
 #define ACT_SHOW               1
 #define ACT_DEL                        2
 #define ACT_NEW                        4
+#define ACT_LINKED             8       
+#define ACT_VISIBLE            16      
 
 /* link codes */
 #define LINK_SENSOR            0
@@ -349,10 +362,11 @@ typedef struct FreeCamera {
 /* editObjectActuator->type */
 #define ACT_EDOB_ADD_OBJECT            0
 #define ACT_EDOB_END_OBJECT            1
-#define ACT_EDOB_REPLACE_MESH  2
+#define ACT_EDOB_REPLACE_MESH          2
 #define ACT_EDOB_TRACK_TO              3
-#define ACT_EDOB_MAKE_CHILD            4
-#define ACT_EDOB_END_CHILD             5
+#define ACT_EDOB_DYNAMICS              4
+
+
 
 /* editObjectActuator->flag */
 #define ACT_TRACK_3D                   1
index 95c9b0d0cf7b0f72fed212d014bdd2048b74321a..376f95b0145147d9a8f59dc0419a4c2ef03fa544 100644 (file)
@@ -57,7 +57,7 @@ typedef struct bController {
 
        struct bSensor **slinks;
        short val, valo;
-       int pad5;
+       unsigned int state_mask;
        
 } bController;
 
@@ -66,11 +66,16 @@ typedef struct bController {
 #define CONT_LOGIC_OR  1
 #define CONT_EXPRESSION        2
 #define CONT_PYTHON            3
+#define CONT_LOGIC_NAND        4
+#define CONT_LOGIC_NOR 5
+#define CONT_LOGIC_XOR 6
+#define CONT_LOGIC_XNOR        7
 
 /* controller->flag */
 #define CONT_SHOW              1
 #define CONT_DEL               2
 #define CONT_NEW               4
+#define CONT_MASK              8
 
 #endif
 
index 83168248b9a096f01c330783f013a963b3b0e259..c4e8cb4925b83aeff9bace19c457583f853a626e 100644 (file)
@@ -216,7 +216,9 @@ typedef struct Object {
 
        struct DerivedMesh *derivedDeform, *derivedFinal;
        int lastDataMask;                       /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */
-       int pad;
+       unsigned int state;                     /* bit masks of game controllers that are active */
+       unsigned int init_state;        /* bit masks of initial state as recorded by the users */
+       int pad2;
 
 /*#ifdef WITH_VERSE*/
        void *vnode;                    /* pointer at object VerseNode */
@@ -440,6 +442,8 @@ extern Object workob;
 #define OB_ADDCONT             512
 #define OB_ADDACT              1024
 #define OB_SHOWCONT            2048
+#define OB_SETSTBIT            4096
+#define OB_INITSTBIT   8192
 
 /* ob->restrictflag */
 #define OB_RESTRICT_VIEW       1
index 90e2b8f9f413475d914d94399678e2bc223a16a1..ae7b92bb06c90199a20af376ac801362c708cf72 100644 (file)
@@ -144,7 +144,7 @@ typedef struct bSensor {
 
        /* just add here, to avoid align errors... */
        short invert; /* Whether or not to invert the output. */
-       short freq2;  /* The negative pulsing frequency? Not used anymore... */
+       short level;  /* Whether the sensor is level base (edge by default) */
        int pad;
 } bSensor;
 
@@ -202,6 +202,7 @@ typedef struct bJoystickSensor {
 #define SENS_DEL               2
 #define SENS_NEW               4
 #define SENS_NOT               8
+#define SENS_VISIBLE   16
 
 /* sensor->pulse */
 #define SENS_PULSE_CONT        0
index acc1651e9fa8af2862a048ecf559d1834f251bd1..3de5b0ff5baf5ba1921159ed09f9ca3f0c7b59c9 100644 (file)
@@ -310,7 +310,7 @@ extern UserDef U; /* from usiblender.c !!!! */
 #define        USER_DUP_ACT                    (1 << 10)
 
 /* gameflags */
-#define USER_VERTEX_ARRAYS             1
+#define USER_DEPRECATED_FLAG   1
 #define USER_DISABLE_SOUND             2
 #define USER_DISABLE_MIPMAP            4
 
index d00ce18a44f4669a6c42dd74d4525f67b903a38c..421c1343df744d7cd286ab6afb7a360ac279248d 100644 (file)
@@ -57,7 +57,7 @@ static void do_math(bNode *node, float *out, float *in, float *in2)
                break; 
        case 3: /* Divide */
                {
-                       if(in[1]==0)    /* We don't want to divide by zero. */
+                       if(in2[0]==0)   /* We don't want to divide by zero. */
                                out[0]= 0.0;
                        else
                                out[0]= in[0] / in2[0];
index 174b5fb08dc42afe913fb34e29686fa886374c98..b2120bd63c604841c3ab60dfcb7aaee7bcfdf7b7 100644 (file)
@@ -53,6 +53,8 @@ static int CurNurb_setFlagU( BPy_CurNurb * self, PyObject * args );
 static PyObject *CurNurb_getFlagV( BPy_CurNurb * self );
 static PyObject *CurNurb_oldsetFlagV( BPy_CurNurb * self, PyObject * args );
 static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args );
+static PyObject *CurNurb_getOrderU( BPy_CurNurb * self );
+static int CurNurb_setOrderU( BPy_CurNurb * self, PyObject * args );
 static PyObject *CurNurb_getType( BPy_CurNurb * self );
 static PyObject *CurNurb_oldsetType( BPy_CurNurb * self, PyObject * args );
 static int CurNurb_setType( BPy_CurNurb * self, PyObject * args );
@@ -176,6 +178,9 @@ static PyGetSetDef BPy_CurNurb_getseters[] = {
         (getter)CurNurb_getFlagV, (setter)CurNurb_setFlagV,
         "The knot type in the V direction",
         NULL},
+       {"orderU",
+        (getter)CurNurb_getOrderU, (setter)CurNurb_setOrderU,
+        "order setting for U direction", NULL},
        {"type",
         (getter)CurNurb_getType, (setter)CurNurb_setType,
         "The curve type (poly: bezier, or NURBS)",
@@ -710,6 +715,35 @@ static int CurNurb_setFlagV( BPy_CurNurb * self, PyObject * args )
        return 0;
 }
 
+static PyObject *CurNurb_getOrderU( BPy_CurNurb * self )
+{
+       return PyInt_FromLong( ( long ) self->nurb->orderu );
+}
+
+static int CurNurb_setOrderU( BPy_CurNurb * self, PyObject * args )
+{
+       int order;
+
+       args = PyNumber_Int( args );
+       if( !args )
+               return EXPP_ReturnIntError( PyExc_TypeError,
+                          "expected integer argument" );
+
+       order = ( int )PyInt_AS_LONG( args );
+       Py_DECREF( args );
+
+       if( order < 2 ) order = 2;
+       else if( order > 6 ) order = 6;
+
+       if( self->nurb->pntsu < order )
+               order = self->nurb->pntsu;
+
+       self->nurb->orderu = (short)order;
+       makeknots( self->nurb, 1, self->nurb->flagu >> 1 );
+
+       return 0;
+}
+
 /*
  * CurNurb_getIter
  *
index ef3174ac4edf3373e560b1afda9ece978514dc32..53d25a6429d7498a8f2fcf881c6d3a776129b57f 100644 (file)
@@ -1520,12 +1520,11 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
        char *type = PyString_AsString(value);
        PyObject *arg, *error;
 
-       /* parse string argument */
-
-       if( !value )
-               return ( EXPP_ReturnPyObjError( PyExc_TypeError,
-                                               "expected string argument" ) );
-
+       /* parse string argument */     
+       if( !type ) 
+               return EXPP_ReturnPyObjError ( PyExc_TypeError,
+                                              "expected string argument" );
+       
        /* check for valid arguments, set type accordingly */
 
        if( !strcmp( type, "Lamp" ) )
@@ -1546,7 +1545,7 @@ static PyObject *Lamp_oldsetType( BPy_Lamp * self, PyObject * value )
 
        /* build tuple, call wrapper */
 
-       arg = Py_BuildValue( "(i)", type );
+       arg = Py_BuildValue( "(i)", self->lamp->type );
        error = EXPP_setterWrapper ( (void *)self, arg, (setter)Lamp_setType );
        Py_DECREF ( arg );
        return error;
index 87ac3e3e6ba63c386ccca4e977042d72923034d3..85c56a616288dd9a3574270577643ed0b75ec590 100644 (file)
@@ -1452,8 +1452,8 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
                                                "vectors must be of the same size\n" ) );
 
        if( vec1->size == 3 || vec1->size == 2) {
-               float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
-               float d;
+               int result;
+               
                if (vec1->size == 3) {
                        VECCOPY(v1, vec1->vec);
                        VECCOPY(v2, vec2->vec);
@@ -1477,63 +1477,19 @@ PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
                        v4[1] = vec4->vec[1];
                        v4[2] = 0.0f;
                }
+               
+               result = LineIntersectLine(v1, v2, v3, v4, i1, i2);
 
-               VecSubf(c, v3, v1);
-               VecSubf(a, v2, v1);
-               VecSubf(b, v4, v3);
-
-               VECCOPY(dir1, a);
-               Normalize(dir1);
-               VECCOPY(dir2, b);
-               Normalize(dir2);
-               d = Inpf(dir1, dir2);
-               if (d == 1.0f || d == -1.0f) {
+               if (result == 0) {
                        /* colinear */
                        return EXPP_incr_ret( Py_None );
                }
-
-               Crossf(ab, a, b);
-               d = Inpf(c, ab);
-
-               /* test if the two lines are coplanar */
-               if (d > -0.000001f && d < 0.000001f) {
-                       Crossf(cb, c, b);
-
-                       VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
-                       VecAddf(i1, v1, a);
-                       VECCOPY(i2, i1);
-               }
-               /* if not */
                else {
-                       float n[3], t[3];
-                       VecSubf(t, v1, v3);
-
-                       /* offset between both plane where the lines lies */
-                       Crossf(n, a, b);
-                       Projf(t, t, n);
-
-                       /* for the first line, offset the second line until it is coplanar */
-                       VecAddf(v3, v3, t);
-                       VecAddf(v4, v4, t);
-                       
-                       VecSubf(c, v3, v1);
-                       VecSubf(a, v2, v1);
-                       VecSubf(b, v4, v3);
-
-                       Crossf(ab, a, b);
-                       Crossf(cb, c, b);
-
-                       VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
-                       VecAddf(i1, v1, a);
-
-                       /* for the second line, just substract the offset from the first intersection point */
-                       VecSubf(i2, i1, t);
+                       tuple = PyTuple_New( 2 );
+                       PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) );
+                       PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) );
+                       return tuple;
                }
-
-               tuple = PyTuple_New( 2 );
-               PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) );
-               PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) );
-               return tuple;
        }
        else {
                return ( EXPP_ReturnPyObjError( PyExc_TypeError,
index ba8d6d219708eae1220fb73d7d36e676c08a1445..765921665cd317b003978c11b7149bdaa53001a9 100644 (file)
@@ -535,6 +535,8 @@ class CurNurb:
        @type flagU: int
        @ivar flagV: The CurNurb knot flag V.  See L{setFlagU} for description.
        @type flagV: int
+       @ivar orderU: The CurNurb knot order U, for nurbs curves only, this is clamped by the number of points, so the orderU will never be greater.
+       @type orderU: int
        @ivar type: The type of the curve (Poly: 0, Bezier: 1, NURBS: 4)
        @type type: int
        @ivar knotsU: The knot vector in the U direction. The tuple will be empty
index ebb52c491323d2f71141f43dd9781004c3c79b96..6a0af82b4d7373e0096786f9f3a5353314d52c90 100644 (file)
@@ -2675,9 +2675,9 @@ void RE_set_max_threads(int threads)
 
 void RE_init_threadcount(Render *re) 
 {
-       if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
+        if(commandline_threads >= 1) { /* only set as an arg in background mode */
+               re->r.threads= MIN2(commandline_threads, BLENDER_MAX_THREADS);
+       } else if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
                re->r.threads = BLI_system_thread_count();
-       } else if(commandline_threads >= 1 && commandline_threads<=BLENDER_MAX_THREADS) {
-               re->r.threads= commandline_threads;
        }
 }
index a9261185f42430552b27b10951bafc6a52caffdc..179a094a98144ef2107f98de5e157a4ec0afa8bf 100644 (file)
@@ -6311,7 +6311,7 @@ static void editing_panel_mesh_texface(void)
                uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles",      660,160,60,19, &tf->mode, 0, 0, 0, 0, "Use tilemode for face");
                uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light",       720,160,60,19, &tf->mode, 0, 0, 0, 0, "Use light for face");
                uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &tf->mode, 0, 0, 0, 0, "Make face invisible");
-               uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision detection");
+               uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision and ray-sensor detection");
 
                uiBlockBeginAlign(block);
                uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared",  600,135,60,19, &tf->mode, 0, 0, 0, 0, "Blend vertex colors across face when vertices are shared");
index b6877b2e2b766fd3e060926563476751069e233e..4e5e8a605eeea74b48ac4500d34402405dd1c3db 100644 (file)
@@ -88,6 +88,7 @@
 #include "mydevice.h"
 #include "nla.h"       /* For __NLA : Important, do not remove */
 #include "butspace.h" // own module
+#include "interface.h"
 
 /* internals */
 void buttons_enji(uiBlock *, Object *);
@@ -228,7 +229,7 @@ static void sca_move_sensor(void *datav, void *data2_unused)
        bSensor *sens_to_delete= datav;
        int val;
        Base *base;
-       bSensor *sens;
+       bSensor *sens, *tmp;
        
        val= pupmenu("Move up%x1|Move down %x2");
        
@@ -245,12 +246,24 @@ static void sca_move_sensor(void *datav, void *data2_unused)
                        
                        if(sens) {
                                if( val==1 && sens->prev) {
-                                       BLI_remlink(&base->object->sensors, sens);
-                                       BLI_insertlinkbefore(&base->object->sensors, sens->prev, sens);
+                                       for (tmp=sens->prev; tmp; tmp=tmp->prev) {
+                                               if (tmp->flag & SENS_VISIBLE)
+                                                       break;
+                                       }
+                                       if (tmp) {
+                                               BLI_remlink(&base->object->sensors, sens);
+                                               BLI_insertlinkbefore(&base->object->sensors, tmp, sens);
+                                       }
                                }
                                else if( val==2 && sens->next) {
-                                       BLI_remlink(&base->object->sensors, sens);
-                                       BLI_insertlink(&base->object->sensors, sens->next, sens);
+                                       for (tmp=sens->next; tmp; tmp=tmp->next) {
+                                               if (tmp->flag & SENS_VISIBLE)
+                                                       break;
+                                       }
+                                       if (tmp) {
+                                               BLI_remlink(&base->object->sensors, sens);
+                                               BLI_insertlink(&base->object->sensors, tmp, sens);
+                                       }
                                }
                                BIF_undo_push("Move sensor");
                                allqueue(REDRAWBUTSLOGIC, 0);
@@ -267,7 +280,7 @@ static void sca_move_controller(void *datav, void *data2_unused)
        bController *controller_to_del= datav;
        int val;
        Base *base;
-       bController *cont;
+       bController *cont, *tmp;
        
        val= pupmenu("Move up%x1|Move down %x2");
        
@@ -284,12 +297,27 @@ static void sca_move_controller(void *datav, void *data2_unused)
                        
                        if(cont) {
                                if( val==1 && cont->prev) {
-                                       BLI_remlink(&base->object->controllers, cont);
-                                       BLI_insertlinkbefore(&base->object->controllers, cont->prev, cont);
+                                       /* locate the controller that has the same state mask but is earlier in the list */
+                                       tmp = cont->prev;
+                                       while(tmp) {
+                                               if(tmp->state_mask & cont->state_mask) 
+                                                       break;
+                                               tmp = tmp->prev;
+                                       }
+                                       if (tmp) {
+                                               BLI_remlink(&base->object->controllers, cont);
+                                               BLI_insertlinkbefore(&base->object->controllers, tmp, cont);
+                                       }
                                }
                                else if( val==2 && cont->next) {
+                                       tmp = cont->next;
+                                       while(tmp) {
+                                               if(tmp->state_mask & cont->state_mask) 
+                                                       break;
+                                               tmp = tmp->next;
+                                       }
                                        BLI_remlink(&base->object->controllers, cont);
-                                       BLI_insertlink(&base->object->controllers, cont->next, cont);
+                                       BLI_insertlink(&base->object->controllers, tmp, cont);
                                }
                                BIF_undo_push("Move controller");
                                allqueue(REDRAWBUTSLOGIC, 0);
@@ -306,7 +334,7 @@ static void sca_move_actuator(void *datav, void *data2_unused)
        bActuator *actuator_to_move= datav;
        int val;
        Base *base;
-       bActuator *act;
+       bActuator *act, *tmp;
        
        val= pupmenu("Move up%x1|Move down %x2");
        
@@ -323,12 +351,25 @@ static void sca_move_actuator(void *datav, void *data2_unused)
                        
                        if(act) {
                                if( val==1 && act->prev) {
-                                       BLI_remlink(&base->object->actuators, act);
-                                       BLI_insertlinkbefore(&base->object->actuators, act->prev, act);
+                                       /* locate the first visible actuators before this one */
+                                       for (tmp = act->prev; tmp; tmp=tmp->prev) {
+                                               if (tmp->flag & ACT_VISIBLE)
+                                                       break;
+                                       }
+                                       if (tmp) {
+                                               BLI_remlink(&base->object->actuators, act);
+                                               BLI_insertlinkbefore(&base->object->actuators, tmp, act);
+                                       }
                                }
                                else if( val==2 && act->next) {
-                                       BLI_remlink(&base->object->actuators, act);
-                                       BLI_insertlink(&base->object->actuators, act->next, act);
+                                       for (tmp=act->next; tmp; tmp=tmp->next) {
+                                               if (tmp->flag & ACT_VISIBLE)
+                                                       break;
+                                       }
+                                       if (tmp) {
+                                               BLI_remlink(&base->object->actuators, act);
+                                               BLI_insertlink(&base->object->actuators, tmp, act);
+                                       }
                                }
                                BIF_undo_push("Move actuator");
                                allqueue(REDRAWBUTSLOGIC, 0);
@@ -348,7 +389,7 @@ void do_logic_buts(unsigned short event)
        bActuator *act;
        Base *base;
        Object *ob;
-       int didit;
+       int didit, bit;
        
        ob= OBACT;
        if(ob==0) return;
@@ -462,6 +503,18 @@ void do_logic_buts(unsigned short event)
                                make_unique_prop_names(cont->name);
                                base->object->scaflag |= OB_SHOWCONT;
                                BLI_addtail(&(base->object->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))
+                                               break;
+                               }
+                               cont->state_mask = (1<<bit);
+                               if (cont->state_mask == 0) {
+                                       /* shouldn't happen, object state is never 0 */
+                                       cont->state_mask = 1;
+                               }
                        }
                        base= base->next;
                }
@@ -469,6 +522,32 @@ void do_logic_buts(unsigned short event)
                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;
+                       }
+                       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;
+                       }
+                       base= base->next;
+               }
+               allqueue(REDRAWBUTSLOGIC, 0);
+               break;
+
        case B_CHANGE_CONT:
                base= FIRSTBASE;
                while(base) {
@@ -505,7 +584,7 @@ void do_logic_buts(unsigned short event)
                BIF_undo_push("Delete controller");
                allqueue(REDRAWBUTSLOGIC, 0);
                break;
-       
+
        case B_ADD_ACT:
                base= FIRSTBASE;
                while(base) {
@@ -661,6 +740,14 @@ static char *controller_name(int type)
                return "AND";
        case CONT_LOGIC_OR:
                return "OR";
+       case CONT_LOGIC_NAND:
+               return "NAND";
+       case CONT_LOGIC_NOR:
+               return "NOR";
+       case CONT_LOGIC_XOR:
+               return "XOR";
+       case CONT_LOGIC_XNOR:
+               return "XNOR";
        case CONT_EXPRESSION:
                return "Expression";
        case CONT_PYTHON:
@@ -671,7 +758,7 @@ static char *controller_name(int type)
 
 static char *controller_pup(void)
 {
-       return "Controllers   %t|AND %x0|OR %x1|Expression %x2|Python %x3";
+       return "Controllers   %t|AND %x0|OR %x1|XOR %x6|NAND %x4|NOR %x5|XNOR %x7|Expression %x2|Python %x3";
 }
 
 static char *actuator_name(int type)
@@ -717,6 +804,8 @@ static char *actuator_name(int type)
                return "2D Filter";
        case ACT_PARENT:
                return "Parent";
+       case ACT_STATE:
+               return "State";
        }
        return "unknown";
 }
@@ -732,21 +821,21 @@ static char *actuator_pup(Object *owner)
                return "Actuators  %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1"
                        "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
                        "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
-                       "|Visibility %x18|2D Filter %x19|Parent %x20";
+                       "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
                break;
 
        case OB_MESH:
                return "Actuators  %t|Shape Action %x21|Motion %x0|Constraint %x9|Ipo %x1"
                        "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
                        "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
-                       "|Visibility %x18|2D Filter %x19|Parent %x20";
+                       "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
                break;
 
        default:
                return "Actuators  %t|Motion %x0|Constraint %x9|Ipo %x1"
                        "|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
                        "|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
-                       "|Visibility %x18|2D Filter %x19|Parent %x20";
+                       "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
        }
 }
 
@@ -815,7 +904,8 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
                if(scavisflag & BUTS_ACT_ACT) OBACT->scavisflag |= OB_VIS_ACT;
        }
        
-       if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK)) {
+       /* BUTS_XXX_STATE are similar to BUTS_XXX_LINK for selecting the object */
+       if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK|BUTS_SENS_STATE|BUTS_ACT_STATE)) {
                doit= 1;
                while(doit) {
                        doit= 0;
@@ -824,7 +914,7 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
                        while(ob) {
                        
                                /* 1st case: select sensor when controller selected */
-                               if((scavisflag & BUTS_SENS_LINK) && (ob->scavisflag & OB_VIS_SENS)==0) {
+                               if((scavisflag & (BUTS_SENS_LINK|BUTS_SENS_STATE)) && (ob->scavisflag & OB_VIS_SENS)==0) {
                                        sens= ob->sensors.first;
                                        while(sens) {
                                                for(a=0; a<sens->totlinks; a++) {
@@ -879,7 +969,7 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
                                }
                                
                                /* 4th case: select actuator when controller selected */
-                               if( (scavisflag & BUTS_ACT_LINK)  && (ob->scavisflag & OB_VIS_CONT)) {
+                               if( (scavisflag & (BUTS_ACT_LINK|BUTS_ACT_STATE))  && (ob->scavisflag & OB_VIS_CONT)) {
                                        cont= ob->controllers.first;
                                        while(cont) {
                                                for(a=0; a<cont->totlinks; a++) {
@@ -984,6 +1074,10 @@ static void draw_default_sensor_header(bSensor *sens,
                         (short)(x + 10 + 0.85 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
                         &sens->invert, 0.0, 0.0, 0, 0,
                         "Invert the level (output) of this sensor");
+       uiDefButS(block, TOG, 1, "Lvl",
+                        (short)(x + 10 + 0.70 * (w-20)), (short)(y - 19), (short)(0.15 * (w-20)), 19,
+                        &sens->level, 0.0, 0.0, 0, 0,
+                        "Level detector versus edge detector (only applicable in case of logic state transition)");
 }
 
 static short draw_sensorbuttons(bSensor *sens, uiBlock *block, short xco, short yco, short width,char* objectname)
@@ -1458,6 +1552,7 @@ static int get_col_actuator(int type)
        case ACT_GAME:                  return TH_BUT_SETTING2;
        case ACT_VISIBILITY:            return TH_BUT_NUM;
        case ACT_CONSTRAINT:            return TH_BUT_ACTION;
+       case ACT_STATE:                 return TH_BUT_SETTING2;
        default:                                return TH_BUT_NEUTRAL;
        }
 }
@@ -1468,7 +1563,23 @@ static void set_col_actuator(int item, int medium)
        
 }
 
-static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, short yco, short width)
+char *get_state_name(Object *ob, short bit)
+{
+       bController *cont;
+       unsigned int mask;
+
+       mask = (1<<bit);
+       cont = ob->controllers.first;
+       while (cont) {
+               if (cont->state_mask & mask) {
+                       return cont->name;
+               }
+               cont = cont->next;
+       }
+       return (char*)"";
+}
+
+static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, short xco, short yco, short width)
 {
        bSoundActuator      *sa      = NULL;
        bCDActuator                     *cda     = NULL;
@@ -1487,11 +1598,12 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
        bVisibilityActuator *visAct  = NULL;
        bTwoDFilterActuator     *tdfa    = NULL;
        bParentActuator     *parAct  = NULL;
+       bStateActuator          *staAct  = NULL;
        
        float *fp;
        short ysize = 0, wval;
        char *str;
-       int myline;
+       int myline, stbit;
 
        /* yco is at the top of the rect, draw downwards */
        uiBlockSetEmboss(block, UI_EMBOSSM);
@@ -1501,7 +1613,7 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
        {
        case ACT_OBJECT:
                {
-                       ysize= 129;
+                       ysize= 152;
                        
                        glRects(xco, yco-ysize, xco+width, yco);
                        uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
@@ -1539,14 +1651,18 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
                        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, "");
                        
-                       uiDefButBitI(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");
-                       uiDefButBitI(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");
-                       uiDefButBitI(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");
-                       uiDefButBitI(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");
-                       uiDefButBitI(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");
-                       uiDefButBitI(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");
+                       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");
                        
-                       uiDefButBitI(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");
+                       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");
                        
                        yco-= ysize;
                        break;
@@ -1573,31 +1689,34 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
 #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, 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, yco-44, width-60, 19, &aa->act, "Action name");
+                       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");
                        
                        if(aa->type == ACT_ACTION_FROM_PROP)
                        {
-                               uiDefBut(block, TEX, 0, "Prop: ",xco+30, yco-64, 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+30, yco-44, width-60, 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-64, (width-60)/2, 19, &aa->sta, 0.0, MAXFRAMEF, 0, 0, "Start frame");
-                               uiDefButI(block, NUM, 0, "End: ",xco+30+(width-60)/2, yco-64, (width-60)/2, 19, &aa->end, 0.0, MAXFRAMEF, 0, 0, "End frame");
+                               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, "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");
                        
-                       
-                       
-                       uiDefButI(block, NUM, 0, "Blendin: ", xco+30, yco-84, (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-84, (width-60)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers");
+                       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");                  
+
                        
 #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
                        if(aa->type == ACT_ACTION_MOTION)
                        {
-                               uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-104, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action");
+                               uiDefButF(block, NUM, 0, "Cycle: ",xco+30, yco-84, (width-60)/2, 19, &aa->stridelength, 0.0, 2500.0, 0, 0, "Distance covered by a single cycle of the action");
                        }
 #endif
                        
+                       
+                       
                        yco-=ysize;
                        break;
                }
@@ -1821,8 +1940,15 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
                        uiDefButI(block, NUM, 0, "Time:",       xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes");
                        uiDefButS(block, TOG, 0, "3D",  xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking");
                }
-               
-               str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3";
+               else if(eoa->type==ACT_EDOB_DYNAMICS) {
+                       ysize= 48;
+                       glRects(xco, yco-ysize, xco+width, yco);
+                       uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
+                       
+                       str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3";
+                       uiDefButS(block, MENU, B_REDR, str,             xco+40, yco-44, (width-80), 19,  &(eoa->dyn_operation), 0.0, 0.0, 0, 0, "");
+               }
+               str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4";
                uiDefButS(block, MENU, B_REDR, str,             xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, "");
 
                yco-= ysize;
@@ -2022,6 +2148,37 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
 
                break;
                
+       case ACT_STATE:
+               ysize = 34;
+
+               glRects(xco, yco-ysize, xco+width, yco);
+               uiEmboss((float)xco,
+                        (float)yco-ysize, (float)xco+width, (float)yco, 1);
+               
+               staAct = act->data;
+
+               str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3";
+
+               uiDefButI(block, MENU, B_REDR, str,
+                         xco + 10, yco - 24, 65, 19, &staAct->type,
+                         0.0, 0.0, 0, 0,
+                         "Select the bit operation on object state mask");
+
+               for (wval=0; wval<15; wval+=5) {
+                       uiBlockBeginAlign(block);
+                       for (stbit=0; stbit<5; stbit++) {
+                               uiDefButBitI(block, TOG, (1<<(stbit+wval)), 0, "",      (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(wval+stbit)));
+                       }
+                       for (stbit=0; stbit<5; stbit++) {
+                               uiDefButBitI(block, TOG, (1<<(stbit+wval+15)), 0, "",   (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(wval+stbit+15)));
+                       }
+               }
+               uiBlockEndAlign(block);
+
+               yco-= ysize;
+
+               break;
+
        case ACT_RANDOM:
                ysize  = 69;
 
@@ -2225,7 +2382,11 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
                                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-60, 19, &tdfa->text, "");
+                               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)");
                                break;
                }
                
@@ -2596,6 +2757,118 @@ void buttons_bullet(uiBlock *block, Object *ob)
        uiBlockEndAlign(block);
 }
 
+static void check_object_state(void *arg1_but, void *arg2_mask)
+{
+       unsigned int *cont_mask = arg2_mask;
+       uiBut *but = arg1_but;
+
+       if (*cont_mask == 0 || !(G.qual & LR_SHIFTKEY))
+               *cont_mask = (1<<but->retval);
+       but->retval = B_REDR;
+}
+
+static void check_controller_state_mask(void *arg1_but, void *arg2_mask)
+{
+       unsigned int *cont_mask = arg2_mask;
+       uiBut *but = arg1_but;
+       
+       /* a controller is always in a single state */
+       *cont_mask = (1<<but->retval);
+       but->retval = B_REDR;
+}
+
+static int first_bit(unsigned int mask)
+{
+       int bit;
+
+       for (bit=0; bit<32; bit++) {
+               if (mask & (1<<bit))
+                       return bit;
+       }
+       return -1;
+}
+
+static uiBlock *controller_state_mask_menu(void *arg_cont)
+{
+       uiBlock *block;
+       uiBut *but;
+       bController *cont = arg_cont;
+
+       short yco = 12, xco = 0, stbit, offset;
+
+       block= uiNewBlock(&curarea->uiblocks, "Controller state mask", UI_EMBOSS, UI_HELV, curarea->win);
+
+       /* use this for a fake extra empy space around the buttons */
+       uiDefBut(block, LABEL, 0, "",                   -5, -5, 200, 34, NULL, 0, 0, 0, 0, "");
+       
+       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+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
+                       uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
+               }
+               for (stbit=0; stbit<5; stbit++) {
+                       but = uiDefButBitI(block, TOG, (1<<(stbit+offset+15)), (stbit+offset+15), "",   (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
+                       uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
+               }
+       }
+       uiBlockEndAlign(block);
+
+       uiBlockSetDirection(block, UI_TOP);
+
+       return block;
+}
+
+static void do_object_state_menu(void *arg, int event)
+{      
+       Object *ob = arg;
+
+       switch (event) {
+       case 0:
+               ob->state = 0x3FFFFFFF;
+               break;
+       case 1:
+               ob->state = ob->init_state;
+               if (!ob->state)
+                       ob->state = 1;
+               break;
+       case 2:
+               ob->init_state = ob->state;
+               break;
+       }
+       allqueue(REDRAWBUTSLOGIC, 0);
+}
+
+static uiBlock *object_state_mask_menu(void *arg_obj)
+{
+       uiBlock *block;
+       short xco = 0;
+
+       block= uiNewBlock(&curarea->uiblocks, "obstatemenu", UI_EMBOSSP, UI_HELV, curarea->win);
+       uiBlockSetButmFunc(block, do_object_state_menu, arg_obj);
+       
+       uiDefBut(block, BUTM, 1, "Set all bits",                0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+       uiDefBut(block, BUTM, 1, "Recall init state",   0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
+       uiDefBut(block, SEPR, 0, "",                                    0, (short)(xco-=6),      160, 6,  NULL, 0.0, 0.0, 0, 0, "");
+       uiDefBut(block, BUTM, 1, "Store init state",    0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+       uiBlockSetDirection(block, UI_TOP);
+       return block;
+}
+
+static int is_sensor_linked(uiBlock *block, bSensor *sens)
+{
+       bController *cont;
+       int i, count;
+
+       for (count=0, i=0; i<sens->totlinks; i++) {
+               cont = sens->links[i];
+               if (uiFindInlink(block, cont) != NULL)
+                       return 1;
+       }
+       return 0;
+}
+
 /* never used, see CVS 1.134 for the code */
 /*  static FreeCamera *new_freecamera(void) */
 
@@ -2614,7 +2887,7 @@ void logic_buts(void)
        uiBlock *block;
        uiBut *but;
        World *wrld;
-       int a;
+       int a, iact, stbit, offset;
        short xco, yco, count, width, ycoo;
        char *pupstr, name[32];
 
@@ -2686,158 +2959,241 @@ void logic_buts(void)
        uiClearButLock();
 
        idar= get_selected_and_linked_obs(&count, G.buts->scaflag);
-       
+
+       /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that 
+          we can determine which is actually linked/visible */
+       for(a=0; a<count; a++) {
+               ob= (Object *)idar[a];
+               act= ob->actuators.first;
+               while(act) {
+                       act->flag &= ~(ACT_LINKED|ACT_VISIBLE);
+                       act = act->next;
+               }
+               /* same for sensors */
+               sens= ob->sensors.first;
+               while(sens) {
+                       sens->flag &= ~(SENS_VISIBLE);
+                       sens = sens->next;
+               }
+       }
+               
+       /* start with the controller because we need to know which one is visible */
        /* ******************************* */
-       xco= 375; yco= 170; width= 230;
+       xco= 695; yco= 170; width= 275;
 
        uiBlockSetEmboss(block, UI_EMBOSSP);
-       uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 80, 19, "");
+       uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
        uiBlockSetEmboss(block, UI_EMBOSS);
        
        uiBlockBeginAlign(block);
-       uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-       uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
-       uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+       uiDefButBitS(block, TOG, BUTS_CONT_SEL,  B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+       uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
+       uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
        uiBlockEndAlign(block);
        
+       ob= OBACT;
+       
        for(a=0; a<count; a++) {
                ob= (Object *)idar[a];
                uiClearButLock();
                uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-               
-               if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
-               
+               if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
+
                /* presume it is only objects for now */
                uiBlockSetEmboss(block, UI_EMBOSS);
                uiBlockBeginAlign(block);
-               if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
-               uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
-               if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
-               uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
+               if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
+               uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
+               if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
+               uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
                uiBlockEndAlign(block);
-               yco-=20;
+               yco-=17;
                
-               if(ob->scaflag & OB_SHOWSENS) {
-                       
-                       sens= ob->sensors.first;
-                       while(sens) {
-                               uiBlockSetEmboss(block, UI_EMBOSSM);
-                               uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,      xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
-                               uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
+               /* mark all actuators linked to these controllers */
+               /* note that some of these actuators could be from objects that are not in the display list.
+                  It's ok because those actuators will not be displayed here */
+               cont= ob->controllers.first;
+               while(cont) {
+                       for (iact=0; iact<cont->totlinks; iact++) {
+                               act = cont->links[iact];
+                               act->flag |= ACT_LINKED;
+                       }
+                       cont = cont->next;
+               }
 
-                               ycoo= yco;
-                               if(sens->flag & SENS_SHOW)
-                               {
-                                       uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),     (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
-                                       but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name");
-                                       uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
+               if(ob->scaflag & OB_SHOWCONT) {
 
-                                       sens->otype= sens->type;
-                                       yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name);
-                                       if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+                       /* first show the state */
+                       uiBlockSetEmboss(block, UI_EMBOSSP);
+                       uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 40, 19, "Object state menu: store and retrieve initial state");
+                       uiBlockSetEmboss(block, UI_EMBOSS);
+                       if (!ob->state)
+                               ob->state = 1;
+                       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)));
+                                       uiButSetFunc(but, check_object_state, but, &(ob->state));
                                }
-                               else {
-                                       set_col_sensor(sens->type, 1);
-                                       glRecti(xco+22, yco, xco+width-22,yco+19);
-                                       but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, "");
-                                       uiButSetFunc(but, sca_move_sensor, sens, NULL);
-                                       but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, "");
-                                       uiButSetFunc(but, sca_move_sensor, sens, NULL);
+                               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)));
+                                       uiButSetFunc(but, check_object_state, but, &(ob->state));
                                }
+                       }
+                       uiBlockBeginAlign(block);
+                       uiDefButBitS(block, TOG, OB_SETSTBIT, B_SET_STATE_BIT, "All",(short)(xco+235), yco-10, 25, 19, &ob->scaflag, 0, 0, 0, 0, "Set all state bits");
+                       uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+260), yco-10, 25, 19, &ob->scaflag, 0, 0, 0, 0, "Set the initial state");
+                       uiBlockEndAlign(block);
 
-                               but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
-                               uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
-
-                               yco-=20;
+                       yco-=35;
+               
+                       /* display only the controllers that match the current state */
+                       offset = 0;
+                       for (stbit=0; stbit<32; stbit++) {
+                               if (!(ob->state & (1<<stbit)))
+                                       continue;
+                               /* add a separation between controllers of different states */
+                               if (offset) {
+                                       offset = 0;
+                                       yco -= 6;
+                               }
+                               cont= ob->controllers.first;
+                               while(cont) {
+                                       if (cont->state_mask & (1<<stbit)) {
+                                               /* this controller is visible, mark all its actuator */
+                                               for (iact=0; iact<cont->totlinks; iact++) {
+                                                       act = cont->links[iact];
+                                                       act->flag |= ACT_VISIBLE;
+                                               }
+                                               uiBlockSetEmboss(block, UI_EMBOSSM);
+                                               uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,      xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
+                                               uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
+                                               uiBlockSetEmboss(block, UI_EMBOSSP);
+                                               sprintf(name, "%d", first_bit(cont->state_mask)+1);
+                                               uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state mask");
+                                               uiBlockSetEmboss(block, UI_EMBOSSM);
+                               
+                                               if(cont->flag & CONT_SHOW) {
+                                                       cont->otype= cont->type;
+                                                       uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type");
+                                                       but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-166), 19, cont->name, 0, 31, 0, 0, "Controller name");
+                                                       uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
+                               
+                                                       ycoo= yco;
+                                                       yco= draw_controllerbuttons(cont, block, xco, yco, width);
+                                                       if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+                                               }
+                                               else {
+                                                       cpack(0x999999);
+                                                       glRecti(xco+22, yco, xco+width-22,yco+19);
+                                                       but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type");
+                                                       uiButSetFunc(but, sca_move_controller, cont, NULL);
+                                                       but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-166), 19, cont, 0, 0, 0, 0, "Controller name");
+                                                       uiButSetFunc(but, sca_move_controller, cont, NULL);
+                                                       ycoo= yco;
+                                               }
+                               
+                                               but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+                                               uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
+                               
+                                               uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, "");
+                                               /* offset is >0 if at least one controller was displayed */
+                                               offset++;
+                                               yco-=20;
+                                       }
+                                       cont= cont->next;
+                               }
 
-                               sens= sens->next;
                        }
                        yco-= 6;
                }
        }
-
+       
        /* ******************************* */
-       xco= 675; yco= 170; width= 230;
+       xco= 375; yco= 170; width= 250;
 
        uiBlockSetEmboss(block, UI_EMBOSSP);
-       uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
+       uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, 19, "");
        uiBlockSetEmboss(block, UI_EMBOSS);
        
        uiBlockBeginAlign(block);
-       uiDefButBitS(block, TOG, BUTS_CONT_SEL,  B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-       uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
-       uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
+       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");
        uiBlockEndAlign(block);
        
-       ob= OBACT;
-       
        for(a=0; a<count; a++) {
                ob= (Object *)idar[a];
                uiClearButLock();
                uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-               if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
-
+               
+               if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
+               
                /* presume it is only objects for now */
                uiBlockSetEmboss(block, UI_EMBOSS);
                uiBlockBeginAlign(block);
-               if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
-               uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
-               if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
-               uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
+               if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
+               uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
+               if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
+               uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
                uiBlockEndAlign(block);
                yco-=20;
                
-               if(ob->scaflag & OB_SHOWCONT) {
-               
-                       cont= ob->controllers.first;
-                       while(cont) {
-                               uiBlockSetEmboss(block, UI_EMBOSSM);
-                               uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X,      xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
-                               uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
-               
-                               if(cont->flag & CONT_SHOW) {
-                                       cont->otype= cont->type;
-                                       uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type");
-                                       but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, cont->name, 0, 31, 0, 0, "Controller name");
-                                       uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
-               
-                                       ycoo= yco;
-                                       yco= draw_controllerbuttons(cont, block, xco, yco, width);
-                                       if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
-                               }
-                               else {
-                                       cpack(0x999999);
-                                       glRecti(xco+22, yco, xco+width-22,yco+19);
-                                       but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type");
-                                       uiButSetFunc(but, sca_move_controller, cont, NULL);
-                                       but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-144), 19, cont, 0, 0, 0, 0, "Controller name");
-                                       uiButSetFunc(but, sca_move_controller, cont, NULL);
+               if(ob->scaflag & OB_SHOWSENS) {
+                       
+                       sens= ob->sensors.first;
+                       while(sens) {
+                               if (!(G.buts->scaflag & BUTS_SENS_STATE) ||
+                                       sens->totlinks == 0 ||          /* always display sensor without links so that is can be edited */
+                                       is_sensor_linked(block, sens)) {
+                                       sens->flag |= SENS_VISIBLE;
+                                       uiBlockSetEmboss(block, UI_EMBOSSM);
+                                       uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X,      xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
+                                       uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
+
                                        ycoo= yco;
+                                       if(sens->flag & SENS_SHOW)
+                                       {
+                                               uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(),     (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
+                                               but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name");
+                                               uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
+
+                                               sens->otype= sens->type;
+                                               yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name);
+                                               if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+                                       }
+                                       else {
+                                               set_col_sensor(sens->type, 1);
+                                               glRecti(xco+22, yco, xco+width-22,yco+19);
+                                               but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, "");
+                                               uiButSetFunc(but, sca_move_sensor, sens, NULL);
+                                               but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, "");
+                                               uiButSetFunc(but, sca_move_sensor, sens, NULL);
+                                       }
+
+                                       but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+                                       uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
+
+                                       yco-=20;
                                }
-               
-                               but= uiDefIconBut(block, LINK, 0, ICON_LINK,    (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
-                               uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
-               
-                               uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, "");
-               
-                               yco-=20;
-                               
-                               cont= cont->next;
+                               sens= sens->next;
                        }
                        yco-= 6;
                }
        }
-       
+
        /* ******************************* */
-       xco= 985; yco= 170; width= 280;
+       xco= 1040; yco= 170; width= 280;
        
        uiBlockSetEmboss(block, UI_EMBOSSP);
-       uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 100, 19, "");
+       uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, 19, "");
        uiBlockSetEmboss(block, UI_EMBOSS);
        uiBlockBeginAlign(block);
-       uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
-       uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
-       uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+       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");
        uiBlockEndAlign(block);
        for(a=0; a<count; a++) {
                ob= (Object *)idar[a];
@@ -2859,34 +3215,38 @@ void logic_buts(void)
                        
                        act= ob->actuators.first;
                        while(act) {
-                               uiBlockSetEmboss(block, UI_EMBOSSM);
-                               uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X,        xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator");
-                               uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings");
+                               if (!(G.buts->scaflag & BUTS_ACT_STATE) ||
+                                       !(act->flag & ACT_LINKED) ||            /* always display actuators without links so that is can be edited */
+                                       (act->flag & ACT_VISIBLE)) {            /* this actuator has visible connection, display it */
+                                       act->flag |= ACT_VISIBLE;       /* mark the actuator as visible to help implementing the up/down action */
+                                       uiBlockSetEmboss(block, UI_EMBOSSM);
+                                       uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X,        xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator");
+                                       uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings");
+
+                                       if(act->flag & ACT_SHOW) {
+                                               act->otype= act->type;
+                                               uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),  (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type");
+                                               but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name");
+                                               uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
+
+                                               ycoo= yco;
+                                               yco= draw_actuatorbuttons(ob, act, block, xco, yco, width);
+                                               if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+                                       }
+                                       else {
+                                               set_col_actuator(act->type, 1);
+                                               glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
+                                               but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type");
+                                               uiButSetFunc(but, sca_move_actuator, act, NULL);
+                                               but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name");
+                                               uiButSetFunc(but, sca_move_actuator, act, NULL);
+                                               ycoo= yco;
+                                       }
 
-                               if(act->flag & ACT_SHOW) {
-                                       act->otype= act->type;
-                                       uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob),  (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type");
-                                       but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name");
-                                       uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
+                                       uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, "");
 
-                                       ycoo= yco;
-                                       yco= draw_actuatorbuttons(act, block, xco, yco, width);
-                                       if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
-                               }
-                               else {
-                                       set_col_actuator(act->type, 1);
-                                       glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
-                                       but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type");
-                                       uiButSetFunc(but, sca_move_actuator, act, NULL);
-                                       but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name");
-                                       uiButSetFunc(but, sca_move_actuator, act, NULL);
-                                       ycoo= yco;
+                                       yco-=20;
                                }
-
-                               uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, "");
-
-                               yco-=20;
-
                                act= act->next;
                        }
                        yco-= 6;
index 3797a92f16fd4fd4778e86ba81ddef13daeacb23..1c98950080a50a867f71481a85ca9bc4c1cf6796 100644 (file)
@@ -900,7 +900,7 @@ static void seq_panel_filter_video()
                     "Convert input to float data");
 
        uiDefButBitI(block, TOG, SEQ_FILTERY, 
-                    B_SEQ_BUT_RELOAD, "FilterY",       
+                    B_SEQ_BUT_RELOAD_FILE, "De-Inter", 
                     170,110,80,19, &last_seq->flag, 
                     0.0, 21.0, 100, 0, 
                     "For video movies to remove fields");
index 8c4958a651a76002d1b187c614be2e501fb7b20e..89466151a39f9216e6cbdac597c95587ae4b35e5 100644 (file)
@@ -474,10 +474,13 @@ static void draw_channel_names(void)
                                        indent= 0;
                                        special= -1;
                                        
-                                       if (EXPANDED_AGRP(agrp))
-                                               expand = ICON_TRIA_DOWN;
-                                       else
-                                               expand = ICON_TRIA_RIGHT;
+                                       /* only show expand if there are any channels */
+                                       if (agrp->channels.first) {
+                                               if (EXPANDED_AGRP(agrp))
+                                                       expand = ICON_TRIA_DOWN;
+                                               else
+                                                       expand = ICON_TRIA_RIGHT;
+                                       }
                                                
                                        if (EDITABLE_AGRP(agrp))
                                                protect = ICON_UNLOCKED;
index deb7ddc068d71c8d0daa514e3182918c0a258434..2f1cdb8b951b4a28f9bba3c1f6504a8dca40706a 100644 (file)
@@ -246,7 +246,8 @@ void default_gl_light(void)
        glDisable(GL_COLOR_MATERIAL);
 }
 
-/* also called when render 'ogl' */
+/* also called when render 'ogl'
+   keep synced with Myinit_gl_stuff in the game engine! */
 void init_gl_stuff(void)       
 {
        float mat_ambient[] = { 0.0, 0.0, 0.0, 0.0 };
index 40b6b7ba6fe9c6084739b17e487e008d99b7b04a..f93a1526e3cb891d53a389e24115595736f4531a 100644 (file)
@@ -390,7 +390,7 @@ static void actdata_filter_actionchannel (ListBase *act_data, bActionChannel *ac
 
 static void actdata_filter_action (ListBase *act_data, bAction *act, int filter_mode)
 {
-       bActListElem *ale;
+       bActListElem *ale=NULL;
        bActionGroup *agrp;
        bActionChannel *achan, *lastchan=NULL;
        
@@ -429,6 +429,15 @@ static void actdata_filter_action (ListBase *act_data, bAction *act, int filter_
                                        for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
                                                actdata_filter_actionchannel(act_data, achan, filter_mode);
                                        }
+                                       
+                                       /* remove group from filtered list if last element is group 
+                                        * (i.e. only if group had channels, which were all hidden)
+                                        */
+                                       if ( (ale) && (act_data->last == ale) && 
+                                                (ale->data == agrp) && (agrp->channels.first) ) 
+                                       {
+                                               BLI_freelinkN(act_data, ale);
+                                       }
                                }
                        }
                }
@@ -3648,7 +3657,7 @@ static void mouse_actionchannels (short mval[])
                        {
                                bActionGroup *agrp= (bActionGroup *)act_channel;
                                
-                               if (mval[0] < 16) {
+                               if ((mval[0] < 16) && (agrp->channels.first)) {
                                        /* toggle expand */
                                        agrp->flag ^= AGRP_EXPANDED;
                                }
index cb245867c8963322c24114f18597f38cdbf1d006..a3b05a008c8d6b3ba851221cb9646319bba3c08a 100644 (file)
@@ -354,7 +354,7 @@ void txt_export_to_object(struct Text *text)
 //     char sdir[FILE_MAXDIR];
 //     char sfile[FILE_MAXFILE];
 
-       if(!text) return;
+       if(!text || !text->lines.first) return;
 
        id = (ID *)text;
 
@@ -429,7 +429,7 @@ void txt_export_to_objects(struct Text *text)
        int linenum = 0;
        float offset[3] = {0.0,0.0,0.0};
 
-       if(!text) return;
+       if(!text || !text->lines.first) return;
 
        id = (ID *)text;
 
index d5e34779173b68789ee6dc5efdfc01163d6eec21..c7a75b32df16656dc58b4f46bfeb028729d3cc59 100644 (file)
@@ -2307,7 +2307,7 @@ void selectconnected_mesh(void)
        if(em->edges.first==0) return;
        
        if( unified_findnearest(&eve, &eed, &efa)==0 ) {
-               error("Nothing indicated ");
+               /* error("Nothing indicated "); */ /* this is mostly annoying, eps with occluded geometry */
                return;
        }
        
@@ -2407,7 +2407,7 @@ static void selectconnected_delimit_mesh__internal(short all, short sel)
                EditFace *efa_mouse = findnearestface(&dist);
                
                if( !efa_mouse ) {
-                       error("Nothing indicated ");
+                       /* error("Nothing indicated "); */ /* this is mostly annoying, eps with occluded geometry */
                        return;
                }
                
index 3c945775b5b070ba26dfea2cf706f43eb774cd63..2e5785eaab89b88f1d8cd8d79328c6909e6b5dda 100644 (file)
@@ -5942,7 +5942,7 @@ void hide_objects(int select)
        Base *base;
        short changed = 0, changed_act = 0;
        for(base = FIRSTBASE; base; base=base->next){
-               if(TESTBASELIB(base)==select){
+               if ((base->lay & G.vd->lay) && (TESTBASELIB(base)==select)) {
                        base->flag &= ~SELECT;
                        base->object->flag = base->flag;
                        base->object->restrictflag |= OB_RESTRICT_VIEW;
index fb0fac4489d9772eadb7769a831f5195fd217a6c..b9351f82d1e03de1fd49d3b33fa93bb147f9643b 100644 (file)
@@ -2634,12 +2634,13 @@ void set_filter_seq(void)
        ed= G.scene->ed;
        if(ed==0) return;
 
-       if(okee("Set FilterY")==0) return;
+       if(okee("Set Deinterlace")==0) return;
 
        WHILE_SEQ(ed->seqbasep) {
                if(seq->flag & SELECT) {
                        if(seq->type==SEQ_MOVIE) {
                                seq->flag |= SEQ_FILTERY;
+                               reload_sequence_new_file(seq);
                        }
 
                }
index 5f8485267bcbf5d711e204db2b33cfa5886ee524..18a9803dcae088762e8b33efc54b3d7f82d345bb 100644 (file)
@@ -2690,15 +2690,17 @@ void image_changed(SpaceImage *sima, Image *image)
                                        
                                        if(image->id.us==0) id_us_plus(&image->id);
                                        else id_lib_extern(&image->id);
-                                       
+#if 0                          /* GE People dont like us messing with their face modes */
                                        if (tface->transp==TF_ADD) {} /* they obviously know what they are doing! - leave as is */
                                        else if (ibuf && ibuf->depth == 32)     tface->transp = TF_ALPHA;
                                        else                                                            tface->transp = TF_SOLID;
-                                       
+#endif
                                } else {
                                        tface->tpage= NULL;
                                        tface->mode &= ~TF_TEX;
+#if 0
                                        tface->transp = TF_SOLID;
+#endif
                                }
                                change = 1;
                        }
index 6582866d9a167b330b158e5ff19c2c040b594884..4fbf92d646e4e875ed52c6f9f669b012ba2b020a 100644 (file)
@@ -2797,6 +2797,10 @@ static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt)
        line->to= bt;
 }
 
+uiBut *uiFindInlink(uiBlock *block, void *poin)
+{
+       return ui_find_inlink(block, poin);
+}
 
 void uiComposeLinks(uiBlock *block)
 {
index 99645b5e71f3f6ffb1c40a9374d02a95f28c07d7..51d83eff3e612316db8658fc865f3d54d3e2514a 100644 (file)
@@ -1153,7 +1153,6 @@ void build_oops()
                                                }
                                        }
                                        else if(type==ID_AR && G.soops->visiflag & OOPS_AR) {
-                                               bArmature *ar= ob->data;
                                                oops= add_test_oops(ob->data);
                                        }
                                }
index dcceea971f7f30e3299f6ba6cca02fb8bc6384ac..cc08bf53a72a439c7ea4f5ae4bff13304015a5d5 100644 (file)
@@ -1627,6 +1627,8 @@ void pose_flipquats(void)
                        pchan->quat[3]= -pchan->quat[3];
                }
        }
-                       
+       
+      &n