00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "std3d.h"
00027
00028
00029 #include "nel/misc/aabbox.h"
00030 #include "nel/misc/matrix.h"
00031
00032 #include "3d/ps_util.h"
00033 #include "3d/particle_system.h"
00034 #include "3d/driver.h"
00035 #include "3d/vertex_buffer.h"
00036 #include "3d/primitive_block.h"
00037 #include "3d/material.h"
00038 #include "3d/nelu.h"
00039 #include "3d/font_generator.h"
00040 #include "3d/font_manager.h"
00041 #include "3d/computed_string.h"
00042 #include "3d/dru.h"
00043 #include "3d/ps_located.h"
00044 #include "3d/ps_sound.h"
00045
00046 #include "3d/particle_system_shape.h"
00047
00048
00049
00050 namespace NL3D {
00051
00052
00053 using NLMISC::CVector;
00054
00055
00056
00057 bool CPSUtil::_CosTableInitialized = false;
00058 bool CPSUtil::_PerlinNoiseTableInitialized = false;
00059
00060
00061 float CPSUtil::_CosTable[256];
00062 float CPSUtil::_SinTable[256];
00063 float CPSUtil::_PerlinNoiseTab[1024];
00064
00065
00066
00067
00068
00069 void CPSUtil::initPerlinNoiseTable(void)
00070 {
00071 for (uint32 k = 0; k < 1024; ++k)
00072 {
00073 _PerlinNoiseTab[k] = (rand() % 30000) / 30000.f;
00074 }
00075
00076 _PerlinNoiseTableInitialized = true;
00077
00078 }
00079
00080
00081 void CPSUtil::initFastCosNSinTable(void)
00082 {
00083 for (uint32 k = 0; k < 256; k++)
00084 {
00085 const float angle = k / 256.0f * 2.0f * float(NLMISC::Pi);
00086 _CosTable[k] = (float) cos( angle );
00087 _SinTable[k] = (float) sin( angle );
00088 }
00089
00090 _CosTableInitialized = true;
00091
00092 }
00093
00094
00095 void CPSUtil::registerSerialParticleSystem(void)
00096 {
00097 NLMISC_REGISTER_CLASS(CPSLocated);
00098 NLMISC_REGISTER_CLASS(CParticleSystemShape);
00099 NLMISC_REGISTER_CLASS(CPSSound);
00100
00101
00102 registerParticles();
00103 registerForces();
00104 registerEmitters();
00105 registerZones();
00106 registerAttribs();
00107
00108
00109
00110 initFastCosNSinTable();
00111 initPerlinNoiseTable();
00112 }
00113
00114
00115 void CPSUtil::displayBBox(NL3D::IDriver *driver, const NLMISC::CAABBox &box, NLMISC::CRGBA col )
00116 {
00117 CVector max = box.getMax()
00118 ,min = box.getMin();
00119 CVertexBuffer vb;
00120 vb.setVertexFormat(CVertexBuffer::PositionFlag);
00121 vb.setNumVertices(8);
00122
00123 vb.setVertexCoord(0, min);
00124 vb.setVertexCoord(1, CVector(max.x, min.y, min.z));
00125 vb.setVertexCoord(2, CVector(min.x, max.y, min.z));
00126 vb.setVertexCoord(3, CVector(max.x, max.y, min.z));
00127 vb.setVertexCoord(4, CVector(min.x, min.y, max.z));
00128 vb.setVertexCoord(5, CVector(max.x, min.y, max.z));
00129 vb.setVertexCoord(6, CVector(min.x, max.y, max.z));
00130 vb.setVertexCoord(7, max);
00131
00132
00133 CMaterial material;
00134
00135 material.setColor(col);
00136 material.setLighting(false);
00137 material.setBlendFunc(CMaterial::one, CMaterial::one);
00138 material.setZWrite(false);
00139 material.setBlend(true);
00140
00141
00142
00143 CPrimitiveBlock pb;
00144 pb.reserveLine(12);
00145 pb.addLine(0, 1);
00146 pb.addLine(1, 5);
00147 pb.addLine(5, 4);
00148 pb.addLine(4, 0);
00149 pb.addLine(0, 2);
00150 pb.addLine(1, 3);
00151 pb.addLine(4, 6);
00152 pb.addLine(5, 7);
00153 pb.addLine(6, 7);
00154 pb.addLine(7, 3);
00155 pb.addLine(3, 2);
00156 pb.addLine(2, 6);
00157
00158
00159
00160 driver->activeVertexBuffer(vb);
00161 driver->render(pb, material);
00162 }
00163
00164
00165
00166 void CPSUtil::displayArrow(IDriver *driver, const CVector &start, const CVector &v, float size, CRGBA col1, CRGBA col2)
00167 {
00168
00169 const float coneSize = size * 0.1f;
00170
00171 uint32 vTab[] = { 1, 2, 4,
00172 4, 2, 3,
00173 1, 2, 0,
00174 2, 3, 0,
00175 3, 4, 0,
00176 4, 1, 0 };
00177
00178 CVector end = start + size * v;
00179 CDRU::drawLine(start, end, col1, *driver);
00180 CMatrix m;
00181 buildSchmidtBasis(v, m);
00182
00183 CVertexBuffer vb;
00184 vb.setVertexFormat(CVertexBuffer::PositionFlag);
00185 vb.setNumVertices(5);
00186
00187
00188
00189 vb.setVertexCoord(0, end + m * CVector(0, 0, 3.0f * coneSize) );
00190 vb.setVertexCoord(1, end + m * CVector(-coneSize, -coneSize, 0) );
00191 vb.setVertexCoord(2, end + m * CVector(coneSize, -coneSize, 0) );
00192 vb.setVertexCoord(3, end + m * CVector(coneSize, coneSize, 0) );
00193 vb.setVertexCoord(4, end + m * CVector(-coneSize, coneSize, 0) );
00194
00195 CMaterial material;
00196
00197 material.setColor(col2);
00198 material.setLighting(false);
00199 material.setBlendFunc(CMaterial::one, CMaterial::one);
00200 material.setZWrite(false);
00201 material.setBlend(true);
00202 material.setDoubleSided(true);
00203
00204 driver->activeVertexBuffer(vb, 0, 5);
00205 driver->renderTriangles(material, vTab, 6);
00206 }
00207
00208
00209 void CPSUtil::displayBasis(IDriver *driver, const CMatrix &modelMat, const NLMISC::CMatrix &m, float size, CFontGenerator &fg, CFontManager &fm)
00210 {
00211 CMaterial material;
00212
00213 driver->setupModelMatrix(modelMat);
00214
00215
00216
00217 displayArrow(driver, m.getPos(), m.getI(), size, CRGBA(127, 127, 127), CRGBA(0, 0, 80));
00218 displayArrow(driver, m.getPos(), m.getJ(), size, CRGBA(127, 127, 127), CRGBA(0, 0, 80));
00219 displayArrow(driver, m.getPos(), m.getK(), size, CRGBA(127, 127, 127), CRGBA(200, 0, 80));
00220
00221
00222
00223
00224 CPSUtil::print(driver, std::string("x"), fg, fm, modelMat * m * CVector(1.4f * size, 0, 0), 15.0f * size);
00225 CPSUtil::print(driver, std::string("y"), fg, fm, modelMat * m * CVector(0, 1.4f * size, 0), 15.0f * size);
00226 CPSUtil::print(driver, std::string("z"), fg, fm, modelMat * m * CVector(0, 0, 1.4f * size), 15.0f * size);
00227
00228 };
00229
00230
00231
00232 void CPSUtil::print(IDriver *driver, const std::string &text, CFontGenerator &fg, CFontManager &fm, const CVector &pos, float size)
00233 {
00234 nlassert((&fg) && (&fm));
00235 CComputedString cptedString;
00236 fm.computeString ( text,
00237 &fg,
00238 CRGBA(255,255,255),
00239 16,
00240 driver,
00241 cptedString);
00242
00243
00244 CMatrix mat = driver->getViewMatrix();
00245 mat.setPos(CVector::Null);
00246 mat.scale(CVector(size, size, size));
00247 mat.transpose();
00248 mat.setPos(pos);
00249 cptedString.render3D(*driver, mat);
00250 }
00251
00252
00253
00254 void CPSUtil::buildSchmidtBasis(const CVector &k_, NLMISC::CMatrix &result)
00255 {
00256 const float epsilon = 10E-4f;
00257
00258
00259 CVector k = k_;
00260 k.normalize();
00261 CVector i;
00262 if ((1.0f - fabsf(k * CVector::I)) > epsilon)
00263 {
00264 i = k ^ CVector::I;
00265 }
00266 else
00267 if ((1.0f - fabs(k * CVector::J)) > epsilon)
00268 {
00269 i = k ^ CVector::J;
00270 }
00271 else
00272 {
00273 i = k ^ CVector::K;
00274 }
00275
00276 i = i - (k * i) * k;
00277 i.normalize();
00278 result.setRot(i, k ^ i, k, true);
00279 }
00280
00281
00282
00283 void CPSUtil::displaySphere(IDriver &driver, float radius, const CVector ¢er, uint nbSubdiv, CRGBA color)
00284 {
00285 uint x, y, k;
00286 CVector p, p1, p2;
00287
00288 static const CVector lK[] = { CVector::I, -CVector::I
00289 ,CVector::J, -CVector::J
00290 ,CVector::K, -CVector::K };
00291
00292
00293
00294
00295
00296
00297
00298 for (k = 0; k < 6; ++k)
00299 {
00300 const CVector &I = lK[(k + 2) % 6];
00301 const CVector &K = lK[k];
00302 const CVector J = K ^ I;
00303
00304 for (x = 0; x < nbSubdiv; ++x)
00305 {
00306 for (y = 0; y < nbSubdiv; ++y)
00307 {
00308 p = ((2.f * x / float(nbSubdiv) ) - 1.f) * I + ((2.f * y / float(nbSubdiv) ) - 1.f) * J + K;
00309 p1 = p + 2.f / float(nbSubdiv) * I;
00310 p2 = p + 2.f / float(nbSubdiv) * J;
00311
00312 p.normalize();
00313 p1.normalize();
00314 p2.normalize();
00315
00316 p = center + radius * p;
00317 p1 = center + radius * p1;
00318 p2 = center + radius * p2;
00319
00320 CDRU::drawLine(p, p1, color, driver);
00321 CDRU::drawLine(p, p2, color, driver);
00322 }
00323 }
00324 }
00325 }
00326
00327
00328
00329 void CPSUtil::displayDisc(IDriver &driver, float radius, const CVector ¢er, const CMatrix &mat, uint nbSubdiv, CRGBA color)
00330 {
00331
00332 float thetaDelta = (float) NLMISC::Pi * 2.f / nbSubdiv;
00333 float theta = 0.f;
00334 const CVector &I = mat.getI();
00335 const CVector &J = mat.getJ();
00336 for (uint k = 0; k < nbSubdiv; ++k)
00337 {
00338
00339 CDRU::drawLine(center + radius * ((float) cos(theta) * I + (float) sin(theta) * J)
00340 , center + radius * ((float) cos(theta + thetaDelta) * I + (float) sin(theta + thetaDelta) * J)
00341 , color, driver);
00342 theta += thetaDelta;
00343 }
00344
00345 }
00346
00347
00348 void CPSUtil::displayCylinder(IDriver &driver, const CVector ¢er, const CMatrix &mat, const CVector &dim, uint nbSubdiv, CRGBA color)
00349 {
00350
00351 float thetaDelta = (float) NLMISC::Pi * 2.f / nbSubdiv;
00352 float theta = 0.f;
00353 const CVector &I = mat.getI();
00354 const CVector &J = mat.getJ();
00355 const CVector &K = mat.getK();
00356
00357 for (uint k = 0; k < nbSubdiv; ++k)
00358 {
00359
00360 CDRU::drawLine(center + dim.z * K + dim.x * cosf(theta) * I + dim.y * sinf(theta) * J
00361 , center + dim.z * K + dim.x * cosf(theta + thetaDelta) * I + dim.y * sinf(theta + thetaDelta) * J
00362 , color, driver);
00363
00364 CDRU::drawLine(center - dim.z * K + dim.x * cosf(theta) * I + dim.y * sinf(theta) * J
00365 , center - dim.z * K + dim.x * cosf(theta + thetaDelta) * I + dim.y * sinf(theta + thetaDelta) * J
00366 , color, driver);
00367
00368 CDRU::drawLine(center + dim.z * K + dim.x * cosf(theta) * I + dim.y * sinf(theta) * J
00369 , center - dim.z * K + dim.x * cosf(theta) * I + dim.y * sinf(theta) * J
00370 , color, driver);
00371
00372
00373
00374
00375 theta += thetaDelta;
00376 }
00377 }
00378
00379
00380 void CPSUtil::display3DQuad(IDriver &driver, const CVector &c1, const CVector &c2
00381 ,const CVector &c3, const CVector &c4, CRGBA color)
00382 {
00383 CDRU::drawLine(c1, c2, color, driver);
00384 CDRU::drawLine(c2, c3, color, driver);
00385 CDRU::drawLine(c3, c4, color, driver);
00386 CDRU::drawLine(c4, c1, color, driver);
00387 }
00388
00389
00390
00391
00392 }