Morph-SynRJ

view efx_screen2.cxx @ 0:22de913c2d84

morph-synrj intro
author "Cedric Pinson <cedric.pinson@alcove.fr> <mornifle@plopbyte.net>"
date Tue Nov 27 15:23:52 2007 +0100 (2007-11-27)
parents
children
line source
1 #include "efx_screen2.h"
2 #include "sys_assert.h"
3 #include "mth_vector3.h"
4 #include "gl_header.h"
5 #include "cmn_intro.h"
7 // sync
8 extern fxSync * sync;
10 efxScreen2_t::efxScreen2_t()
11 {
12 textureForSpherical=0;
13 spherical=0;
14 currentShapeToMorph=0;
15 morphFrac=0;
18 stepDanceYTargetPosition=0;
19 stepDanceDirection=0;
20 toufForce.Init();
21 internalTime=0;
22 textureTouf=0;
24 endPart=false;
25 restingTime=0;
27 }
33 void efxScreen2_t::InitDesign()
34 { //0123456789a
36 const int NbDesignElements=16;
37 const float QuadSizeX = 100;
38 const float QuadSizeY = 100;
39 const float DelayStart=0.1;
40 const float StartPositionX=-1000;
41 const float OffsetY=0.14;
42 const float ResizeElement = 0.1;
43 const float Space = 0.8;
44 const float baseColor[3]={0.1,0.1,0.1};
46 design.Init(NbDesignElements);
47 designElements=new cmnDesignElementTexturedQuad_t[NbDesignElements];
49 GLuint tex=txtCreateTextureCircular(128,128,1.0);
51 float currentPosx=0;
52 float currentPosy=0;
53 float currentSizeX=QuadSizeX ;
54 float currentSizeY=QuadSizeY ;
55 int half=NbDesignElements/2;
56 int index=0;
58 for (int i=0;i<half;i++) {
60 designElements[index+i].texture=tex;
61 designElements[index+i].Init(
62 3.0+i*0.1,
63 mth::Vector3_t(StartPositionX,OffsetY*RY,0),
64 mth::Vector3_t(currentPosx,OffsetY*RY,0),10);
66 designElements[index+i].sizex=currentSizeX;
67 designElements[index+i].sizey=currentSizeY;
68 designElements[index+i].Color(baseColor[0],baseColor[1],baseColor[2]);
69 currentPosx+=currentSizeX*Space;
70 currentSizeX=currentSizeX*(1.0-ResizeElement);
71 currentSizeY=currentSizeY*(1.0-ResizeElement);
72 design.AddElement(&designElements[index+i]);
73 }
74 index+=i;
77 currentPosx=0;
78 currentSizeX=QuadSizeX;
79 currentSizeY=QuadSizeY ;
81 //currentPosy=RY-QuadSizeY;
82 for (i=0;i<half;i++) {
83 designElements[index+i].texture=tex;
84 designElements[index+i].Init(
85 3.0+i*0.1,
86 mth::Vector3_t(-StartPositionX,RY-OffsetY*RY-currentSizeY,0),
87 mth::Vector3_t(RX-currentPosx-currentSizeX,RY-OffsetY*RY-currentSizeY,0),10);
89 designElements[index+i].sizex=currentSizeX;
90 designElements[index+i].sizey=currentSizeY;
91 designElements[index+i].Color(baseColor[0],baseColor[1],baseColor[2]);
92 currentPosx+=currentSizeX*Space;
93 currentSizeX=currentSizeX*(1.0-ResizeElement);
94 currentSizeY=currentSizeY*(1.0-ResizeElement);
95 design.AddElement(&designElements[index+i]);
96 }
98 }
104 void efxScreen2_t::Init()
105 {
106 // Spherical harmonics meshs init
107 int size=256;
108 float div=1.0/size;
109 textureForSpherical=txtCreatePerlin2d(size,size,div,div);
111 spherical=new efxSpherical_t;
112 #ifdef HIGHRES
113 const int ResConfig=100;
114 #else
115 #ifdef MIDDLERES
116 const int ResConfig=80;
117 #endif
118 #endif
119 spherical->Init(7,ResConfig,20);
121 bool order=true;
122 radius=150;
123 spherical->Shape(6).Params(4,4,0,0,2,0,0,0);
124 spherical->Shape(6).Generate(radius,order); // generate a shape with reverse normal
125 spherical->Shape(5).Params(6,6,0,0,2,0,0,0);
126 spherical->Shape(5).Generate(radius,order); // generate a shape with reverse normal
127 spherical->Shape(4).Params(2,2,6,4,2,4,0,0);
128 spherical->Shape(4).Generate(radius,order); // generate a shape with reverse normal
129 spherical->Shape(3).Params(2,2,6,4,0,2,0,0);
130 spherical->Shape(3).Generate(radius,order); // generate a shape with reverse normal
131 spherical->Shape(2).Params(2,2,4,4,0,0,4,2);
132 spherical->Shape(2).Generate(radius,order); // generate a shape with reverse normal
133 spherical->Shape(1).Params(2,2,4,0,0,0,4,2);
134 spherical->Shape(1).Generate(radius,order); // generate a shape with reverse normal
135 spherical->Shape(0).Params(0,4,4,0,2,0,0,0);
136 spherical->Shape(0).Generate(radius,order); // generate a shape with reverse normal
138 spherical->SetTexture(textureForSpherical);
141 // touf init
142 InitToufs(5);
145 // init path
146 // path.Init(4096);
149 // camera init
150 const int CameraNbKeys=15;
151 const float CameraKeyTime=1.5;
152 camera.Init(0,0,-90);
153 lookat.Init(0,0,0);
155 cameraPath= new mth::Hermite_t(CameraNbKeys*2);
156 cameraKeyData= new mth::HermiteKey_t[CameraNbKeys];
157 mth::Vector3_t cpos[CameraNbKeys]= {
158 camera,
159 mth::Vector3_t(10,10,-90),
160 mth::Vector3_t(0,30,-60),
161 mth::Vector3_t(-30,30,-30),
162 mth::Vector3_t(-60,20,-10),
163 mth::Vector3_t(-90,0,0),
164 mth::Vector3_t(-70,-10,10),
165 mth::Vector3_t(-50,-40,40),
166 mth::Vector3_t(-40,-50,70),
167 mth::Vector3_t(-30,-80,90),
168 mth::Vector3_t(-20,-60,50),
169 mth::Vector3_t(-10,-30,20),
170 mth::Vector3_t(0,-10,-10),
171 mth::Vector3_t(0,0,-50),
172 mth::Vector3_t(0,0,-90)};
174 for (int i=0;i<CameraNbKeys;i++) {
175 cameraKeyData[i].Init(CameraKeyTime*i,cpos[i]);
176 cameraPath->AddKey(&cameraKeyData[i]);
177 }
179 InitDesign();
181 scroller.Init(textureForSpherical);
182 scroller.ScrollX(1);
183 scroller.ScrollY(0.5);
184 }
189 void efxScreen2_t::GetRandomPos(float _rangeRandomRadius,float _distmin,const mth::Vector3_t& _fromPosition,mth::Vector3_t& _result)
190 {
191 for (int j=0;j<100;j++) {
192 _result.InitRandomVectorInBox(_rangeRandomRadius);
193 if (_result.DistSqr(_fromPosition)>_distmin*_distmin && _result.DistSqr(_fromPosition)<150*150)
194 break;
195 }
196 }
199 void efxScreen2_t::InitToufs(int _nbToufs)
200 {
202 #ifdef HIGHRES
203 const int VToufsSection=12; //12; //15
204 const int HToufsSection=12; //12; //15
205 const int SToufsSection=10; //10;
206 #else
207 #ifdef MIDDLERES
208 const int VToufsSection=11; //12; //15
209 const int HToufsSection=11; //12; //15
210 const int SToufsSection=9; //10;
211 #endif
212 #endif
215 const float RandomDistFromMum=120;
216 const float RandomMinDistFromMum=80;
217 // const float RandomDistFromMum=50;
218 // const float RandomMinDistFromMum=80;
219 const float RandomMinimumDistForMum=10;
220 // const float StepTimeOfKeyFrame=1.5;
221 const float StepTimeOfKeyFrame=2.0;
222 // const float StepTimeOfKeyFrame=3.0;
224 typedef mth::Hermite_t* Hptr_t;
225 nbKeys=60;
227 nbToufs=_nbToufs;
228 touffus=new efxTouf_t[nbToufs];
229 SYS_ASSERT(touffus);
231 // use a spline for mum touf
232 toufPaths=new Hptr_t[nbToufs];
235 touffus[0].Init(VToufsSection,HToufsSection,SToufsSection,3.0); // mum touf is bigger than her children
236 toufPaths[0]=new mth::Hermite_t(nbKeys*4);
237 for (int i=1;i<nbToufs;i++) {
238 touffus[i].Init(VToufsSection,HToufsSection,SToufsSection,3.0);
239 // touffus[i].SetTint(0.2,0.2,0.7);
240 // touffus[i].SetTint(239.0/255,150.0/255,26.0/255);
241 touffus[i].SetTint(219.0/255,127.0/255,13.0/255);
242 toufPaths[i]=new mth::Hermite_t(nbKeys*4);
243 }
245 keyData=new mth::HermiteKey_t[nbKeys*nbToufs];
246 float a[3];
247 mth::Vector3_t tmpPos;
248 mth::Vector3_t tmpPrevPos(0,0,0);
249 mth::Vector3_t tmpPos2;
251 float minFromMum;
252 float minForMum;
253 float maxRadius;
254 float stepTime;
255 float currentTime=0;
256 for (i=0;i<nbKeys-1;i++) {
257 maxRadius=radius;
258 minFromMum=RandomDistFromMum;
259 minForMum=RandomMinimumDistForMum;
260 stepTime=StepTimeOfKeyFrame;
262 // one key on two I made a small and a large step
263 if (i%2==0) {
264 maxRadius*=0.5;
265 minForMum*=0.5;
266 stepTime*=2;
267 } else {
268 maxRadius*=0.8;
269 minForMum*=0.8;
270 //stepTime*=2;
271 }
273 GetRandomPos(maxRadius,minForMum,tmpPrevPos,tmpPos);
274 tmpPrevPos=tmpPos;
276 keyData[i].Init(currentTime,tmpPos);
277 toufPaths[0]->AddKey(&keyData[i]);
278 for (int k=1;k<nbToufs;k++) {
279 tmpPos2.InitRandomVectorInBox(minFromMum);
280 GetRandomPos(minFromMum,minFromMum,tmpPrevPos,tmpPos2);
281 keyData[i+k*nbKeys].Init(currentTime,tmpPos+tmpPos2);
282 toufPaths[k]->AddKey(&keyData[i+k*nbKeys]);
283 }
284 currentTime+=stepTime;
286 }
288 toufStartMoving=1;
290 textureTouf=txtCreateTextureCircular(256,256,0.9,1);
291 }
293 #if 0
294 void efxScreen2_t::DrawPath()
295 {
296 glColor3f(1,1,1);
297 glBegin(GL_LINE_STRIP);
298 for (int i=0;i<path.NbCurrentVertexes();i++)
299 glVertex3fv(path.GetReverseVertex(i));
300 glEnd();
301 }
302 #endif
305 void efxScreen2_t::UpdateToufs()
306 {
307 const float DragForceScale=0.4;
309 HandleToufs();
311 for (int i=0;i<nbToufs;i++) {
312 touffus[i].ApplyForce(-touffus[i].Element().Velocity()*DragForceScale+toufForce); // apply a drag force
313 touffus[i].Update(Timer->GetFrameTime());
314 }
316 toufForce.Init();
318 }
323 void efxScreen2_t::HandleToufs()
324 {
325 const double WaitStart=1;
326 const double TimeDanceStart=1;
327 const double TimeDanceEnd=25;
328 const double TimeMoveCameraStart=7;
329 const double TimeMoveCameraEnd=86;
330 const double TimeMoveToufsStart=12;
331 const double TimeMoveToufsEnd=86;
333 const float DistFromMum=30;
336 // fixe position at start
337 if (internalTime<WaitStart) {
338 touffus[0].Element().Position().Init();
339 touffus[0].Element().Velocity().Init();
341 int nb=(nbToufs-1)/2;
342 int index=1;
343 float sign=1;
344 for (int j=0;j<2;j++) {
345 if (j==1)
346 sign=-1;
347 for (int i=0;i<nb;i++) {
348 touffus[index].Element().Position().Init(sign*DistFromMum*(i+1),0,0);
349 touffus[index].Element().Velocity().Init();
350 index++;
351 }
352 }
354 } /* else if (internalTime>=TimeDanceStart && internalTime < TimeDanceEnd ) {
355 sync->SyncSnareTouf();
356 //HandleSnareSound();
357 }*/
359 if (internalTime>=TimeMoveCameraStart && internalTime < TimeMoveCameraEnd)
360 HandleCameraMoving(internalTime-TimeMoveCameraStart);
362 if (internalTime>=TimeMoveToufsStart && internalTime < TimeMoveToufsEnd ) {
363 HandleToufsMoving(internalTime-TimeMoveToufsStart);
364 HandleCameraTarget();
365 }
369 // if (internalTime>WaitStart) {
370 sync->SyncWindTouf();
371 //HandleWindSound();
372 // }
375 }
380 void efxScreen2_t::HandleWindSound()
381 {
382 const float WindForce=600;
383 const double WindTime=3;
385 #if 0
386 static double time=0;
387 time+=Timer->GetFrameTime();
388 double nb=time/WindTime;
389 int n= mth::Floor(nb);
391 mth::Vector3_t f;
392 for (int i=0;i<n;i++) {
393 f.InitRandomVectorInBox(5);
394 f.Normalize();
395 toufForce+=f*WindForce;
396 }
397 time=mth::Frac(nb)*WindTime;
398 #else
399 mth::Vector3_t f;
400 f.InitRandomVectorInBox(5);
401 f.Normalize();
402 toufForce+=f*WindForce;
403 #endif
405 }
408 void efxScreen2_t::HandleCameraTarget()
409 {
410 mth::Vector3_t cmin(1e5,1e5,1e5);
411 mth::Vector3_t cmax(-cmin);
412 for (int i=0;i<nbToufs;i++)
413 for (int j=0;j<3;j++) {
414 cmin[j]=mth::Min(cmin[j],touffus[0].Element().Position()[j]);
415 cmax[j]=mth::Max(cmax[j],touffus[0].Element().Position()[j]);
416 }
418 cmax-=cmin;
419 cmin+=cmax*0.5;
420 lookat=cmin;
421 }
424 void efxScreen2_t::HandleCameraMoving(double _time)
425 {
426 mth::Vector3_t result;
427 cameraPath->GetData(_time,result);
428 camera=result;
429 }
433 void efxScreen2_t::HandleToufsMoving(double _time)
434 {
436 // set up the first keyframe of splines
437 if (toufStartMoving) {
438 for (int k=0;k<nbToufs;k++)
439 keyData[0+k*nbKeys].Data()=touffus[k].Element().Position();
440 toufStartMoving=0;
441 }
445 mth::Vector3_t result;
446 mth::Vector3_t currentPos;
447 mth::Vector3_t pos;
448 for (int i=0;i<nbToufs;i++) {
449 currentPos=touffus[i].Element().Position();
450 toufPaths[i]->GetData(_time,result);
452 if (endPart) {
453 result=currentPos+(camera-currentPos)*Timer->GetFrameTime()*1.0/restingTime;
454 }
456 pos=(result-currentPos)*1.0/Timer->GetFrameTime();
457 touffus[i].Element().Velocity(pos);
458 touffus[i].Element().Position(result);
459 }
461 }
466 void efxScreen2_t::DrawParticle(float _r,
467 float _g,
468 float _b,
469 float _alpha,
470 int _i,
471 const mth::Vector3_t& _v0,
472 const mth::Vector3_t& _v1)
473 {
474 glColor4f(_r,_g,_b,_alpha);
475 glBegin(GL_QUADS);
476 glTexCoord2f(0,0);
477 glVertex3fv(touffus[_i].Element().Position()-_v0-_v1);
478 glTexCoord2f(0,1);
479 glVertex3fv(touffus[_i].Element().Position()+_v0-_v1);
480 glTexCoord2f(1,1);
481 glVertex3fv(touffus[_i].Element().Position()+_v0+_v1);
482 glTexCoord2f(1,0);
483 glVertex3fv(touffus[_i].Element().Position()-_v0+_v1);
484 glEnd();
485 }
488 void efxScreen2_t::DrawToufs()
489 {
490 const float ScaleColor=0.6;
491 const float ScaleLine=10;
493 #ifndef FINALE_RELEASE
494 cmnPushMatrix();
495 cmnSetPlanarView();
496 font->Clear();
497 font->Print("time %f\n",Timer->GetRealTime());
498 cmnPopMatrix();
499 #endif
500 glMatrixMode(GL_MODELVIEW);
503 glEnable(GL_BLEND);
504 glBlendFunc(GL_ONE,GL_ONE);
506 #define USE_PARTICULE
508 #ifdef USE_PARTICULE
509 float m[16];
510 glGetFloatv(GL_MODELVIEW_MATRIX,m);
511 mth::Vector3_t v[4];
512 v[0].Init(m[0],m[4],m[8]);
513 v[1].Init(m[1],m[5],m[9]);
514 // v[2].Init(m[2],m[6],m[10]);
515 v[2]=v[0];
516 v[3]=v[1];
517 v[0]*=5;
518 v[1]*=5;
519 v[2]*=1.5;
520 v[3]*=1.5;
522 #endif
524 for (int i=0;i<nbToufs;i++) {
525 #if 0 // enable it for better GPU
526 glEnable(GL_LINE_SMOOTH);
527 float a=camera.Dist(touffus[i].Element().Position());
528 glLineWidth(ScaleLine*1.0/a);
529 touffus[i].Draw(ScaleColor);
530 glLineWidth(0.5*ScaleLine*1.0/a);
531 touffus[i].Draw(ScaleColor);
532 #else
533 touffus[i].Draw(ScaleColor);
534 #endif
536 #ifdef USE_PARTICULE // enable a particule for toufs
537 // draw a srpite at the center of the toufs
538 txtBindTexture2d(textureTouf,0);
539 glDisable(GL_DEPTH_TEST);
540 #if 1
542 mth::Vector3_t color;
543 if (i==0)
544 color.Init(1,1,1);
545 else
546 color.Init(219.0/255,127.0/255,13.0/255);
548 DrawParticle(color[0],color[1],color[2],1,i,v[2],v[3]);
549 color*=0.5;
550 DrawParticle(color[0],color[1],color[2],0.01,i,v[0],v[1]);
552 #else
553 for (int t=0;t<4;t+=2) {
554 glColor4f(0.5+t,0.5+t,0.5+t,0.01+t);
555 glBegin(GL_QUADS);
556 glTexCoord2f(0,0);
557 glVertex3fv(touffus[i].Element().Position()-v[t+0]-v[t+1]);
558 glTexCoord2f(0,1);
559 glVertex3fv(touffus[i].Element().Position()+v[t+0]-v[t+1]);
560 glTexCoord2f(1,1);
561 glVertex3fv(touffus[i].Element().Position()+v[t+0]+v[t+1]);
562 glTexCoord2f(1,0);
563 glVertex3fv(touffus[i].Element().Position()-v[t+0]+v[t+1]);
564 glEnd();
565 }
566 #endif
567 txtUnBindTexture2d(0);
568 glEnable(GL_DEPTH_TEST);
569 #endif
570 }
572 glDisable(GL_BLEND);
573 }
577 void efxScreen2_t::UpdateSpherical()
578 {
580 const float MorphAdd = 0.5;
581 morphFrac+=MorphAdd *Timer->GetFrameTime();
582 if (morphFrac>1.0) {
583 morphFrac=0;
584 currentShapeToMorph++;
585 }
587 spherical->MakeMorph(currentShapeToMorph%spherical->NbShapes(),(currentShapeToMorph+1)%spherical->NbShapes(),morphFrac);
589 }
591 void efxScreen2_t::DrawSpherical()
592 {
593 cmnPushMatrix();
594 glShadeModel(GL_SMOOTH);
595 txtBindTexture2d(textureForSpherical,0);
596 spherical->MorphShape().Draw();
597 txtUnBindTexture2d(0);
598 cmnPopMatrix();
599 }
603 void efxScreen2_t::Update()
604 {
605 internalTime+=Timer->GetFrameTime();
607 UpdateSpherical();
608 UpdateToufs();
609 design.Update();
610 scroller.Update();
611 }
614 void efxScreen2_t::Draw()
615 {
616 cmnPushMatrix();
617 cmnSetFrustrum(90);
620 glEnable(GL_LIGHTING);
621 glEnable(GL_LIGHT0);
623 float light[4]={0.0,0.0,1,0};
624 glLightfv(GL_LIGHT0,GL_POSITION,light);
626 // light[0]=167.0/255;light[1]=92.0/255;light[2]=5.0/255;
627 light[0]=33.0/255;light[1]=137.0/255;light[2]=255/255;
628 glLightfv(GL_LIGHT0,GL_DIFFUSE,light) ;
630 // light[0]=167.0/2550;light[1]=92.0/2550;light[2]=5.0/2550;
631 light[0]=0;light[1]=0;light[2]=0;
632 glLightfv(GL_LIGHT0,GL_AMBIENT,light) ;
634 cmnSetCamera (camera,lookat);
636 #ifndef _DEBUG
637 DrawSpherical();
638 #endif
640 glDisable(GL_LIGHT0);
641 glDisable(GL_LIGHTING);
643 DrawToufs();
645 //UpdatePath(); for debugging path of toufs
647 glDisable(GL_DEPTH_TEST);
648 glColor4f(0.1,0.1,0.1,1);
649 glEnable(GL_BLEND);
650 glBlendFunc(GL_ONE,GL_ONE);
651 cmnSetPlanarView();
652 design.Draw();
655 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
656 glColor4f(1,1,1,0.2);
657 scroller.Draw();
659 cmnPopMatrix();
660 }