nuclear@0: /* nuclear@0: Open Asset Import Library (assimp) nuclear@0: ---------------------------------------------------------------------- nuclear@0: nuclear@0: Copyright (c) 2006-2012, assimp team nuclear@0: All rights reserved. nuclear@0: nuclear@0: Redistribution and use of this software in source and binary forms, nuclear@0: with or without modification, are permitted provided that the nuclear@0: following conditions are met: nuclear@0: nuclear@0: * Redistributions of source code must retain the above nuclear@0: copyright notice, this list of conditions and the nuclear@0: following disclaimer. nuclear@0: nuclear@0: * Redistributions in binary form must reproduce the above nuclear@0: copyright notice, this list of conditions and the nuclear@0: following disclaimer in the documentation and/or other nuclear@0: materials provided with the distribution. nuclear@0: nuclear@0: * Neither the name of the assimp team, nor the names of its nuclear@0: contributors may be used to endorse or promote products nuclear@0: derived from this software without specific prior nuclear@0: written permission of the assimp team. nuclear@0: nuclear@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS nuclear@0: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT nuclear@0: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR nuclear@0: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT nuclear@0: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, nuclear@0: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT nuclear@0: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, nuclear@0: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY nuclear@0: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT nuclear@0: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE nuclear@0: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. nuclear@0: nuclear@0: ---------------------------------------------------------------------- nuclear@0: */ nuclear@0: /** @file Defines a helper class to represent an interleaved vertex nuclear@0: along with arithmetic operations to support vertex operations nuclear@0: such as subdivision, smoothing etc. nuclear@0: nuclear@0: While the code is kept as general as possible, arithmetic operations nuclear@0: that are not currently well-defined (and would cause compile errors nuclear@0: due to missing operators in the math library), are commented. nuclear@0: */ nuclear@0: #ifndef AI_VERTEX_H_INC nuclear@0: #define AI_VERTEX_H_INC nuclear@0: nuclear@0: #include nuclear@0: nuclear@0: namespace Assimp { nuclear@0: nuclear@0: /////////////////////////////////////////////////////////////////////////// nuclear@0: // std::plus-family operates on operands with identical types - we need to nuclear@0: // support all the (vectype op float) combinations in vector maths. nuclear@0: // Providing T(float) would open the way to endless implicit conversions. nuclear@0: /////////////////////////////////////////////////////////////////////////// nuclear@0: namespace Intern { nuclear@0: template struct plus { nuclear@0: TRES operator() (const T0& t0, const T1& t1) const { nuclear@0: return t0+t1; nuclear@0: } nuclear@0: }; nuclear@0: template struct minus { nuclear@0: TRES operator() (const T0& t0, const T1& t1) const { nuclear@0: return t0-t1; nuclear@0: } nuclear@0: }; nuclear@0: template struct multiplies { nuclear@0: TRES operator() (const T0& t0, const T1& t1) const { nuclear@0: return t0*t1; nuclear@0: } nuclear@0: }; nuclear@0: template struct divides { nuclear@0: TRES operator() (const T0& t0, const T1& t1) const { nuclear@0: return t0/t1; nuclear@0: } nuclear@0: }; nuclear@0: } nuclear@0: nuclear@0: // ------------------------------------------------------------------------------------------------ nuclear@0: /** Intermediate description a vertex with all possible components. Defines a full set of nuclear@0: * operators, so you may use such a 'Vertex' in basic arithmetics. All operators are applied nuclear@0: * to *all* vertex components equally. This is useful for stuff like interpolation nuclear@0: * or subdivision, but won't work if special handling is required for some vertex components. */ nuclear@0: // ------------------------------------------------------------------------------------------------ nuclear@0: class Vertex nuclear@0: { nuclear@0: friend Vertex operator + (const Vertex&,const Vertex&); nuclear@0: friend Vertex operator - (const Vertex&,const Vertex&); nuclear@0: nuclear@0: // friend Vertex operator + (const Vertex&,float); nuclear@0: // friend Vertex operator - (const Vertex&,float); nuclear@0: friend Vertex operator * (const Vertex&,float); nuclear@0: friend Vertex operator / (const Vertex&,float); nuclear@0: nuclear@0: // friend Vertex operator + (float, const Vertex&); nuclear@0: // friend Vertex operator - (float, const Vertex&); nuclear@0: friend Vertex operator * (float, const Vertex&); nuclear@0: // friend Vertex operator / (float, const Vertex&); nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: Vertex() {} nuclear@0: nuclear@0: // ---------------------------------------------------------------------------- nuclear@0: /** Extract a particular vertex from a mesh and interleave all components */ nuclear@0: explicit Vertex(const aiMesh* msh, unsigned int idx) { nuclear@0: ai_assert(idx < msh->mNumVertices); nuclear@0: position = msh->mVertices[idx]; nuclear@0: nuclear@0: if (msh->HasNormals()) { nuclear@0: normal = msh->mNormals[idx]; nuclear@0: } nuclear@0: nuclear@0: if (msh->HasTangentsAndBitangents()) { nuclear@0: tangent = msh->mTangents[idx]; nuclear@0: bitangent = msh->mBitangents[idx]; nuclear@0: } nuclear@0: nuclear@0: for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) { nuclear@0: texcoords[i] = msh->mTextureCoords[i][idx]; nuclear@0: } nuclear@0: nuclear@0: for (unsigned int i = 0; msh->HasVertexColors(i); ++i) { nuclear@0: colors[i] = msh->mColors[i][idx]; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: Vertex& operator += (const Vertex& v) { nuclear@0: *this = *this+v; nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: Vertex& operator -= (const Vertex& v) { nuclear@0: *this = *this-v; nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: /* nuclear@0: Vertex& operator += (float v) { nuclear@0: *this = *this+v; nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: Vertex& operator -= (float v) { nuclear@0: *this = *this-v; nuclear@0: return *this; nuclear@0: } nuclear@0: */ nuclear@0: Vertex& operator *= (float v) { nuclear@0: *this = *this*v; nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: Vertex& operator /= (float v) { nuclear@0: *this = *this/v; nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: public: nuclear@0: nuclear@0: // ---------------------------------------------------------------------------- nuclear@0: /** Convert back to non-interleaved storage */ nuclear@0: void SortBack(aiMesh* out, unsigned int idx) const { nuclear@0: nuclear@0: ai_assert(idxmNumVertices); nuclear@0: out->mVertices[idx] = position; nuclear@0: nuclear@0: if (out->HasNormals()) { nuclear@0: out->mNormals[idx] = normal; nuclear@0: } nuclear@0: nuclear@0: if (out->HasTangentsAndBitangents()) { nuclear@0: out->mTangents[idx] = tangent; nuclear@0: out->mBitangents[idx] = bitangent; nuclear@0: } nuclear@0: nuclear@0: for(unsigned int i = 0; out->HasTextureCoords(i); ++i) { nuclear@0: out->mTextureCoords[i][idx] = texcoords[i]; nuclear@0: } nuclear@0: nuclear@0: for(unsigned int i = 0; out->HasVertexColors(i); ++i) { nuclear@0: out->mColors[i][idx] = colors[i]; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: private: nuclear@0: nuclear@0: // ---------------------------------------------------------------------------- nuclear@0: /** Construct from two operands and a binary operation to combine them */ nuclear@0: template