📄 tsmesh.cc
字号:
AssertFatal(0,"TSMesh::renderShadow: strips or triangles only...how'd you get in here.");
}
//-----------------------------------------------------
// TSMesh render fog
//-----------------------------------------------------
void TSMesh::renderFog(S32 frame, TSMaterialList* materials)
{
if (getFlags(Billboard))
{
if (getFlags(BillboardZAxis))
forceFaceCameraZAxis();
else
forceFaceCamera();
}
S32 firstVert = vertsPerFrame * frame;
// set up vertex arrays -- already enabled in TSShapeInstance::render
glVertexPointer(3,GL_FLOAT,0,&verts[firstVert]);
// lock...
bool lockArrays = dglDoesSupportCompiledVertexArray();
if (lockArrays)
glLockArraysEXT(0,vertsPerFrame);
for (S32 i=0; i<primitives.size(); i++)
{
TSDrawPrimitive & draw = primitives[i];
if (primitives[i].matIndex & TSDrawPrimitive::NoMaterial ||
materials->getFlags(primitives[i].matIndex & TSDrawPrimitive::MaterialMask) & (TSMaterialList::Translucent | TSMaterialList::Additive))
continue;
glDrawElements(getDrawType(draw.matIndex>>30),draw.numElements,GL_UNSIGNED_SHORT,&indices[draw.start]);
}
// unlock...
if (lockArrays)
glUnlockArraysEXT();
}
//-----------------------------------------------------
// TSMesh collision methods
//-----------------------------------------------------
bool TSMesh::buildPolyList(S32 frame, AbstractPolyList * polyList, U32 & surfaceKey)
{
S32 firstVert = vertsPerFrame * frame, i, base;
// add the verts...
if (vertsPerFrame)
{
base = polyList->addPoint(verts[firstVert]);
for (i=1; i<vertsPerFrame; i++)
polyList->addPoint(verts[i+firstVert]);
}
// add the polys...
for (i=0; i<primitives.size(); i++)
{
TSDrawPrimitive & draw = primitives[i];
U32 start = draw.start;
AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,"TSMesh::buildPolyList (1)");
U32 material = draw.matIndex & TSDrawPrimitive::MaterialMask;
// gonna depend on what kind of primitive it is...
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
{
for (S32 j=0; j<draw.numElements; )
{
U32 idx0 = base + indices[start + j + 0];
U32 idx1 = base + indices[start + j + 1];
U32 idx2 = base + indices[start + j + 2];
polyList->begin(material,surfaceKey++);
polyList->vertex(idx0);
polyList->vertex(idx1);
polyList->vertex(idx2);
polyList->plane(idx0,idx1,idx2);
polyList->end();
j += 3;
}
}
else
{
AssertFatal((draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Strip,"TSMesh::buildPolyList (2)");
U32 idx0 = base + indices[start + 0];
U32 idx1;
U32 idx2 = base + indices[start + 1];
U32 * nextIdx = &idx1;
for (S32 j=2; j<draw.numElements; j++)
{
*nextIdx = idx2;
// nextIdx = (j%2)==0 ? &idx0 : &idx1;
nextIdx = (U32*) ( (dsize_t)nextIdx ^ (dsize_t)&idx0 ^ (dsize_t)&idx1);
idx2 = base + indices[start + j];
if (idx0 == idx1 || idx0 == idx2 || idx1 == idx2)
continue;
polyList->begin(material,surfaceKey++);
polyList->vertex(idx0);
polyList->vertex(idx1);
polyList->vertex(idx2);
polyList->plane(idx0,idx1,idx2);
polyList->end();
}
}
}
return true;
}
bool TSMesh::getFeatures(S32 frame, const MatrixF& mat, const VectorF& /*n*/, ConvexFeature* cf, U32& /*surfaceKey*/)
{
// DMM NOTE! Do not change without talking to Dave Moore. ShapeBase assumes that
// this will return ALL information from the mesh.
S32 firstVert = vertsPerFrame * frame;
S32 i;
S32 base = cf->mVertexList.size();
for (i = 0; i < vertsPerFrame; i++) {
cf->mVertexList.increment();
mat.mulP(verts[firstVert + i], &cf->mVertexList.last());
}
// add the polys...
for (i=0; i < primitives.size(); i++)
{
TSDrawPrimitive & draw = primitives[i];
U32 start = draw.start;
AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,"TSMesh::buildPolyList (1)");
U32 material = draw.matIndex & TSDrawPrimitive::MaterialMask;
// gonna depend on what kind of primitive it is...
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
{
for (S32 j=0; j<draw.numElements; j+=3)
{
PlaneF plane(cf->mVertexList[base + indices[start + j + 0]],
cf->mVertexList[base + indices[start + j + 1]],
cf->mVertexList[base + indices[start + j + 2]]);
cf->mFaceList.increment();
cf->mFaceList.last().normal = plane;
cf->mFaceList.last().vertex[0] = base + indices[start + j + 0];
cf->mFaceList.last().vertex[1] = base + indices[start + j + 1];
cf->mFaceList.last().vertex[2] = base + indices[start + j + 2];
for (U32 l = 0; l < 3; l++) {
U32 newEdge0, newEdge1;
U32 zero = base + indices[start + j + l];
U32 one = base + indices[start + j + ((l+1)%3)];
newEdge0 = getMin(zero, one);
newEdge1 = getMax(zero, one);
bool found = false;
for (S32 k = 0; k < cf->mEdgeList.size(); k++) {
if (cf->mEdgeList[k].vertex[0] == newEdge0 &&
cf->mEdgeList[k].vertex[1] == newEdge1) {
found = true;
break;
}
}
if (!found) {
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = newEdge0;
cf->mEdgeList.last().vertex[1] = newEdge1;
}
}
}
}
else
{
AssertFatal((draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Strip,"TSMesh::buildPolyList (2)");
U32 idx0 = base + indices[start + 0];
U32 idx1;
U32 idx2 = base + indices[start + 1];
U32 * nextIdx = &idx1;
for (S32 j=2; j<draw.numElements; j++)
{
*nextIdx = idx2;
nextIdx = (U32*) ( (dsize_t)nextIdx ^ (dsize_t)&idx0 ^ (dsize_t)&idx1);
idx2 = base + indices[start + j];
if (idx0 == idx1 || idx0 == idx2 || idx1 == idx2)
continue;
PlaneF plane(cf->mVertexList[idx0],
cf->mVertexList[idx1],
cf->mVertexList[idx2]);
cf->mFaceList.increment();
cf->mFaceList.last().normal = plane;
cf->mFaceList.last().vertex[0] = idx0;
cf->mFaceList.last().vertex[1] = idx1;
cf->mFaceList.last().vertex[2] = idx2;
U32 newEdge0, newEdge1;
newEdge0 = getMin(idx0, idx1);
newEdge1 = getMax(idx0, idx1);
bool found = false;
S32 k;
for (k = 0; k < cf->mEdgeList.size(); k++) {
if (cf->mEdgeList[k].vertex[0] == newEdge0 &&
cf->mEdgeList[k].vertex[1] == newEdge1) {
found = true;
break;
}
}
if (!found) {
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = newEdge0;
cf->mEdgeList.last().vertex[1] = newEdge1;
}
newEdge0 = getMin(idx1, idx2);
newEdge1 = getMax(idx1, idx2);
found = false;
for (k = 0; k < cf->mEdgeList.size(); k++) {
if (cf->mEdgeList[k].vertex[0] == newEdge0 &&
cf->mEdgeList[k].vertex[1] == newEdge1) {
found = true;
break;
}
}
if (!found) {
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = newEdge0;
cf->mEdgeList.last().vertex[1] = newEdge1;
}
newEdge0 = getMin(idx0, idx2);
newEdge1 = getMax(idx0, idx2);
found = false;
for (k = 0; k < cf->mEdgeList.size(); k++) {
if (cf->mEdgeList[k].vertex[0] == newEdge0 &&
cf->mEdgeList[k].vertex[1] == newEdge1) {
found = true;
break;
}
}
if (!found) {
cf->mEdgeList.increment();
cf->mEdgeList.last().vertex[0] = newEdge0;
cf->mEdgeList.last().vertex[1] = newEdge1;
}
}
}
}
return false;
}
void TSMesh::support(S32 frame, const Point3F& v, F32* currMaxDP, Point3F* currSupport)
{
if (vertsPerFrame == 0)
return;
U32 waterMark = FrameAllocator::getWaterMark();
F32* pDots = (F32*)FrameAllocator::alloc(sizeof(F32) * vertsPerFrame);
S32 firstVert = vertsPerFrame * frame;
m_point3F_bulk_dot(&v.x,
&verts[firstVert].x,
vertsPerFrame,
sizeof(Point3F),
pDots);
F32 localdp = *currMaxDP;
S32 index = -1;
for (S32 i = 0; i < vertsPerFrame; i++)
{
if (pDots[i] > localdp)
{
localdp = pDots[i];
index = i;
}
}
FrameAllocator::setWaterMark(waterMark);
if (index != -1)
{
*currMaxDP = localdp;
*currSupport = verts[index + firstVert];
}
}
bool TSMesh::castRay(S32 frame, const Point3F & start, const Point3F & end, RayInfo * rayInfo)
{
if (planeNormals.empty())
// if haven't done it yet...
buildConvexHull();
// Keep track of startTime and endTime. They start out at just under 0 and just over 1, respectively.
// As we check against each plane, prune start and end times back to represent current intersection of
// line with all the planes (or rather with all the half-spaces defined by the planes).
// But, instead of explicitly keeping track of startTime and endTime, keep track as numerator and denominator
// so that we can avoid as many divisions as possible.
// F32 startTime = -0.01f;
F32 startNum = -0.01f;
F32 startDen = 1.00f;
// F32 endTime = 1.01f;
F32 endNum = 1.01f;
F32 endDen = 1.00f;
S32 curPlane = 0;
U32 curMaterial = 0;
bool found = false;
// the following block of code is an optimization...
// it isn't necessary if the longer version of the main loop is used
bool tmpFound;
S32 tmpPlane;
F32 sgn = -1.0f;
F32 * pnum = &startNum;
F32 * pden = &startDen;
S32 * pplane = &curPlane;
bool * pfound = &found;
S32 startPlane = frame * planesPerFrame;
for (S32 i=startPlane; i<startPlane+planesPerFrame; i++)
{
// if start & end outside, no collision
// if start & end inside, continue
// if start outside, end inside, or visa versa, find intersection of line with plane
// then update intersection of line with hu
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -