# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

ps_util.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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 //#ifdef NL_DEBUG
00057         bool CPSUtil::_CosTableInitialized = false;
00058         bool CPSUtil::_PerlinNoiseTableInitialized = false;
00059 //#endif
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         //#ifdef NL_DEBUG
00076                 _PerlinNoiseTableInitialized = true;
00077         //#endif
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         //#ifdef NL_DEBUG
00090                 _CosTableInitialized = true;
00091         //#endif
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                 // while we are here, we perform some important inits           
00110                 initFastCosNSinTable(); // init fast cosine lookup table
00111                 initPerlinNoiseTable(); // init perlin noise table                              
00112 }
00113 
00114 //==========================================================================
00115 void CPSUtil::displayBBox(NL3D::IDriver *driver, const NLMISC::CAABBox &box, NLMISC::CRGBA col /* = NLMISC::CRGBA::White */)
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         // draw the letters
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 &center, 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 /*      static const CVector lI = { CVector::J, -CVector::J
00293                                                                 ,CVector::K, -CVector::K
00294                                                                 ,CVector::I, -CVector::I };*/
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 &center, const CMatrix &mat, uint nbSubdiv, CRGBA color)
00330 {
00331         // not optimized, but for edition only
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 &center, const CMatrix &mat, const CVector &dim, uint nbSubdiv, CRGBA color)
00349 {
00350         // not optimized, but for edition only
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 } // NL3D