From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/tangent__space__build_8cpp-source.html | 327 +++++++++++++++++++++ 1 file changed, 327 insertions(+) create mode 100644 docs/doxygen/nel/tangent__space__build_8cpp-source.html (limited to 'docs/doxygen/nel/tangent__space__build_8cpp-source.html') diff --git a/docs/doxygen/nel/tangent__space__build_8cpp-source.html b/docs/doxygen/nel/tangent__space__build_8cpp-source.html new file mode 100644 index 00000000..034bb9aa --- /dev/null +++ b/docs/doxygen/nel/tangent__space__build_8cpp-source.html @@ -0,0 +1,327 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# 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  
+

tangent_space_build.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000-2002 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 
+00027 #include "std3d.h"
+00028 
+00029 #include "3d/tangent_space_build.h"
+00030 #include "3d/primitive_block.h"
+00031 #include "3d/vertex_buffer.h"
+00032 #include "nel/misc/triangle.h"
+00033 
+00034 
+00035 
+00036 namespace NL3D
+00037 {
+00038 
+00039 
+00040 //========================================================================================================================
+00044 static uint    DuplicateMBAndAddTexCoord(CMesh::CMeshBuild &outMeshBuild, const CMesh::CMeshBuild &inMeshBuild)
+00045 {       
+00046         outMeshBuild = inMeshBuild;
+00047         uint   numTexCoord = 0;
+00048         for (uint k = CVertexBuffer::FirstTexCoordValue; k <= CVertexBuffer::FirstTexCoordValue; ++k)
+00049         {
+00050                 if (inMeshBuild.VertexFlags & (1 << k)) numTexCoord = 1 + k - CVertexBuffer::FirstTexCoordValue;
+00051         }
+00052         if (numTexCoord == CVertexBuffer::MaxStage) return 0;
+00053         outMeshBuild.VertexFlags = inMeshBuild.VertexFlags | (1 << (numTexCoord + CVertexBuffer::FirstTexCoordValue));
+00054         outMeshBuild.NumCoords[numTexCoord] = 3;
+00055         return numTexCoord;
+00056 }
+00057 
+00058 //========== Build one tangent space vector ==================
+00059 static void BuildTGSpaceVect(const NLMISC::CVector &normal, const NLMISC::CVector &sGrad, NLMISC::CUVW &result)
+00060 {
+00061         // start normalizing the basis
+00062         NLMISC::CVector res = (sGrad - ((sGrad * normal) * normal)).normed();   
+00063         result.U = res.x;
+00064         result.V = res.y;
+00065         result.W = res.z;
+00066 }
+00067 
+00068 //========== build one tri from a vb and 3 index in it=================
+00069 static void BuildTriFromMB(const CMesh::CMeshBuild &mb, const uint index[3], NLMISC::CTriangle &tri)
+00070 {
+00071         tri.V0 = mb.Vertices[index[0]];
+00072         tri.V1 = mb.Vertices[index[1]];
+00073         tri.V2 = mb.Vertices[index[2]];
+00074 }
+00075 
+00076 
+00077 //========================================================================================================================
+00078 bool    BuildTangentSpace(CMesh::CMeshBuild &outMeshBuild, const CMesh::CMeshBuild &inMeshBuild)
+00079 {
+00080         static const NLMISC::CUVW NullUVW(0, 0, 0); // todo add this directly in the CUVW class (for next compile ...)
+00081 
+00083         nlassert(&outMeshBuild != &inMeshBuild);
+00084         uint tgSpaceStage = DuplicateMBAndAddTexCoord(outMeshBuild, inMeshBuild); // format the resulting vb    
+00085         if (tgSpaceStage == 0) return false; // unable to create the vb
+00086 
+00087         uint l, m, n, k;         // some loop counters
+00088         
+00089         // Tells for each vertex what faces belong to it 
+00090         std::vector<std::vector<uint> > VertToFace(inMeshBuild.Vertices.size());
+00091         
+00092         // fill VertToFace
+00093         for (l = 0; l < inMeshBuild.Faces.size(); ++l)
+00094         {
+00095                 for (m = 0; m < 3; ++m)
+00096                 {
+00097                         outMeshBuild.Faces[l].Corner[m].Uvws[tgSpaceStage] = NLMISC::CUVW(0, 0, 0);
+00098                         VertToFace[outMeshBuild.Faces[l].Corner[m].Vertex].push_back(l);
+00099                 }
+00100         }
+00101         
+00102 /* TODO: debug this version
+00103         std::vector<NLMISC::CVector> SGradArray(outMeshBuild.Faces.size());     // SGradient for each face      
+00104 
+00105         // compute sGradient for each face
+00106         for (k = 0; k < outMeshBuild.Faces.size(); ++k)
+00107         {
+00108                 CMesh::CFace &f = outMeshBuild.Faces[k];
+00109                 NLMISC::CTriangle tri;                          
+00110                 tri.V0 = outMeshBuild.Vertices[f.Corner[0].Vertex];
+00111                 tri.V1 = outMeshBuild.Vertices[f.Corner[1].Vertex];
+00112                 tri.V2 = outMeshBuild.Vertices[f.Corner[2].Vertex];
+00113                 tri.computeGradient(f.Corner[0].Uvws[0].U, 
+00114                                                     f.Corner[1].Uvws[0].U,
+00115                                                         f.Corner[2].Uvws[0].U, SGradArray[k]);
+00116                 SGradArray[k].normalize();              
+00117         }
+00118 
+00119 
+00120         // for each triangle, add the S gradient contribution to any neighbour vertex for which the owning face has TexCoords that do not mirror with that face
+00121         for (k = 0; k < outMeshBuild.Faces.size(); ++k)
+00122         {
+00123                 CMesh::CFace &f = outMeshBuild.Faces[k];
+00124                 for (l = 0; l < 3; ++l)
+00125                 {
+00126                         const std::vector<uint> &neighbours = VertToFace[f.Corner[l].Vertex];
+00127                         for (m = 0; m < neighbours.size(); ++m)
+00128                         {
+00129                                 // other face must share smoothgroups with this one
+00130                                 if (f.SmoothGroup & outMeshBuild.Faces[neighbours[m]].SmoothGroup)
+00131                                 {                               
+00132                                         // test if the other face UVs are not mirroring the current ones..
+00133                                         float dp = SGradArray[k] * SGradArray[neighbours[m]];
+00134                                         if (dp > 0.f)
+00135                                         {
+00136                                                 f.Corner[l].Uvws[tgSpaceStage] += NLMISC::CUVW(SGradArray[neighbours[m]].x, SGradArray[neighbours[m]].y, SGradArray[neighbours[m]].z);
+00137                                         }
+00138                                 }
+00139                         }
+00140                 }
+00141         }
+00142 
+00143         // normalize each tangent space vector
+00144         for (k = 0; k < outMeshBuild.Faces.size(); ++k)
+00145         {
+00146                 CMesh::CFace &f = outMeshBuild.Faces[k];
+00147                 for (l = 0; l < 3; ++l)         
+00148                 {
+00149                         CMesh::CCorner &c = f.Corner[l];
+00150                         CVector tgs(c.Uvws[tgSpaceStage].U, c.Uvws[tgSpaceStage].V, c.Uvws[tgSpaceStage].W);
+00151                         tgs = (tgs - (tgs * c.Normal) * c.Normal).normed();
+00152                         c.Uvws[tgSpaceStage].U = tgs.x;
+00153                         c.Uvws[tgSpaceStage].V = tgs.y;
+00154                         c.Uvws[tgSpaceStage].W = tgs.z;
+00155                 }
+00156         }
+00157 */
+00158         
+00159         // Old tangent space version (no support for mirrored textures ..)
+00160         for (l = 0; l < inMeshBuild.Faces.size(); ++l)
+00161         {                       
+00162 
+00163                 CMesh::CFace &curF = outMeshBuild.Faces[l];     
+00164 
+00165 
+00166                 // Build each tangent space vector if needed
+00167                 for (m = 0; m < 3; ++m)
+00168                 {
+00169                         uint vertIndex = outMeshBuild.Faces[l].Corner[m].Vertex;
+00170                         bool found = false;
+00171                         NLMISC::CUVW *tsv=0; // a previously computed tangent space vector
+00172                         // Test wether it hasn't been built before, by looking in each corner of each face that share that vertex
+00173                         for (n = 0; n < VertToFace[vertIndex].size() && !found; ++n)
+00174                         {
+00175                                 CMesh::CFace &f = outMeshBuild.Faces[VertToFace[vertIndex][n]]; // ref to the current face
+00176                                 for (k = 0; k < 3; ++k)
+00177                                 {
+00178                                         // can only share with corners that are equal to this one
+00179                                         if (f.Corner[k].Vertex == curF.Corner[m].Vertex) // same position
+00180                                         {
+00181                                                 if (f.Corner[k].Uvws[tgSpaceStage] != NullUVW) // must have built the tangent space vector previously.
+00182                                                 {
+00183                                                         if (f.Corner[k].Normal == curF.Corner[m].Normal
+00184                                                                 && f.Corner[k].Uvws[0] ==  curF.Corner[m].Uvws[0]
+00185                                                            )
+00186                                                         {
+00187                                                                 // no texture and normal discontinuity
+00188                                                                 found = true;
+00189                                                                 tsv = &f.Corner[k].Uvws[tgSpaceStage];
+00190                                                         }
+00191                                                 }
+00192                                         }
+00193                                 }
+00194                         }
+00195 
+00196                         if (!found)
+00197                         {
+00198                                 NLMISC::CVector grad(0, 0, 0);
+00199                                 // walk all the triangles around this vertex to sum the gradients
+00200                                 // Get the s coordinate gradient over that triangle
+00201                                 for (n = 0; n < VertToFace[vertIndex].size(); ++n)
+00202                                 {       
+00203                                         CMesh::CFace &f = outMeshBuild.Faces[VertToFace[vertIndex][n]]; // ref to the current face
+00204 
+00205                                         // before to sum this face gradient, make sure there's no normal or mapping discontinuity
+00206                                         bool canShare = true;
+00207                                         for (k = 0; k < 3; ++k)
+00208                                         {
+00209                                                 // can only share with corners that are equal to this one
+00210                                                 if (f.Corner[k].Vertex == curF.Corner[m].Vertex) // same position
+00211                                                 {
+00212                                                         if (!(f.Corner[k].Normal == curF.Corner[m].Normal
+00213                                                                   && f.Corner[k].Uvws[0] ==  curF.Corner[m].Uvws[0]
+00214                                                              )
+00215                                                            )
+00216                                                         {
+00217                                                                 canShare = false;
+00218                                                                 break;
+00219                                                         }
+00220                                                 }
+00221                                         }
+00222 
+00223                                         if (!canShare) continue;
+00224 
+00225                                         // Get indices of vertices of current tri
+00226                                         const uint indices[] = { f.Corner[0].Vertex,
+00227                                                                                          f.Corner[1].Vertex,
+00228                                                                                          f.Corner[2].Vertex };
+00229                                         NLMISC::CTriangle tri;
+00230                                         // Build it
+00231                                         BuildTriFromMB(outMeshBuild, indices, tri);
+00232                                         // Get s coordinates for each corner
+00233                                         float s[3];
+00234                                         for (k = 0; k < 3; ++k) 
+00235                                         {
+00236                                                 s[k] = f.Corner[k].Uvws[0].U;                   
+00237                                         }       
+00238 
+00239                                         NLMISC::CVector sGrad;                                          
+00240                                         tri.computeGradient(s[0], s[1], s[2], sGrad);
+00241                                         grad += ((tri.V1 - tri.V0) ^ (tri.V2 - tri.V0)).norm() * sGrad; // ponderate by twice the area
+00242                                 }
+00243                                 grad.normalize();
+00244 
+00245                                 // build new tangent space vector
+00246                                 BuildTGSpaceVect(inMeshBuild.Faces[l].Corner[m].Normal, grad, curF.Corner[m].Uvws[tgSpaceStage]);
+00247                         }
+00248                         else
+00249                         {
+00250                                 // use previously built vector
+00251                                 curF.Corner[m].Uvws[tgSpaceStage] = *tsv; 
+00252                         }
+00253                 }                       
+00254         }               
+00255         return true;
+00256 }
+00257 
+00258 
+00259 
+00260 
+00261 
+00262 }
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1