[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