[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23064] branches/itasc/source: BGE: enhanced PyObjectPlus_Proxy class to support generic pointer, added pose channel and bone proxy class.

Benoit Bolsee benoit.bolsee at online.be
Tue Sep 8 13:57:52 CEST 2009


Revision: 23064
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23064
Author:   ben2610
Date:     2009-09-08 13:57:52 +0200 (Tue, 08 Sep 2009)

Log Message:
-----------
BGE: enhanced PyObjectPlus_Proxy class to support generic pointer, added pose channel and bone proxy class.

Add Generic pointer reference in PyObjectPlus_Proxy so that generic Blender structure can easily be proxied in the GE.
3 modes are available: on GE object ref (as before), GE+generic struct, generic struct. 
The last mode is handy to create light proxy to Blender structure in the GE without having to create a GE object.
A GE class still needs to be created but it's just a placeholder for Attributes.

See BL_ArmatureBone for an example of generic struct (Bone) proxy 
See BL_ArmatureChannel for an example of GE+generic struct (bPoseChannel) proxy
Use Py_HeaderPtr when you need to create a GE proxy class with generic structure capability.

Added numerous KY_PYATTRIBUTE macro to deal with C struct: vector, matrix, flags, negative flags, C string.

Added BL_ArmatureChannel to allow setting armature pose in game. 
joint_rotation attribute is especially handy for robotics applications where the joints have limited degree of freedom.

Added BL_ArmatureBone to allow reading bone rest pose data (read-only)

epydoc updated for BL_ArmatureBone and BL_ArmatureChannel. 

Modified Paths:
--------------
    branches/itasc/source/blender/blenlib/intern/arithb.c
    branches/itasc/source/blender/ikplugin/intern/iksolver_plugin.c
    branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp
    branches/itasc/source/blender/makesdna/DNA_action_types.h
    branches/itasc/source/blender/python/generic/matrix.c
    branches/itasc/source/blender/python/generic/vector.c
    branches/itasc/source/gameengine/Converter/BL_ArmatureObject.cpp
    branches/itasc/source/gameengine/Converter/BL_ArmatureObject.h
    branches/itasc/source/gameengine/Expressions/CMakeLists.txt
    branches/itasc/source/gameengine/Expressions/PyObjectPlus.cpp
    branches/itasc/source/gameengine/Expressions/PyObjectPlus.h
    branches/itasc/source/gameengine/Expressions/SConscript
    branches/itasc/source/gameengine/Ketsji/KX_PythonInit.cpp
    branches/itasc/source/gameengine/Ketsji/KX_PythonInitTypes.cpp
    branches/itasc/source/gameengine/Ketsji/KX_PythonSeq.cpp
    branches/itasc/source/gameengine/Ketsji/KX_PythonSeq.h
    branches/itasc/source/gameengine/PyDoc/GameTypes.py

Added Paths:
-----------
    branches/itasc/source/gameengine/Converter/BL_ArmatureChannel.cpp
    branches/itasc/source/gameengine/Converter/BL_ArmatureChannel.h

Modified: branches/itasc/source/blender/blenlib/intern/arithb.c
===================================================================
--- branches/itasc/source/blender/blenlib/intern/arithb.c	2009-09-08 11:41:27 UTC (rev 23063)
+++ branches/itasc/source/blender/blenlib/intern/arithb.c	2009-09-08 11:57:52 UTC (rev 23064)
@@ -2835,9 +2835,9 @@
 	double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
 	double a[3];
 	
-	if (R->parity) e[1] = -e[1];
+	ti = e[i]/2; tj = e[j]/2; th = e[k]/2;
 	
-	ti = e[0]/2; tj = e[1]/2; th = e[2]/2;
+	if (R->parity) e[j] = -e[j];
 	
 	ci = cos(ti);  cj = cos(tj);  ch = cos(th);
 	si = sin(ti);  sj = sin(tj);  sh = sin(th);
@@ -2874,13 +2874,12 @@
 	double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
 	
 	if (R->parity) {
-		e[0] = -e[0]; 
-		e[1] = -e[1]; 
-		e[2] = -e[2];
+		ti = -e[i];	  tj = -e[j];	th = -e[k];
 	}
+	else {
+		ti = e[i];	  tj = e[j];	th = e[k];
+	}
 	
-	ti = e[0];	  tj = e[1];	th = e[2];
-	
 	ci = cos(ti); cj = cos(tj); ch = cos(th);
 	si = sin(ti); sj = sin(tj); sh = sin(th);
 	
@@ -2908,17 +2907,17 @@
 {
 	RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); 
 	short i=R->i,  j=R->j, 	k=R->k;
-	double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]);
+	double cy = sqrt(M[i][i]*M[i][i] + M[i][j]*M[i][j]);
 	
 	if (cy > 16*FLT_EPSILON) {
-		e[0] = atan2(M[j][k], M[k][k]);
-		e[1] = atan2(-M[i][k], cy);
-		e[2] = atan2(M[i][j], M[i][i]);
+		e[i] = atan2(M[j][k], M[k][k]);
+		e[j] = atan2(-M[i][k], cy);
+		e[k] = atan2(M[i][j], M[i][i]);
 	} 
 	else {
-		e[0] = atan2(-M[k][j], M[j][j]);
-		e[1] = atan2(-M[i][k], cy);
-		e[2] = 0;
+		e[i] = atan2(-M[k][j], M[j][j]);
+		e[j] = atan2(-M[i][k], cy);
+		e[k] = 0;
 	}
 	
 	if (R->parity) {
@@ -2944,21 +2943,28 @@
 {
 	RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); 
 	short i=R->i,  j=R->j, 	k=R->k;
-	double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]);
+	float m[3][3];
+	double cy;
 	
+	/* process the matrix first */
+	Mat3CpyMat3(m, M);
+	Mat3Ortho(m);
+	
+	cy= sqrt(m[i][i]*m[i][i] + m[i][j]*m[i][j]);
+	
 	if (cy > 16*FLT_EPSILON) {
-		e1[0] = atan2(M[j][k], M[k][k]);
-		e1[1] = atan2(-M[i][k], cy);
-		e1[2] = atan2(M[i][j], M[i][i]);
+		e1[i] = atan2(m[j][k], m[k][k]);
+		e1[j] = atan2(-m[i][k], cy);
+		e1[k] = atan2(m[i][j], m[i][i]);
 		
-		e2[0] = atan2(-M[j][k], -M[k][k]);
-		e2[1] = atan2(-M[i][k], -cy);
-		e2[2] = atan2(-M[i][j], -M[i][i]);
+		e2[i] = atan2(-m[j][k], -m[k][k]);
+		e2[j] = atan2(-m[i][k], -cy);
+		e2[k] = atan2(-m[i][j], -m[i][i]);
 	} 
 	else {
-		e1[0] = atan2(-M[k][j], M[j][j]);
-		e1[1] = atan2(-M[i][k], cy);
-		e1[2] = 0;
+		e1[i] = atan2(-m[k][j], m[j][j]);
+		e1[j] = atan2(-m[i][k], cy);
+		e1[k] = 0;
 		
 		VecCopyf(e2, e1);
 	}
@@ -2975,7 +2981,6 @@
 }
 
 /* uses 2 methods to retrieve eulers, and picks the closest */
-// FIXME: this does not work well with the other rotation modes...
 void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order)
 {
 	float eul1[3], eul2[3];
@@ -3369,6 +3374,41 @@
 	}
 }
 
+/* Returns a vector bisecting the angle at v2 formed by v1, v2 and v3 */
+void VecBisect3(float *out, float *v1, float *v2, float *v3)
+{
+	float d_12[3], d_23[3];
+	VecSubf(d_12, v2, v1);
+	VecSubf(d_23, v3, v2);
+	Normalize(d_12);
+	Normalize(d_23);
+	VecAddf(out, d_12, d_23);
+	Normalize(out);
+}
+
+/* Returns a reflection vector from a vector and a normal vector
+reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror)
+*/
+void VecReflect(float *out, float *v1, float *v2)
+{
+	float vec[3], normal[3];
+	float reflect[3] = {0.0f, 0.0f, 0.0f};
+	float dot2;
+
+	VecCopyf(vec, v1);
+	VecCopyf(normal, v2);
+
+	Normalize(normal);
+
+	dot2 = 2 * Inpf(vec, normal);
+
+	reflect[0] = vec[0] - (dot2 * normal[0]);
+	reflect[1] = vec[1] - (dot2 * normal[1]);
+	reflect[2] = vec[2] - (dot2 * normal[2]);
+
+	VecCopyf(out, reflect);
+}
+
 /* Return the angle in degrees between vecs 1-2 and 2-3 in degrees
    If v1 is a shoulder, v2 is the elbow and v3 is the hand,
    this would return the angle at the elbow */

Modified: branches/itasc/source/blender/ikplugin/intern/iksolver_plugin.c
===================================================================
--- branches/itasc/source/blender/ikplugin/intern/iksolver_plugin.c	2009-09-08 11:41:27 UTC (rev 23063)
+++ branches/itasc/source/blender/ikplugin/intern/iksolver_plugin.c	2009-09-08 11:57:52 UTC (rev 23064)
@@ -504,6 +504,8 @@
 		for(a=0; a<tree->totchannel; a++) {
 			if(!(tree->pchan[a]->flag & POSE_DONE))	// successive trees can set the flag
 				where_is_pose_bone(scene, ob, tree->pchan[a], ctime);
+			// tell blender that this channel was controlled by IK, it's cleared on each where_is_pose()
+			tree->pchan[a]->flag |= POSE_CHAIN;
 		}
 		/* 5. execute the IK solver */
 		execute_posetree(ob, tree);

Modified: branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp
===================================================================
--- branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp	2009-09-08 11:41:27 UTC (rev 23063)
+++ branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp	2009-09-08 11:57:52 UTC (rev 23064)
@@ -1205,10 +1205,11 @@
 
 static void execute_scene(IK_Scene* ikscene, bItasc* ikparam, float ctime, float frtime)
 {
-	// We don't allow external contraint to change our bones, mark the channel done
 	int i;
 	for (i=0; i<ikscene->numchan; i++) {
-		ikscene->channels[i].pchan->flag |= POSE_DONE;
+		// We don't allow external contraint to change our bones, mark the channel done
+		// also tell Blender that this channel is part of IK tree (cleared on each where_is_pose()
+		ikscene->channels[i].pchan->flag |= (POSE_DONE|POSE_CHAIN);
 	}
 	// only run execute the scene if at least one of our target is enabled
 	for (i=ikscene->targets.size(); i > 0; --i) {

Modified: branches/itasc/source/blender/makesdna/DNA_action_types.h
===================================================================
--- branches/itasc/source/blender/makesdna/DNA_action_types.h	2009-09-08 11:41:27 UTC (rev 23063)
+++ branches/itasc/source/blender/makesdna/DNA_action_types.h	2009-09-08 11:57:52 UTC (rev 23064)
@@ -207,6 +207,8 @@
 	PCHAN_ROT_YZX,
 	PCHAN_ROT_ZXY,
 	PCHAN_ROT_ZYX,
+	
+	PCHAN_ROT_MAX,	/* sentinel */
 } ePchan_RotMode;
 
 /* Pose ------------------------------------ */

Modified: branches/itasc/source/blender/python/generic/matrix.c
===================================================================
--- branches/itasc/source/blender/python/generic/matrix.c	2009-09-08 11:41:27 UTC (rev 23063)
+++ branches/itasc/source/blender/python/generic/matrix.c	2009-09-08 11:57:52 UTC (rev 23064)
@@ -598,18 +598,18 @@
 		return NULL;
 	
 	BLI_strncpy(str,"",1024);
-	for(x = 0; x < self->rowSize; x++){
+	for(x = 0; x < self->colSize; x++){
 		sprintf(buffer, "[");
 		strcat(str,buffer);
-		for(y = 0; y < (self->colSize - 1); y++) {
-			sprintf(buffer, "%.6f, ", self->matrix[x][y]);
+		for(y = 0; y < (self->rowSize - 1); y++) {
+			sprintf(buffer, "%.6f, ", self->matrix[y][x]);
 			strcat(str,buffer);
 		}
-		if(x < (self->rowSize-1)){
-			sprintf(buffer, "%.6f](matrix [row %d])\n", self->matrix[x][y], x);
+		if(x < (self->colSize-1)){
+			sprintf(buffer, "%.6f](matrix [row %d])\n", self->matrix[y][x], x);
 			strcat(str,buffer);
 		}else{
-			sprintf(buffer, "%.6f](matrix [row %d])", self->matrix[x][y], x);
+			sprintf(buffer, "%.6f](matrix [row %d])", self->matrix[y][x], x);
 			strcat(str,buffer);
 		}
 	}
@@ -703,7 +703,7 @@
 		return -1;
 	
 	if(i >= self->rowSize || i < 0){
-		PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad row\n");
+		PyErr_SetString(PyExc_TypeError, "matrix[attribute] = x: bad column\n");
 		return -1;
 	}
 
@@ -933,21 +933,21 @@
 	}
 
 	if(mat1 && mat2) { /*MATRIX * MATRIX*/
-		if(mat1->colSize != mat2->rowSize){
+		if(mat1->rowSize != mat2->colSize){
 			PyErr_SetString(PyExc_AttributeError,"Matrix multiplication: matrix A rowsize must equal matrix B colsize");
 			return NULL;
 		}
-		for(x = 0; x < mat1->rowSize; x++) {
-			for(y = 0; y < mat2->colSize; y++) {
-				for(z = 0; z < mat1->colSize; z++) {
-					dot += (mat1->matrix[x][z] * mat2->matrix[z][y]);
+		for(x = 0; x < mat2->rowSize; x++) {
+			for(y = 0; y < mat1->colSize; y++) {
+				for(z = 0; z < mat1->rowSize; z++) {
+					dot += (mat1->matrix[z][y] * mat2->matrix[x][z]);
 				}
-				mat[((x * mat1->rowSize) + y)] = (float)dot;
+				mat[((x * mat1->colSize) + y)] = (float)dot;
 				dot = 0.0f;
 			}
 		}
 		
-		return newMatrixObject(mat, mat1->rowSize, mat2->colSize, Py_NEW, NULL);
+		return newMatrixObject(mat, mat2->rowSize, mat1->colSize, Py_NEW, NULL);
 	}
 	
 	if(mat1==NULL){
@@ -1288,9 +1288,9 @@
 
 //----------------column_vector_multiplication (internal)---------
 //COLUMN VECTOR Multiplication (Matrix X Vector)
-// [1][2][3]   [a]
-// [4][5][6] * [b]
-// [7][8][9]   [c]
+// [1][4][7]   [a]
+// [2][5][8] * [b]
+// [3][6][9]   [c]
 //vector/matrix multiplication IS NOT COMMUTATIVE!!!!
 static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject* vec)
 {
@@ -1312,11 +1312,12 @@
 
 	for(x = 0; x < vec->size; x++){
 		vecCopy[x] = vec->vec[x];
-		}
+	}
+	vecNew[3] = 1.0f;
 
-	for(x = 0; x < mat->rowSize; x++) {
-		for(y = 0; y < mat->colSize; y++) {
-			dot += mat->matrix[x][y] * vecCopy[y];
+	for(x = 0; x < mat->colSize; z++) {
+		for(y = 0; y < mat->rowSize; y++) {
+			dot += mat->matrix[y][x] * vecCopy[y];
 		}
 		vecNew[z++] = (float)dot;
 		dot = 0.0f;

Modified: branches/itasc/source/blender/python/generic/vector.c
===================================================================
--- branches/itasc/source/blender/python/generic/vector.c	2009-09-08 11:41:27 UTC (rev 23063)
+++ branches/itasc/source/blender/python/generic/vector.c	2009-09-08 11:57:52 UTC (rev 23064)
@@ -1955,9 +1955,9 @@
 
 //-----------------row_vector_multiplication (internal)-----------
 //ROW VECTOR Multiplication - Vector X Matrix
-//[x][y][z] *  [1][2][3]
-//             [4][5][6]
-//             [7][8][9]
+//[x][y][z] *  [1][4][7]
+//             [2][5][8]
+//             [3][6][9]
 //vector/matrix multiplication IS NOT COMMUTATIVE!!!!
 static PyObject *row_vector_multiplication(VectorObject* vec, MatrixObject * mat)
 {
@@ -1966,7 +1966,7 @@
 	int x, y, z = 0, vec_size = vec->size;
 
 	if(mat->colSize != vec_size){
-		if(mat->rowSize == 4 && vec_size != 3){
+		if(mat->colSize == 4 && vec_size != 3){
 			PyErr_SetString(PyExc_AttributeError, "vector * matrix: matrix column size and the vector size must be the same");
 			return NULL;
 		}else{

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list