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
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
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
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
00079
00080
00081
00082 if(axis==0) {
00083 cox= 0; coy= 1; coz= 2;
00084 }
00085 if(axis==1) {
00086 cox= 1; coy= 2; coz= 0;
00087 }
00088 if(axis==2) {
00089 cox= 2; coy= 0; coz= 1;
00090 }
00091 if(axis==3) {
00092 cox= 0; coy= 1; coz= 2;
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;
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;
00131 float mindistsq, maxdistsq, distsq;
00132 float mat[3][3];
00133
00134
00135
00136 bool bNegativeEvent = IsNegativeEvent();
00137 if (bNegativeEvent) return false;
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 mindistsq= m_minHeight*m_minHeight;
00159 maxdistsq= m_maxHeight*m_maxHeight;
00160
00161
00162
00163
00164
00165
00166 from[2] = (15.0*from[2] + lookat[2] + m_height)/16.0;
00167
00168
00169
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
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
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
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);
00236
00237
00238
00239 from[2] = (20.0*from[2] + lookat[2] + m_height)/21.0;
00240
00241
00242
00243
00244
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
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
00273
00274
00275
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,
00287 __repr,
00288 0,
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
00305 {NULL,NULL}
00306 };
00307
00308 PyObject* KX_CameraActuator::_getattr(char* attr) {
00309 _getattr_up(SCA_IActuator);
00310 }
00311
00312
00313
00314 PyObject* KX_CameraActuator::PySet(PyObject* self,
00315 PyObject* args,
00316 PyObject* kwds) {
00317
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
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