2 #define WIN32_LEAN_AND_MEAN
5 #if defined(__APPLE__) && defined(__MACH__)
6 #include <OpenGL/gl.h> // Header File For The OpenGL32 Library
7 #include <OpenGL/glu.h> // Header File For The GLu32 Library
9 #include <GL/gl.h> // Header File For The OpenGL32 Library
10 #include <GL/glu.h> // Header File For The GLu32 Library
13 #include "SDL/SDL_image.h"
14 #include "SDL/SDL_timer.h"
15 #include "SDL/SDL_mixer.h"
17 #include "e3d_engine.h"
20 e3D_Object::e3D_Object(e3D_Render
*render
)
27 ObjectClassname
="Object";
28 // future classes should be named like:
32 // Object.Particle.Atmosphere
33 // A distinctive ObjectClassname is needed when trying to guess the pass number in the render.
38 e3D_Object::e3D_Object(e3D_Object
*parent
)
42 // cout << "Child added to parent" << endl;
43 e3D_Object(parent
->Render
);
45 Parent
->children
.insert(Parent
->children
.begin(),this);
46 Render
=Parent
->Render
;
48 ObjectClassname
="Object";
52 void e3D_Object::init_physics()
54 // printf("init_physics\n");
55 body = dBodyCreate(Render->world);
58 dMassSetSphere(&mass,1,1);
59 dBodySetMass(body,&mass);
60 dBodySetPosition(body,0,0,0);
61 scale_x=scale_y=scale_z=1;
62 AutoDeleteAfterDraw=0;
65 void e3D_Object::init_physics(double size
,double density
)
67 // printf("init_physics\n");
68 body
= dBodyCreate(Render
->world
);
71 dMassSetSphere(&mass
,density
,size
);
72 dBodySetMass(body
,&mass
);
73 dBodySetPosition(body
,0,0,0);
74 scale_x
=scale_y
=scale_z
=size
;
75 AutoDeleteAfterDraw
=0;
78 void e3D_Object::Free()
82 Parent
->children
.remove(this);
95 e3D_Object::~e3D_Object()
101 void e3D_Object::LoadPosition() {glLoadMatrixd(position);}
102 void e3D_Object::MultPosition() {glMultMatrixd(position);}
103 void e3D_Object::SavePosition() {glGetDoublev(GL_MODELVIEW_MATRIX,position);}
105 void e3D_Object::LoadInverse() {glLoadMatrixd(inverse);}
106 void e3D_Object::MultInverse() {glMultMatrixd(inverse);}
107 void e3D_Object::SaveInverse() {glGetDoublev(GL_MODELVIEW_MATRIX,inverse);}
109 void e3D_Object::LoadInverseO() {glLoadMatrixd(inverse_orientation);}
110 void e3D_Object::MultInverseO() {glMultMatrixd(inverse_orientation);}
111 void e3D_Object::SaveInverseO() {glGetDoublev(GL_MODELVIEW_MATRIX,inverse_orientation);}
113 void e3D_Object::ResetAtBody(dBodyID dest
,double x
, double y
, double z
, double vel_mult
)
116 dBodyGetRelPointPos(dest
,x
,y
,z
,p
);
117 const dReal
*r
= dBodyGetRotation(dest
);
118 const dReal
*AngularVel
, *LinearVel
;
119 AngularVel
=dBodyGetAngularVel(dest
);
120 LinearVel
=dBodyGetLinearVel(dest
);
122 dBodySetLinearVel(body
,LinearVel
[0]*vel_mult
,LinearVel
[1]*vel_mult
,LinearVel
[2]*vel_mult
);
123 dBodySetPosition(body
,p
[0],p
[1],p
[2]);
124 dBodySetRotation(body
,r
);
127 void e3D_Object::LoadRealPosition()
130 const dReal
*p
= dBodyGetPosition(body
);
131 const dReal
*r
= dBodyGetRotation(body
);
135 m
[ 0] = r
[ 0];m
[ 1] = r
[ 4];m
[ 2] = r
[ 8];m
[ 3] = 0;
136 m
[ 4] = r
[ 1];m
[ 5] = r
[ 5];m
[ 6] = r
[ 9];m
[ 7] = 0;
137 m
[ 8] = r
[ 2];m
[ 9] = r
[ 6];m
[10] = r
[10];m
[11] = 0;
138 m
[12] = p
[ 0];m
[13] = p
[ 1];m
[14] = p
[ 2];m
[15] = 1;
140 glScaled(scale_x
,scale_y
,scale_z
);
141 /* e3D_Object *Obj=this;
147 } while((Obj=Obj->Parent)!=NULL);
152 for (i=1;i<n;i++) Obj=Obj->Parent;
158 void e3D_Object::GetXYZ(double *x
, double *y
,double *z
)
160 const dReal
*p
= dBodyGetPosition(body
);
171 glGetDoublev(GL_MODELVIEW_MATRIX,M);
172 matrix2point(M, x, y,z);
176 void e3D_Object::GetCamera(double dx
,double dy
, double dz
)
179 double eyeX
,eyeY
,eyeZ
;
180 double centerX
,centerY
,centerZ
;
185 glTranslated(dx
,dy
,dz
);
186 glGetDoublev(GL_MODELVIEW_MATRIX
,M
);
187 matrix2point(M
, &eyeX
, &eyeY
, &eyeZ
);
188 matrix2point(M
, ¢erX
, ¢erY
, ¢erZ
,0,0,-10);
189 matrix2point(M
, &upX
, &upY
, &upZ
,0,10,0);
195 camera_eyeX
=(camera_eyeX
*camlag
+eyeX
)/(camlag
+1);
196 camera_eyeY
=(camera_eyeY
*camlag
+eyeY
)/(camlag
+1);
197 camera_eyeZ
=(camera_eyeZ
*camlag
+eyeZ
)/(camlag
+1);
199 camera_centerX
=(camera_centerX
*camlag
+centerX
)/(camlag
+1);
200 camera_centerY
=(camera_centerY
*camlag
+centerY
)/(camlag
+1);
201 camera_centerZ
=(camera_centerZ
*camlag
+centerZ
)/(camlag
+1);
203 camera_upX
=(camera_upX
*camlag
+upX
)/(camlag
+1);
204 camera_upY
=(camera_upY
*camlag
+upY
)/(camlag
+1);
205 camera_upZ
=(camera_upZ
*camlag
+upZ
)/(camlag
+1);
209 gluLookAt(eyeX
,eyeY
,eyeZ
,
210 centerX
, centerY
, centerZ
,
213 /* gluLookAt(camera_eyeX,camera_eyeY,camera_eyeZ,
214 camera_centerX, camera_centerY, camera_centerZ,
215 camera_upX, camera_upY, camera_upZ);
219 void e3D_Object::Translate(double x
, double y
, double z
)
223 dBodySetPosition(body
,x
+x1
,y
+y1
,z
+z1
);
230 // if (Camera_follows_Translation)
233 glTranslated(-x,-y,-z);
241 void e3D_Object::Rotate(double angle
,double x
, double y
, double z
)
246 glRotated(angle,x,y,z);
249 // if (Camera_follows_Orientation)
252 glRotated(-angle,x,y,z);
258 glRotated(angle,x,y,z);
265 void e3D_Object::Scale(double x
, double y
, double z
)
272 void e3D_Object::BeginDraw()
274 // Code to execute when at the beginning of a block of objects
275 // Recommended: using glPus/PopAttrib prevents
276 // future problems when mixing render types
277 glPushAttrib(GL_ALPHA_TEST
| GL_POLYGON_SMOOTH
| GL_TEXTURE_2D
| GL_BLEND
);
278 /*glDisable(GL_ALPHA_TEST);
280 glEnable(GL_COLOR_MATERIAL);
282 glDisable(GL_LIGHTING);*/
286 void e3D_Object::EndDraw()
288 // Code to execute when at the beginning of a block of objects
292 void e3D_Object::Draw(int pass
) // Example implementation for draw
295 glColor4f(1.0f,1.0f,1.0f,1.0f);
297 glNormal3f( 0.0f, 0.0f, -1.0f);
298 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f);
299 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
300 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
301 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
306 e3D_Object
*e3D_Object::DrawBE(bool AutoBeginEnd
, e3D_Object
*o_begin
)
309 // As a parameter, an e3D_Object indicates from what object started
310 // drawing the loop. For Begin/End control purposes only.
315 if (o_begin
->ObjectClassname
!=ObjectClassname
)
324 o_begin
->BeginDraw();
332 e3D_Object
*e3D_Object::LocateAndDraw(bool AutoBeginEnd
, e3D_Object
*o_begin
)
336 o_begin
=DrawBE(AutoBeginEnd
,o_begin
);
342 void e3D_Object::ApplyGravityFrom(e3D_Object
*from
)
344 double Amass
=mass
.mass
,Bmass
=from
->mass
.mass
;
348 from
->GetXYZ(&Bx
,&By
,&Bz
);
350 double ABx
=Bx
-Ax
,ABy
=By
-Ay
,ABz
=Bz
-Az
;
351 double Rxy
=sqrt(ABx
*ABx
+ABy
*ABy
);
352 double R2
=Rxy
*Rxy
+ABz
*ABz
;
355 const double G
=.0000001; // Universal Gravitation constant
356 double N
=G
*Amass
*Bmass
/R2
; // Gravity force
357 //printf(" - %s - f: %.4f a:%.4f b:%.1f r:%.1f \n", ObjectClassname.c_str(),N,Amass,Bmass,R);
358 dBodyAddForceAtRelPos(body
,ABx
/R
*N
,ABy
/R
*N
,ABz
/R
*N
,0,0,-0.001);
362 void e3D_Object::ApplyGravityForces(e3D_Object
*o_begin
)
364 // Locates and draws all childrens.
365 //e3D_Object *obj=o_begin;
369 std::list
<e3D_Object
*>::iterator list_iter
;
370 for (list_iter
= o_begin
->children
.begin(); list_iter
!= o_begin
->children
.end(); list_iter
++)
377 e3D_Object
*e3D_Object::DrawChildren(
383 // Locates and draws all childrens.
384 e3D_Object
*obj
=o_begin
;
394 std::list
<e3D_Object
*>::iterator list_iter
;
396 for (list_iter
= children
.begin(); list_iter
!= children
.end(); list_iter
++)
400 // obj=c->LocateAndDraw(obj);
401 if (Recursive
) obj
=c
->DrawChildren(AutoBeginEnd
,true,true,obj
);
402 else obj
=c
->LocateAndDraw(obj
);
407 if (!o_begin
&& obj
&& AutoBeginEnd
)
419 e3D_Ship::e3D_Ship(e3D_Object
*parent
, const char *fileobj
, float size
) : e3D_Object(parent
)
422 Ship
.LoadObj(fileobj
,size
);
423 _shield_size
=shield_size
=6;
424 _bright_size
=bright_size
=0.1;
425 if (__E3D_ENGINE_DEBUG
) cout
<< "Create ship:" << fileobj
<< endl
;
427 quad
=gluNewQuadric();
428 gluQuadricOrientation(quad
, GLU_OUTSIDE
);
429 Shield
=new e3D_Sprite(this,"images/escudos.png");
430 Shield
->Scale(shield_size
,shield_size
,shield_size
);
432 Bright
=new e3D_Sprite(this,"images/particles/brightstar-256-128.png");
433 Bright
->Translate(0,0,100);
434 Bright
->Scale(bright_size
,bright_size
,bright_size
);
436 Bright2
=new e3D_Sprite(Bright
,"images/particles/hiddenplanet-256-128.png");
437 Bright2
->Translate(0,0,-4);
438 Bright2
->Scale(2,2,2);
440 geom
=dCreateSphere(Render
->space
,6);
441 dMassSetSphere(&mass
,10,6);
442 dGeomSetBody(geom
,body
);
443 // Camera_follows_Orientation=false;
452 set_engine_energy
=10;
455 ObjectClassname
="Ship";
458 void e3D_Ship::Draw(int pass
) // Example implementation for draw
460 const dReal
*AngularVel
, *LinearVel
;
462 AngularVel
=dBodyGetAngularVel(body
);
463 LinearVel
=dBodyGetLinearVel(body
);
465 double AngularVel_x
=AngularVel
[0],AngularVel_y
=AngularVel
[1],AngularVel_z
=AngularVel
[2];
466 double LinearVel_x
=LinearVel
[0],LinearVel_y
=LinearVel
[1],LinearVel_z
=LinearVel
[2];
469 lv
=sqrt(LinearVel_x
*LinearVel_x
+LinearVel_y
*LinearVel_y
);
470 lv
=sqrt(lv
*lv
+LinearVel_z
*LinearVel_z
);
472 if (rand()%5==0 && Render
->Camera
==this)
475 e3D_Shoot
*shoot
=new e3D_Shoot(
476 Render
->OG_Particles
,"images/particles/supernova-256-16.png",
479 camera_eyeX
+(rand()%200-100)/2.0,
480 camera_eyeY
+(rand()%200-100)/2.0,
481 camera_eyeZ
+(rand()%200-100)/2.0
488 dMassSetSphere(&(shoot
->mass
),1,4);
494 // Fricción simulada / irreal:
495 const double avd
=.500;
496 dBodyAddTorque(body
,-AngularVel_x
*avd
,-AngularVel_y
*avd
,-AngularVel_z
*avd
);
497 const double lvd
=.500;
498 dBodyAddForce(body
,-LinearVel_x
*lvd
,-LinearVel_y
*lvd
,-LinearVel_z
*lvd
);
499 double lv2
=sqrt(LinearVel_x
*lvd
*LinearVel_x
*lvd
+LinearVel_y
*lvd
*LinearVel_y
*lvd
);
500 lv2
=sqrt(lv2
*lv2
+LinearVel_z
*lvd
*LinearVel_z
*lvd
);
502 // ******************** FISICA
503 dBodyAddRelForce(body
,-dx
*(lvd
+1),-dy
*(lvd
+1),-dz
*(lvd
+1)-lv2
);
504 dBodyAddRelTorque(body
,-rx
*(avd
+1),-ry
*(avd
+1),-rz
*(avd
+1));
505 float rxy
=sqrt(rx
*rx
+ry
*ry
);
506 float rxyz
=sqrt(rz
*rz
+rxy
*rxy
);
507 used_fuel
+=rxyz
/10.0;
509 float dxy
=sqrt(dx
*dx
+dy
*dy
);
510 float dxyz
=sqrt(dz
*dz
+dxy
*dxy
);
511 used_fuel
+=dxyz
/10.0;
513 //if (!pass || pass==PASS_SOLIDOBJECTS)
514 energy
+=2+_shield_size
/(energy
/set_inc_energy
+1);
515 /*energy-=fabs(dz)*set_engine_energy*dfriction;
516 energy-=fabs(dx)*set_engine_energy*dfriction;
517 energy-=fabs(dy)*set_engine_energy*dfriction;
519 energy-=fabs(rz)*set_rotor_energy*rfriction;
520 energy-=fabs(rx)*set_rotor_energy*rfriction;
521 energy-=fabs(ry)*set_rotor_energy*rfriction;
538 if (energy
>maxenergy
) energy
=maxenergy
;
542 glDisable(GL_COLOR_MATERIAL
);
543 glEnable(GL_LIGHTING
);
546 _vel
=sqrt(LinearVel_x
*LinearVel_x
+LinearVel_y
*LinearVel_y
);
547 _vel
=sqrt(_vel
*_vel
+LinearVel_z
*LinearVel_z
);
550 bright_size*=bright_size;
552 if (bright_size<0.01) bright_size=0.01;
553 if (bright_size>100) bright_size=100;*/
554 /*Translate(-dx,-dy,-dz);
564 Scale(0.992,0.992,0.992);
565 Shield
->Scale(1.05,1.05,1.05);
566 Bright
->Scale(0.95,0.95,0.95);
567 Bright2
->Scale(1.01,1.01,1.01);
576 rx
/=1+rfriction
+bright_size
/100.0;
577 ry
/=1+rfriction
+bright_size
/100.0;
578 rz
/=1+rfriction
+bright_size
/100.0;
580 ApplyGravityForces(Render
->OG_Planets
);
581 // ***************************
582 if (_bright_size
<0.1) shield_size
+=hull
/(shield_size
)/1000.0;
583 if (_bright_size
<0.1 && shield_size
>50) shield_size
/=1+(shield_size
-15)/5000.0;
584 if (shield_size
>hull
*2) shield_size
/=1.001;
585 if (shield_size
<hull
/5.0) shield_size
=hull
/5.0;
586 if (shield_size
!=_shield_size
)
588 double rx
=shield_size
/_shield_size
;
593 Shield
->Scale(rx
,rx
,rx
);
596 if (bright_size
!=_bright_size
)
598 double rx
=bright_size
/_bright_size
;
599 Bright2
->angle
+=rx
*rx
-0.95;
603 Bright
->angle
-=rx
*rx
-0.98;
606 if (rx
<1) shield_size
-=1-rx
; else shield_size
/=rx
+.001;
608 Bright
->Scale(rx
,rx
,rx
);
616 void e3D_Ship::Shoot(int type
)
622 shoot
=new e3D_Shoot(Render
->OG_Particles
,"images/particles/shoot1.png",1,15);
623 shoot
->ResetAtBody(this->body
,0,0,-2-8-5);
627 shoot
->geom
=dCreateSphere(Render
->space
,5);
628 dGeomSetBody(shoot
->geom
,shoot
->body
);
629 dMassSetSphere(&(shoot
->mass
),100,40);
633 shoot
=new e3D_Shoot(Render
->OG_Particles
,"images/particles/shoot1.png",1,.1);
634 shoot
->ResetAtBody(this->body
,0,0,-1-5-1);
636 shoot
->geom
=dCreateSphere(Render
->space
,0.5);
637 dGeomSetBody(shoot
->geom
,shoot
->body
);
638 dMassSetSphere(&(shoot
->mass
),1,4);