Morph-SynRJ
view efx_touf.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_touf.h"
2 #include "gl_header.h"
4 efxToufElement_t::efxToufElement_t()
5 {
6 elements=0;
7 springs=0;
8 }
11 void efxToufElement_t::Kill()
12 {
13 if (elements)
14 delete [] elements;
15 elements=0;
17 if (springs)
18 delete [] springs;
19 springs=0;
20 }
22 #if 0 //not used
23 void efxToufElement_t::ApplyRotation(const mth::Quaternion_t& _q)
24 {
25 elements[0].Position(_q.Rotate(elements[0].Position()));
26 elements[0].Velocity(_q.Rotate(elements[0].Velocity()));
27 }
28 #endif
30 void efxToufElement_t::Init(int _section)
31 {
32 Kill();
33 nbSections=_section;
35 elements=new phy::Element_t[nbSections];
36 springs=new phy::SpringDamper_t[nbSections];
38 #ifdef USE_QUALITY_TOUFS
39 spline= new mth::Hermite_t(nbSections+1);
40 keyData=new mth::HermiteKey_t[nbSections+1];
41 #endif
42 }
45 void efxToufElement_t::ApplyForce(const mth::Vector3_t& _force)
46 {
47 for (int i=0;i<nbSections;i++)
48 elements[i].ApplyForce(_force);
49 }
52 void efxToufElement_t::AddSphercialForce()
53 {
54 // return;
55 for (int i=0;i<nbSections;i++)
56 elements[i].ApplyForce(initialDirection*(elements[i].Mass()*100*1.0/(i+1)));
57 }
61 void efxToufElement_t::InitData(const mth::Vector3_t& _start,float _massPerTouf)
62 {
63 initialDirection=_start;
65 float l=_start.Mag()*1.0;
66 mth::Vector3_t vec=_start;
67 //float massStart=_massPerTouf;
68 for (int i=0;i<nbSections;i++) {
69 elements[i].Position(vec);
70 vec+=_start;
71 elements[i].Mass(_massPerTouf/nbSections);
72 // massStart*=0.8;
73 // elements[i].Mass(massStart);
74 // springs[i].Init(/*32*8*/ 256*2,50,l);
75 // springs[i].Init(1000,30,l);
76 // springs[i].Init(1000,10,l);
77 // springs[i].Init(200,5,l);
78 springs[i].Init(1000,5,l);
80 #ifdef USE_QUALITY_TOUFS
81 spline->AddKey(&keyData[i]);
82 #endif
84 }
85 }
88 void efxToufElement_t::RegisterElements(phy::Server_t& _server,phy::Element_t* _central)
89 {
91 springs[0].Init(_central,&elements[0]);
92 _server.AddElement(&elements[0]);
93 _server.AddLink(&springs[0]);
94 for (int i=1;i<nbSections;i++) {
95 springs[i].Init(&elements[i-1],&elements[i]);
97 _server.AddElement(&elements[i]);
98 _server.AddLink(&springs[i]);
99 }
100 }
103 void efxToufElement_t::ApplyDrag()
104 {
105 const float InternalDragCoef=0.3;
106 mth::Vector3_t f;
107 for (int i=0;i<nbSections;i++) {
108 f=elements[i].Velocity();
109 f*=-0.3;
110 elements[i].ApplyForce(f);
111 }
112 }
116 void efxToufElement_t::Draw(const mth::Vector3_t& _central,float _radius,float _scaleColor,float* _tint)
117 {
119 float a;
120 _radius*=0.8; // factor to attenuate color quickely
121 _radius*=nbSections;
122 _radius*=_radius;
124 int i;
126 #ifdef USE_QUALITY_TOUFS
127 const float div=1.0/(nbSections-1);
128 keyData[0].Init(0,_central);
129 for (i=1;i<nbSections+1;i++)
130 keyData[i].Init(i*div,elements[i].Position());
133 mth::Vector3_t tmp,tmpPrev=_central;
134 const int SectionSpline=30;
135 const float SectionSplineDiv=1.0/(SectionSpline+2);
136 for (i=0;i<SectionSpline;i++) {
137 spline->GetData((i+1)*SectionSplineDiv,tmp);
139 a=_radius-_central.DistSqr(tmp);
140 a/=_radius;
141 a=mth::Clamp(a*_scaleColor,0,1.0);
142 glColor3f(a*_tint[0],a*_tint[1],a*_tint[2]);
143 #ifdef POLYGON_MODEL
144 mth::Vector3_t dir=tmp;
145 dir[1]+=0.5;
146 glVertex3fv(tmp);
147 glColor3f(a*_tint[0],a*_tint[1],a*_tint[2]);
148 glVertex3fv(dir);
149 #else
150 glVertex3fv(tmp);
151 #endif
152 }
156 #else
158 for (i=0;i<nbSections;i++) {
159 a=_radius-_central.DistSqr(elements[i].Position());
160 a/=_radius;
161 // a*=255;
162 a=mth::Clamp(a*_scaleColor,0,1.0);
163 glColor3f(a*_tint[0],a*_tint[1],a*_tint[2]);
164 glVertex3fv(elements[i].Position());
165 }
166 #endif
168 }
174 efxTouf_t::efxTouf_t()
175 {
176 elements=0;
177 tint[0]=1.0;
178 tint[1]=1.0;
179 tint[2]=1.0;
180 }
183 void efxTouf_t::Kill()
184 {
185 if (elements)
186 delete [] elements;
187 elements=0;
188 }
191 #if 0 //not used
192 void efxTouf_t::ApplyRotation(const mth::Quaternion_t& _q)
193 {
194 for (int j=0;j<nbElements;j++) {
195 elements[j].ApplyRotation(_q);
196 }
198 }
199 #endif
201 void efxTouf_t::Init(int _widthResolution,int _heightResolution,int _section,float _radius)
202 {
203 Kill();
205 sizex=_widthResolution;
206 sizey=_heightResolution;
207 nbElements=sizex*sizey;
208 radius=_radius;
210 elements=new efxToufElement_t[nbElements];
212 int i;
213 for (i=0;i<nbElements;i++) {
214 elements[i].Init(_section);
215 elements[i].RegisterElements(server,¢ral);
216 }
219 mth::Vector3_t startPosition(0,0,0);
221 // init the center of the touf
222 central.Position(startPosition);
223 central.Mass(3);
224 central.Blocked();
226 int j;
227 for (j=0;j<sizey;j++)
228 for (i=0;i<sizex;i++) {
229 InitPosition(_radius,i,j,startPosition);
230 elements[i+j*sizex].InitData(startPosition,5);
231 }
232 }
236 void efxTouf_t::Update(double _dt)
237 {
240 const double IntegrationTime=1e-2;
242 //#define TEST
243 #ifdef TEST
244 static int testToRemove=0;
245 testToRemove++;
247 mth::Vector3_t vel=-central.Position();
248 mth::Vector3_t v(0,0,0);
249 v[0]=50*mth::Cos(1.0*testToRemove/50);
250 vel+=v;
252 central.Position(v);
253 central.Velocity(vel/_dt*0.5);
254 #endif
256 int nbIntegrations=mth::Floor(_dt/IntegrationTime);
258 for (int i=0;i<nbIntegrations;i++) {
259 server.StartForceSession();
260 for (int j=0;j<nbElements;j++) {
261 elements[j].AddSphercialForce();
262 elements[j].ApplyForce(force);
263 elements[j].ApplyDrag();
264 }
265 server.EndForceSession();
266 server.Try1(IntegrationTime);
267 }
269 double notFinished=_dt-nbIntegrations*IntegrationTime;
270 if (notFinished>1e-5) {
271 server.StartForceSession();
272 for (int j=0;j<nbElements;j++) {
273 elements[j].AddSphercialForce();
274 elements[j].ApplyForce(force);
275 elements[j].ApplyDrag();
276 }
277 server.EndForceSession();
278 server.Try1(notFinished);
279 }
282 force.Init();
283 }
288 void efxTouf_t::Draw(float _scaleColor)
289 {
291 // glEnable(GL_BLEND);
293 // glEnable(GL_LINE_SMOOTH);
294 // glLineWidth(1.0);
297 #ifndef POLYGON_MODEL
299 for (int i=0;i<nbElements;i++) {
300 glBegin(GL_LINE_STRIP);
301 glColor3f(tint[0],tint[1],tint[2]);
302 glVertex3fv(central.Position());
303 elements[i].Draw(central.Position(),radius,_scaleColor,tint);
304 glEnd();
305 }
306 #else
308 for (int i=0;i<nbElements;i++) {
309 glBegin(GL_QUAD_STRIP);
310 glColor3f(tint[0],tint[1],tint[2]);
311 glVertex3fv(central.Position());
312 glColor3f(tint[0],tint[1],tint[2]);
313 glVertex3fv(central.Position()+mth::Vector3_t(0,0.5,0));
314 elements[i].Draw(central.Position(),radius,_scaleColor,tint);
315 glEnd();
316 }
318 #endif
321 #if 0
322 for (int i=0;i<nbElements;i++) {
323 glBegin(GL_LINE_STRIP);
324 glVertex3fv(central.Position());
325 elements[i].Draw();
326 glEnd();
327 }
328 #endif
331 }
334 void efxTouf_t::InitPosition(float _radius,float _u,float _v,mth::Vector3_t& _result)
335 {
336 double du=1.0/sizex;
337 double dv=1.0/(sizey);
339 _result.Init(
340 _radius * mth::Cos(mth::TWOPI * _u * du) * mth::Sin(mth::PI * _v * dv),
341 _radius * mth::Cos( mth::PI * _v * dv) ,
342 _radius * mth::Sin(2 * mth::PI * _u * du) * mth::Sin( mth::PI * _v * dv)
343 );
344 }
