Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

KX_CameraActuator.cpp

Go to the documentation of this file.
00001 
00007 
00008 #include "KX_CameraActuator.h"
00009 #include <iostream>
00010 #include <math.h>
00011 #include "KX_GameObject.h"
00012 
00013 CCString KX_CameraActuator::X_AXIS_STRING = "x";
00014 CCString KX_CameraActuator::Y_AXIS_STRING = "y";
00015 
00016 
00017 /* ------------------------------------------------------------------------- */
00018 /* Native functions                                                          */
00019 /* ------------------------------------------------------------------------- */
00020 
00021 KX_CameraActuator::KX_CameraActuator(SCA_IObject* gameobj, 
00022                                                                          CValue *obj,
00023                                                                          float hght,
00024                                                                          float minhght,
00025                                                                          float maxhght,
00026                                                                          bool  xytog,
00027                                                                          PyTypeObject* T)
00028 : SCA_IActuator(gameobj, T)

00029 {
00030         m_ob        = obj;
00031         m_height    = hght;
00032         m_minHeight = minhght;
00033         m_maxHeight = maxhght;
00034         m_x         = xytog;
00035 
00036 
00037 }
00038 
00039 KX_CameraActuator::~KX_CameraActuator()

00040 {
00041 
00042 }
00043 
00044 /* three functions copied from blender arith... don't know if there's an equivalent */
00045 
00046 float Normalise(float *n)

00047 {
00048         float d;
00049         
00050         d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
00051         /* FLT_EPSILON is too large! A larger value causes normalise errors in a scaled down utah teapot */
00052         if(d>0.0000000000001) {
00053                 d= sqrt(d);
00054 
00055                 n[0]/=d; 
00056                 n[1]/=d; 
00057                 n[2]/=d;
00058         } else {
00059                 n[0]=n[1]=n[2]= 0.0;
00060                 d= 0.0;
00061         }
00062         return d;
00063 }
00064 
00065 void Crossf(float *c, float *a, float *b)

00066 {
00067         c[0] = a[1] * b[2] - a[2] * b[1];
00068         c[1] = a[2] * b[0] - a[0] * b[2];
00069         c[2] = a[0] * b[1] - a[1] * b[0];
00070 }
00071 
00072 
00073 void VecUpMat3(float *vec, float mat[][3], short axis)

00074 {
00075         float inp;
00076         short cox = 0, coy = 0, coz = 0;
00077         
00078         /* up varieeren heeft geen zin, is eigenlijk helemaal geen up!

00079          * zie VecUpMat3old

00080          */
00081 
00082         if(axis==0) {
00083                 cox= 0; coy= 1; coz= 2;         /* Y up Z tr */
00084         }
00085         if(axis==1) {
00086                 cox= 1; coy= 2; coz= 0;         /* Z up X tr */
00087         }
00088         if(axis==2) {
00089                 cox= 2; coy= 0; coz= 1;         /* X up Y tr */
00090         }
00091         if(axis==3) {
00092                 cox= 0; coy= 1; coz= 2;         /* Y op -Z tr */
00093                 vec[0]= -vec[0];
00094                 vec[1]= -vec[1];
00095                 vec[2]= -vec[2];
00096         }
00097         if(axis==4) {
00098                 cox= 1; coy= 0; coz= 2;         /*  */
00099         }
00100         if(axis==5) {
00101                 cox= 2; coy= 1; coz= 0;         /* Y up X tr */
00102         }
00103 
00104         mat[coz][0]= vec[0];
00105         mat[coz][1]= vec[1];
00106         mat[coz][2]= vec[2];
00107         Normalise((float *)mat[coz]);
00108         
00109         inp= mat[coz][2];
00110         mat[coy][0]= - inp*mat[coz][0];
00111         mat[coy][1]= - inp*mat[coz][1];
00112         mat[coy][2]= 1.0 - inp*mat[coz][2];
00113 
00114         Normalise((float *)mat[coy]);
00115         
00116         Crossf(mat[cox], mat[coy], mat[coz]);
00117         
00118 }
00119 
00120 bool KX_CameraActuator::Update(double curtime,double deltatime)

00121 {
00122         bool result = true;
00123 
00124         KX_GameObject *obj = (KX_GameObject*) GetParent();
00125         MT_Point3 from = obj->NodeGetWorldPosition();
00126         MT_Matrix3x3 frommat = obj->NodeGetWorldOrientation();
00127         MT_Point3 lookat = ((KX_GameObject*)m_ob)->NodeGetWorldPosition();
00128         MT_Matrix3x3 actormat = ((KX_GameObject*)m_ob)->NodeGetWorldOrientation();
00129         float fp1[3], fp2[3], rc[3];
00130         float inp, fac, factor = 0.0; /* some factor...                                    */
00131         float mindistsq, maxdistsq, distsq;
00132         float mat[3][3];
00133         
00134         /* wondering... is it really neccesary/desirable to suppress negative    */
00135         /* events here?                                                          */
00136         bool bNegativeEvent = IsNegativeEvent();
00137         if (bNegativeEvent) return false;
00138 
00139         /* The rules:                                                            */
00140         /* CONSTRAINT 1: staat camera goed geroteerd in sector (90 graden grid)? */
00141         /* CONSTRAINT 2: kan cam actor zien? niet vanuit schaduw!!!              */
00142         /* CONSTRAINT 3: vaste hoogte boven schaduw                              */
00143         /* CONSTRAINT 4:: achterliggende camera (?)                              */
00144         /* CONSTRAINT 5: minimum / maximum afstand                               */
00145         /* CONSTRAINT 6: nog eens vaste hoogte boven schaduw                     */
00146         /* CONSTRAINT 7: track naar schaduw                                      */
00147         /* CONSTRAINT 8: klein beetje met aktie meekijken: projecteer x-vec op   */
00148         /*             scherm?                                                   */
00149         /* ...and then set the camera position. Since we assume the parent of    */
00150         /* this actuator is always a camera, just set the parent position and    */
00151         /* rotation. We do not check whether we really have a camera as parent.  */
00152         /* It may be better to turn this into a general tracking actuator later  */
00153         /* on, since lots of plausible relations can be filled in here.          */
00154 
00155         /* ... set up some parameters ...                                        */
00156         /* missing here: the 'floorloc' of the actor's shadow */
00157 
00158         mindistsq= m_minHeight*m_minHeight;
00159         maxdistsq= m_maxHeight*m_maxHeight;
00160 
00161         /* C1: not checked... is a future option                                 */
00162 
00163         /* C2: blender test_visibility function                                  */
00164 
00165         /* C3: fixed height  */
00166         from[2] = (15.0*from[2] + lookat[2] + m_height)/16.0;
00167 
00168 
00169         /* C4: camera behind actor   */
00170         if (m_x) {
00171                 fp1[0] = actormat[0][0];
00172                 fp1[1] = actormat[1][0];
00173                 fp1[2] = actormat[2][0];
00174 
00175                 fp2[0] = frommat[0][0];
00176                 fp2[1] = frommat[1][0];
00177                 fp2[2] = frommat[2][0];
00178         } 
00179         else {
00180                 fp1[0] = actormat[0][1];
00181                 fp1[1] = actormat[1][1];
00182                 fp1[2] = actormat[2][1];
00183 
00184                 fp2[0] = frommat[0][1];
00185                 fp2[1] = frommat[1][1];
00186                 fp2[2] = frommat[2][1];
00187         }
00188         
00189         inp= fp1[0]*fp2[0] + fp1[1]*fp2[1] + fp1[2]*fp2[2];
00190         fac= (-1.0 + inp)/32.0;
00191 
00192         from[0]+= fac*fp1[0];
00193         from[1]+= fac*fp1[1];
00194         from[2]+= fac*fp1[2];
00195         
00196         /* alleen alstie ervoor ligt: cross testen en loodrechte bijtellen */
00197         if(inp<0.0) {
00198                 if(fp1[0]*fp2[1] - fp1[1]*fp2[0] > 0.0) {
00199                         from[0]-= fac*fp1[1];
00200                         from[1]+= fac*fp1[0];
00201                 }
00202                 else {
00203                         from[0]+= fac*fp1[1];
00204                         from[1]-= fac*fp1[0];
00205                 }
00206         }
00207 
00208         /* CONSTRAINT 4: minimum / maximum afstand */
00209 
00210         rc[0]= (lookat[0]-from[0]);
00211         rc[1]= (lookat[1]-from[1]);
00212         rc[2]= (lookat[2]-from[2]);
00213         distsq= rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2];
00214 
00215         if(distsq > maxdistsq) {
00216                 distsq = 0.15*(distsq-maxdistsq)/distsq;
00217                 
00218                 from[0] += distsq*rc[0];
00219                 from[1] += distsq*rc[1];
00220                 from[2] += distsq*rc[2];
00221         }
00222         else if(distsq < mindistsq) {
00223                 distsq = 0.15*(mindistsq-distsq)/mindistsq;
00224                 
00225                 from[0] -= distsq*rc[0];
00226                 from[1] -= distsq*rc[1];
00227                 from[2] -= distsq*rc[2];
00228         }
00229 
00230 
00231         /* CONSTRAINT 5: track naar schaduw */
00232         rc[0]= (lookat[0]-from[0]);
00233         rc[1]= (lookat[1]-from[1]);
00234         rc[2]= (lookat[2]-from[2]);
00235         VecUpMat3(rc, mat, 3);  /* y up Track -z */
00236         
00237 
00238         /* C6: should parametrize this as well */
00239         from[2] = (20.0*from[2] + lookat[2] + m_height)/21.0;
00240 
00241         /* C7: */
00242         /* C8: */
00243 
00244         /* now set the camera position and rotation */
00245         
00246         obj->NodeSetLocalPosition(from);
00247         
00248         actormat[0][0]= mat[0][0]; actormat[0][1]= mat[1][0]; actormat[0][2]= mat[2][0];
00249         actormat[1][0]= mat[0][1]; actormat[1][1]= mat[1][1]; actormat[1][2]= mat[2][1];
00250         actormat[2][0]= mat[0][2]; actormat[2][1]= mat[1][2]; actormat[2][2]= mat[2][2];
00251         obj->NodeSetLocalOrientation(actormat);
00252 
00253         return result;
00254 }
00255 
00256 CValue *KX_CameraActuator::findObject(char *obName) 

00257 {
00258         /* hook to object system */
00259         return NULL;
00260 }
00261 
00262 bool KX_CameraActuator::string2axischoice(char *axisString) 

00263 {
00264         bool res = true;
00265 
00266         res = !(axisString == Y_AXIS_STRING);
00267 
00268         return res;
00269 }
00270 
00271 /* ------------------------------------------------------------------------- */
00272 /* Python functions                                                          */
00273 /* ------------------------------------------------------------------------- */
00274 
00275 /* Integration hooks ------------------------------------------------------- */
00276 PyTypeObject KX_CameraActuator::Type = {
00277         PyObject_HEAD_INIT(&PyType_Type)
00278         0,
00279         "KX_CameraActuator",
00280         sizeof(KX_CameraActuator),
00281         0,
00282         PyDestructor,
00283         0,
00284         __getattr,
00285         __setattr,
00286         0, //&MyPyCompare,
00287         __repr,
00288         0, //&cvalue_as_number,
00289         0,
00290         0,
00291         0,
00292         0
00293 };
00294 
00295 PyParentObject KX_CameraActuator::Parents[] = {
00296         &KX_CameraActuator::Type,
00297         &SCA_IActuator::Type,
00298         &SCA_ILogicBrick::Type,
00299         &CValue::Type,
00300         NULL
00301 };
00302 
00303 PyMethodDef KX_CameraActuator::Methods[] = {
00304 //      {"set", (PyCFunction) KX_CameraActuator::sPySet, METH_VARARGS},
00305         {NULL,NULL} //Sentinel
00306 };
00307 
00308 PyObject* KX_CameraActuator::_getattr(char* attr) {
00309         _getattr_up(SCA_IActuator);
00310 }
00311 
00312 /* set --------------------------------------------------------------------- */
00313 
00314 PyObject* KX_CameraActuator::PySet(PyObject* self, 
00315                                                                    PyObject* args, 
00316                                                                    PyObject* kwds) {
00317         /* args: object, height, min, max, axisxory */
00318         char *objectName, *axis;
00319         float heightVal = 0.0, minVal = 0.0, maxVal = 0.0;
00320         bool pickAxisX = true;
00321         CValue *newOb;
00322         if (!PyArg_ParseTuple(args, "sfffs", &objectName, heightVal, 
00323                                                   minVal, maxVal, &axis)) {
00324                 return NULL;
00325         }
00326         
00327         newOb     = findObject(objectName);
00328         pickAxisX = string2axischoice(axis);
00329 
00330         /* only assign if the object makes sense */
00331         if (newOb) {
00332                 m_ob        = newOb;
00333                 m_height    = heightVal;
00334                 m_minHeight = minVal;
00335                 m_maxHeight = maxVal;
00336                 m_x         = pickAxisX;
00337         }
00338 
00339         Py_Return;
00340 }
00341 
00342 /* eof */

Generated at Thu Feb 1 13:03:04 2001 for Ketsji Game Engine by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000