Merge branch 'ryzom/ark-features' into main/gingo-test
[ryzomcore.git] / nel / src / 3d / ps_util.cpp
blobefeaf2125bb329528b585a909d64bac518e3bdf1
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010-2015 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
20 #include "nel/misc/aabbox.h"
21 #include "nel/misc/matrix.h"
23 #include "nel/3d/ps_util.h"
24 #include "nel/3d/particle_system.h"
25 #include "nel/3d/driver.h"
26 #include "nel/3d/vertex_buffer.h"
27 #include "nel/3d/index_buffer.h"
28 #include "nel/3d/material.h"
29 #include "nel/3d/nelu.h"
30 #include "nel/3d/font_generator.h"
31 #include "nel/3d/font_manager.h"
32 #include "nel/3d/computed_string.h"
33 #include "nel/3d/dru.h"
34 #include "nel/3d/ps_located.h"
35 #include "nel/3d/ps_sound.h"
36 #include "nel/3d/ps_light.h"
39 #include "nel/3d/particle_system_shape.h"
42 #ifdef DEBUG_NEW
43 #define new DEBUG_NEW
44 #endif
46 namespace NL3D {
49 using NLMISC::CVector;
52 //#ifdef NL_DEBUG
53 bool CPSUtil::_CosTableInitialized = false;
54 bool CPSUtil::_PerlinNoiseTableInitialized = false;
55 //#endif
57 float CPSUtil::_CosTable[256];
58 float CPSUtil::_SinTable[256];
59 float CPSUtil::_PerlinNoiseTab[1024];
64 //==========================================================================
65 void CPSUtil::initPerlinNoiseTable(void)
67 NL_PS_FUNC(CPSUtil_initPerlinNoiseTable)
68 for (uint32 k = 0; k < 1024; ++k)
70 _PerlinNoiseTab[k] = (rand() % 30000) / 30000.f;
72 //#ifdef NL_DEBUG
73 _PerlinNoiseTableInitialized = true;
74 //#endif
77 //==========================================================================
78 void CPSUtil::initFastCosNSinTable(void)
80 NL_PS_FUNC(CPSUtil_initFastCosNSinTable)
81 for (uint32 k = 0; k < 256; k++)
83 const float angle = k / 256.0f * 2.0f * float(NLMISC::Pi);
84 _CosTable[k] = (float) cos( angle );
85 _SinTable[k] = (float) sin( angle );
87 //#ifdef NL_DEBUG
88 _CosTableInitialized = true;
89 //#endif
92 //==========================================================================
93 void CPSUtil::registerSerialParticleSystem(void)
95 NL_PS_FUNC(CPSUtil_registerSerialParticleSystem)
96 NLMISC_REGISTER_CLASS(CPSLocated);
97 NLMISC_REGISTER_CLASS(CParticleSystemShape);
98 NLMISC_REGISTER_CLASS(CPSSound);
99 NLMISC_REGISTER_CLASS(CPSLight);
102 registerParticles();
103 registerForces();
104 registerEmitters();
105 registerZones();
106 registerAttribs();
109 // while we are here, we perform some important inits
110 initFastCosNSinTable(); // init fast cosine lookup table
111 initPerlinNoiseTable(); // init perlin noise table
114 //==========================================================================
115 void CPSUtil::displayBBox(NL3D::IDriver *driver, const NLMISC::CAABBox &box, NLMISC::CRGBA col /* = NLMISC::CRGBA::White */)
117 NL_PS_FUNC(CPSUtil_displayBBox)
118 CVector max = box.getMax()
119 ,min = box.getMin();
120 CVertexBuffer vb;
121 vb.setVertexFormat(CVertexBuffer::PositionFlag);
122 vb.setNumVertices(8);
125 CVertexBufferReadWrite vba;
126 vb.lock (vba);
127 vba.setVertexCoord(0, min);
128 vba.setVertexCoord(1, CVector(max.x, min.y, min.z));
129 vba.setVertexCoord(2, CVector(min.x, max.y, min.z));
130 vba.setVertexCoord(3, CVector(max.x, max.y, min.z));
131 vba.setVertexCoord(4, CVector(min.x, min.y, max.z));
132 vba.setVertexCoord(5, CVector(max.x, min.y, max.z));
133 vba.setVertexCoord(6, CVector(min.x, max.y, max.z));
134 vba.setVertexCoord(7, max);
138 CMaterial material;
140 material.setColor(col);
141 material.setLighting(false);
142 material.setBlendFunc(CMaterial::one, CMaterial::one);
143 material.setZWrite(false);
144 material.setBlend(true);
148 CIndexBuffer pb;
149 pb.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT);
150 pb.setNumIndexes(2*12);
152 CIndexBufferReadWrite ibaWrite;
153 pb.lock (ibaWrite);
154 ibaWrite.setLine(0, 0, 1);
155 ibaWrite.setLine(2, 1, 5);
156 ibaWrite.setLine(4, 5, 4);
157 ibaWrite.setLine(6, 4, 0);
158 ibaWrite.setLine(8, 0, 2);
159 ibaWrite.setLine(10, 1, 3);
160 ibaWrite.setLine(12, 4, 6);
161 ibaWrite.setLine(14, 5, 7);
162 ibaWrite.setLine(16, 6, 7);
163 ibaWrite.setLine(18, 7, 3);
164 ibaWrite.setLine(20, 3, 2);
165 ibaWrite.setLine(22, 2, 6);
170 driver->activeVertexBuffer(vb);
171 driver->activeIndexBuffer(pb);
172 driver->renderLines(material, 0, pb.getNumIndexes()/2);
176 //==========================================================================
177 void CPSUtil::displayArrow(IDriver *driver, const CVector &start, const CVector &v, float size, CRGBA col1, CRGBA col2)
180 NL_PS_FUNC(CPSUtil_displayArrow)
182 const float coneSize = size * 0.1f;
184 static CIndexBuffer vTab;
185 static const TIndexType vTabIndexes[] =
186 { 1, 2, 4,
187 4, 2, 3,
188 1, 2, 0,
189 2, 3, 0,
190 3, 4, 0,
191 4, 1, 0 };
192 vTab.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT);
194 if (vTab.getNumIndexes()==0)
196 vTab.setNumIndexes (sizeofarray(vTabIndexes));
197 CIndexBufferReadWrite iba;
198 vTab.lock(iba);
199 memcpy (iba.getPtr(), vTabIndexes, sizeof(vTabIndexes));
203 CVector end = start + size * v;
204 CDRU::drawLine(start, end, col1, *driver);
205 CMatrix m;
206 buildSchmidtBasis(v, m);
209 CVertexBuffer vb;
210 vb.setVertexFormat(CVertexBuffer::PositionFlag);
211 vb.setNumVertices(5);
215 CVertexBufferReadWrite vba;
216 vb.lock (vba);
217 vba.setVertexCoord(0, end + m * CVector(0, 0, 3.0f * coneSize) );
218 vba.setVertexCoord(1, end + m * CVector(-coneSize, -coneSize, 0) );
219 vba.setVertexCoord(2, end + m * CVector(coneSize, -coneSize, 0) );
220 vba.setVertexCoord(3, end + m * CVector(coneSize, coneSize, 0) );
221 vba.setVertexCoord(4, end + m * CVector(-coneSize, coneSize, 0) );
225 CMaterial material;
227 material.setColor(col2);
228 material.setLighting(false);
229 material.setBlendFunc(CMaterial::one, CMaterial::one);
230 material.setZWrite(false);
231 material.setBlend(true);
232 material.setDoubleSided(true);
236 driver->activeVertexBuffer(vb);
237 driver->activeIndexBuffer(vTab);
238 driver->renderTriangles(material, 0, 6);
243 //==========================================================================
244 void CPSUtil::displayBasis(IDriver *driver, const CMatrix &modelMat, const NLMISC::CMatrix &m, float size, CFontGenerator &fg, CFontManager &fm)
246 NL_PS_FUNC(CPSUtil_displayBasis)
248 CMaterial material;
250 driver->setupModelMatrix(modelMat);
255 displayArrow(driver, m.getPos(), m.getI(), size, CRGBA(127, 127, 127), CRGBA(0, 0, 80));
257 displayArrow(driver, m.getPos(), m.getJ(), size, CRGBA(127, 127, 127), CRGBA(0, 0, 80));
259 displayArrow(driver, m.getPos(), m.getK(), size, CRGBA(127, 127, 127), CRGBA(200, 0, 80));
262 // draw the letters
264 CPSUtil::print(driver, std::string("x"), fg, fm, modelMat * m * CVector(1.4f * size, 0, 0), 15.0f * size);
266 CPSUtil::print(driver, std::string("y"), fg, fm, modelMat * m * CVector(0, 1.4f * size, 0), 15.0f * size);
268 CPSUtil::print(driver, std::string("z"), fg, fm, modelMat * m * CVector(0, 0, 1.4f * size), 15.0f * size);
273 //==========================================================================
274 void CPSUtil::print(IDriver *driver, const std::string &text, CFontGenerator &fg, CFontManager &fm, const CVector &pos, float size, NLMISC::CRGBA col /*= NLMISC::CRGBA::White*/)
276 NL_PS_FUNC(CPSUtil_print)
277 CComputedString cptedString;
278 fm.computeString ( text,
279 &fg,
280 col,
282 false,
283 false,
284 driver,
285 cptedString);
288 CMatrix mat = driver->getViewMatrix();
289 mat.setPos(CVector::Null);
290 mat.scale(CVector(size, size, size));
291 mat.transpose();
292 mat.setPos(pos);
293 cptedString.render3D(*driver, mat);
297 //==========================================================================
298 void CPSUtil::buildSchmidtBasis(const CVector &k_, NLMISC::CMatrix &result)
300 NL_PS_FUNC(CPSUtil_buildSchmidtBasis)
301 const float epsilon = 10E-4f;
302 CVector k = k_;
303 k.normalize();
304 CVector i;
305 if ((1.0f - fabsf(k * CVector::I)) > epsilon)
307 i = k ^ CVector::I;
309 else
310 if ((1.0f - fabs(k * CVector::J)) > epsilon)
312 i = k ^ CVector::J;
314 else
316 i = k ^ CVector::K;
319 i = i - (k * i) * k;
320 i.normalize();
321 result.setRot(i, k ^ i, k, true);
325 //==========================================================================
326 void CPSUtil::displaySphere(IDriver &driver, float radius, const CVector &center, uint nbSubdiv, CRGBA color)
328 NL_PS_FUNC(CPSUtil_displaySphere)
329 uint x, y, k;
330 CVector p, p1, p2;
332 static const CVector lK[] = { CVector::I, -CVector::I
333 ,CVector::J, -CVector::J
334 ,CVector::K, -CVector::K };
336 /* static const CVector lI = { CVector::J, -CVector::J
337 ,CVector::K, -CVector::K
338 ,CVector::I, -CVector::I };*/
342 for (k = 0; k < 6; ++k)
344 const CVector &I = lK[(k + 2) % 6];
345 const CVector &K = lK[k];
346 const CVector J = K ^ I;
348 for (x = 0; x < nbSubdiv; ++x)
350 for (y = 0; y < nbSubdiv; ++y)
352 p = ((2.f * x / float(nbSubdiv) ) - 1.f) * I + ((2.f * y / float(nbSubdiv) ) - 1.f) * J + K;
353 p1 = p + 2.f / float(nbSubdiv) * I;
354 p2 = p + 2.f / float(nbSubdiv) * J;
356 p.normalize();
357 p1.normalize();
358 p2.normalize();
360 p = center + radius * p;
361 p1 = center + radius * p1;
362 p2 = center + radius * p2;
364 CDRU::drawLine(p, p1, color, driver);
365 CDRU::drawLine(p, p2, color, driver);
372 //==========================================================================
373 void CPSUtil::displayDisc(IDriver &driver, float radius, const CVector &center, const CMatrix &mat, uint nbSubdiv, CRGBA color)
375 NL_PS_FUNC(CPSUtil_displayDisc)
376 // not optimized, but for edition only
377 float thetaDelta = (float) NLMISC::Pi * 2.f / nbSubdiv;
378 float theta = 0.f;
379 const CVector &I = mat.getI();
380 const CVector &J = mat.getJ();
381 for (uint k = 0; k < nbSubdiv; ++k)
384 CDRU::drawLine(center + radius * ((float) cos(theta) * I + (float) sin(theta) * J)
385 , center + radius * ((float) cos(theta + thetaDelta) * I + (float) sin(theta + thetaDelta) * J)
386 , color, driver);
387 theta += thetaDelta;
392 //==========================================================================
393 void CPSUtil::displayCylinder(IDriver &driver, const CVector &center, const CMatrix &mat, const CVector &dim, uint nbSubdiv, CRGBA color)
395 NL_PS_FUNC(CPSUtil_displayCylinder)
396 // not optimized, but for edition only
397 float thetaDelta = (float) NLMISC::Pi * 2.f / nbSubdiv;
398 float theta = 0.f;
399 const CVector &I = mat.getI();
400 const CVector &J = mat.getJ();
401 const CVector &K = mat.getK();
403 for (uint k = 0; k < nbSubdiv; ++k)
406 CDRU::drawLine(center + dim.z * K + dim.x * cosf(theta) * I + dim.y * sinf(theta) * J
407 , center + dim.z * K + dim.x * cosf(theta + thetaDelta) * I + dim.y * sinf(theta + thetaDelta) * J
408 , color, driver);
410 CDRU::drawLine(center - dim.z * K + dim.x * cosf(theta) * I + dim.y * sinf(theta) * J
411 , center - dim.z * K + dim.x * cosf(theta + thetaDelta) * I + dim.y * sinf(theta + thetaDelta) * J
412 , color, driver);
414 CDRU::drawLine(center + dim.z * K + dim.x * cosf(theta) * I + dim.y * sinf(theta) * J
415 , center - dim.z * K + dim.x * cosf(theta) * I + dim.y * sinf(theta) * J
416 , color, driver);
421 theta += thetaDelta;
425 //==========================================================================
426 void CPSUtil::display3DQuad(IDriver &driver, const CVector &c1, const CVector &c2
427 ,const CVector &c3, const CVector &c4, CRGBA color)
429 NL_PS_FUNC(CPSUtil_display3DQuad)
430 CDRU::drawLine(c1, c2, color, driver);
431 CDRU::drawLine(c2, c3, color, driver);
432 CDRU::drawLine(c3, c4, color, driver);
433 CDRU::drawLine(c4, c1, color, driver);
436 } // NL3D