📄 opc_meshinterface.h
字号:
// unpack indexed double-precision tri-fan
OPC_UNPACK_VERTEX(0, mTris[0].mVRef[0] )
OPC_UNPACK_VERTEX(1, (T->mVRef[1]) )
OPC_UNPACK_VERTEX(2, (T->mVRef[2]) )
}
else
{
// unpack non-indexed double-precision tri-trip
OPC_UNPACK_VERTEX(0, 0 )
OPC_UNPACK_VERTEX(1, index+1 )
OPC_UNPACK_VERTEX(2, index+2 )
}
break;
case MESH_TERRAIN:
// NOTE: Terrain models are always non-indexed, so indices won't be used here.
// What we do is compute indices. We introduce a little overhead, but using
// integer operations... shall we test performance??
{
udword trisPerRow = ((mNbVerts-1)<<1);
udword row = index / trisPerRow;
udword coll = index % trisPerRow;
udword i0 = row*mNbVerts + (coll>>1);
// here we use a lookup table for a good tesselation
udword lookup[4][3] =
{
{0,mNbVerts+1,1}, // case 0
{0,mNbVerts,mNbVerts+1},// case 1
{mNbVerts,mNbVerts+1,1},// case 2
{0,mNbVerts,1} // case 3
};
// compute key into lookup table
udword key = (row%2) ? (coll%2) | ((i0%2)<<1) : (3- ((coll%2) | ((i0%2)<<1)));
// unpack terrain mesh here
OPC_UNPACK_VERTEX(0, (i0 + lookup[key][0]) )
OPC_UNPACK_VERTEX(1, (i0 + lookup[key][1]) )
OPC_UNPACK_VERTEX(2, (i0 + lookup[key][2]) )
}
break;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// END OF STRIDE CODE!
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#else
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// START OF NON-STRIDE CODE!
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef OPC_DOUBLE_PRECISION
//! UTILITY macro for unpacking the K-th triangle vertex from a given index (not using strides)
#define OPC_UNPACK_VERTEX(K, ind ) \
vp.Vertex[K] = &mVerts[ind];
#else
//! UTILITY macro for shorter code when using double-precision vertices
#define OPC_COPY_VERTEX(K) \
VertexCache[K].x = (float)v[0]; \
VertexCache[K].x = (float)v[1]; \
VertexCache[K].x = (float)v[2]; \
vp.Vertex[K] = &VertexCache[K];
//! UTILITY macro for unpacking the K-th triangle vertex from a given index (not using strides)
#define OPC_UNPACK_VERTEX(K, ind ) \
{ \
const double* v = (const double*)(((ubyte*)mVerts) + (ind) * 3*sizeof(double));\
OPC_COPY_VERTEX(K) \
}
#endif
switch( mMIType )
{
case MESH_TRIANGLE:
if(mTris)
{
const IceMaths::IndexedTriangle* T = &mTris[index];
OPC_UNPACK_VERTEX(0,T->mVRef[0])
OPC_UNPACK_VERTEX(1,T->mVRef[1])
OPC_UNPACK_VERTEX(2,T->mVRef[2])
}else
{// support for non-indexed meshes
index *= 3;
OPC_UNPACK_VERTEX(0,index )
OPC_UNPACK_VERTEX(1,index+1)
OPC_UNPACK_VERTEX(2,index+2)
}
break;
case MESH_TRIANGLE_STRIP:
if(mTris)
{
const udword* inds = (const udword*)mTris;
// unpack indexed double-precision tri-trip
OPC_UNPACK_VERTEX(0,inds[index] )
OPC_UNPACK_VERTEX(1,inds[index%2 ? index+2 : index+1])
OPC_UNPACK_VERTEX(2,inds[index%2 ? index+1 : index+2])
}
else
{
// unpack non-indexed double-precision tri-trip
OPC_UNPACK_VERTEX(0, index )
OPC_UNPACK_VERTEX(1, (index%2 ? index+2 : index+1) )
OPC_UNPACK_VERTEX(2, (index%2 ? index+1 : index+2) )
}
break;
case MESH_TRIANGLE_FAN:
if(mTris)
{
const udword* inds = (const udword*)mTris;
// unpack indexed double-precision tri-fan
OPC_UNPACK_VERTEX(0, inds[0] )
OPC_UNPACK_VERTEX(1, inds[index+1] )
OPC_UNPACK_VERTEX(2, inds[index+2] )
}
else
{
// unpack non-indexed double-precision tri-trip
OPC_UNPACK_VERTEX(0, 0 )
OPC_UNPACK_VERTEX(1, (index+1) )
OPC_UNPACK_VERTEX(2, (index+2) )
}
break;
case MESH_TERRAIN:
// NOTE: Terrain models are always non-indexed, so indices won't be used here.
// What we do is compute indices. We introduce a little overhead, but using
// integer operations... shall we test performance??
{
udword trisPerRow = ((mNbVerts-1)<<1);
udword row = index / trisPerRow;
udword coll = index % trisPerRow;
udword i0 = row*mNbVerts + (coll>>1);
// here we use a lookup table for a good tesselation
udword lookup[4][3] =
{
{0,mNbVerts+1,1}, // case 0
{0,mNbVerts,mNbVerts+1},// case 1
{mNbVerts,mNbVerts+1,1},// case 2
{0,mNbVerts,1} // case 3
};
// compute key into lookup table
udword key = (row%2) ? (coll%2) | ((i0%2)<<1) : (3- ((coll%2) | ((i0%2)<<1)));
// unpack terrain mesh here
OPC_UNPACK_VERTEX(0, (i0 + lookup[key][0]) )
OPC_UNPACK_VERTEX(1, (i0 + lookup[key][1]) )
OPC_UNPACK_VERTEX(2, (i0 + lookup[key][2]) )
}
break;
}
#endif
#endif
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Remaps client's mesh according to a permutation.
* \param nb_indices [in] number of indices in the permutation (will be checked against number of triangles)
* \param permutation [in] list of triangle indices
* \return true if success
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool RemapClient(udword nb_indices, const udword* permutation) const;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Checks the mesh interface is valid, i.e. things have been setup correctly.
* \return true if valid
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool IsValid() const;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Checks the mesh itself is valid.
* Currently we only look for degenerate faces.
* \return number of degenerate faces
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
udword CheckTopology() const;
private:
udword mNbTris; //!< Number of triangles in the input model
udword mNbVerts; //!< Number of vertices in the input model (if this model is a terrain one, this holds the number of vertices per row)
MeshInterfaceType mMIType; //!< Mesh interface type
#ifdef OPC_USE_CALLBACKS
// User callback
void* mUserData; //!< User-defined data sent to callback
RequestCallback mObjCallback; //!< Object callback
#else
// User pointers
const IceMaths::IndexedTriangle* mTris; //!< Array of indexed triangles
const IceMaths::Point* mVerts; //!< Array of vertices
#ifdef OPC_USE_STRIDE
udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3]
udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3]
#endif
private:
static IceMaths::Point VertexCache[3];
#endif
};
#endif //__OPC_MESHINTERFACE_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -