// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/> // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. #include "stdmisc.h" #include "nel/misc/triangle.h" #include "nel/misc/plane.h" #include "nel/misc/matrix.h" namespace NLMISC { #define EPSILON 0.0001f // *************************************************************************** bool CTriangle::intersect (const CVector& p0, const CVector& p1, CVector& hit, const CPlane& plane) const { CVector normal = plane.getNormal(); float np1 = normal*p1; float np2 = np1-normal*p0; if (np2 == 0.0f) return false; float lambda = (plane.d+np1)/np2; // Checks the intersection belongs to the segment if (lambda < -EPSILON || lambda > 1.0f+EPSILON) return false; // The intersection on the plane hit = p0*lambda+p1*(1.0f-lambda); float d0 = ((V1-V0)^normal)*(hit-V0); float d1 = ((V2-V1)^normal)*(hit-V1); float d2 = ((V0-V2)^normal)*(hit-V2); return (d0 < +EPSILON && d1 < +EPSILON && d2 < +EPSILON) || (d0 > -EPSILON && d1 > -EPSILON && d2 > -EPSILON); } // *************************************************************************** void CTriangle::computeGradient(float c0, float c1, float c2, CVector &grad) const { // Compute basis for 2D triangle. CVector locI, locJ, locK; locI= V1-V0; locJ= V2-V0; locK= locI^locJ; locK.normalize(); locI.normalize(); locJ= locK^locI; // compute triangle in 2D. CTriangle tri2D; tri2D.V0.set(0,0,0); tri2D.V1.x= (V1-V0)*locI; tri2D.V1.y= (V1-V0)*locJ; tri2D.V1.z= 0; tri2D.V2.x= (V2-V0)*locI; tri2D.V2.y= (V2-V0)*locJ; tri2D.V2.z= 0; // Compute 2 2D Gradients. float dx01= tri2D.V0.x - tri2D.V2.x; float dx02= tri2D.V1.x - tri2D.V2.x; float dy01= tri2D.V0.y - tri2D.V2.y; float dy02= tri2D.V1.y - tri2D.V2.y; float dc01= c0 - c2; float dc02= c1 - c2; float gd= dx02*dy01 - dx01*dy02; float OOgd; if(gd!=0) OOgd= 1.0f/gd; else OOgd= 1; // for now, do not manage correctly this case. float gx, gy; gx= (dc02*dy01 - dc01*dy02) * OOgd; gy= (dc01*dx02 - dc02*dx01) * OOgd; // transform in 3D. grad= locI*gx + locJ*gy; } // *************************************************************************** void CTriangle::applyMatrix(const CMatrix &m, CTriangle &dest) const { dest.V0 = m * V0; dest.V1 = m * V1; dest.V2 = m * V2; } } // NLMISC