void Mesh::RenderFaceNormals() const { glPushMatrix(); for (int t = 0; t < faces.size(); ++t) { const vector<int>& vertexIndices = faces.at(t); const Vec3f& normal = faceNormals.at(t); Vec3f faceCenter(0.0f, 0.0f, 0.0f); for (int v = 0; v < vertexIndices.size(); ++v) { faceCenter += vertices.at(vertexIndices.at(v)); } faceCenter /= vertexIndices.size(); RenderNormal(faceCenter, normal / 5.0f); } glPopMatrix(); }
void csDecal::AddStaticPoly (const csPoly3D & p, csArray<size_t>* indices) { CS_ASSERT(animationControlData.animationControl ? indices != (csArray<size_t>*) nullptr : 1); if (!currMesh) return; size_t a; CS::TriangleT<int> tri; csPoly3D poly = p; if (decalTemplate->HasClipping ()) for (a = 0; a < numClipPlanes; ++a) CutPolyToPlane (poly, clipPlanes[a], indices); size_t vertCount = poly.GetVertexCount (); // only support triangles and up if (vertCount < 3) return; // ensure the polygon isn't facing away from the decal's normal too much csVector3 polyNorm = poly.ComputeNormal (); float polyNormThresholdValue = -polyNorm * localNormal; if (polyNormThresholdValue < decalTemplate->GetPolygonNormalThreshold ()) return; // check if we hit our maximum allowed vertices if (vertexCount + vertCount > CS_DECAL_MAX_VERTS_PER_DECAL) vertCount = CS_DECAL_MAX_VERTS_PER_DECAL - vertexCount; if (vertCount < 3) return; // check if we hit our maximum allowed indices size_t idxCount = (vertCount - 2) * 3; if (indexCount + idxCount > CS_DECAL_MAX_TRIS_PER_DECAL * 3) return; // if this face is too perpendicular, then we'll need to push it out a bit // to avoid z-fighting. We do this by pushing the bottom of the face out // more than the top of the face bool doFaceOffset = false; float faceHighDot = 0.0f; float invHighLowFaceDist = 0.0f; csVector3 faceBottomOffset(0.0f); csVector3 faceCenter(0.0f); if (decalTemplate->HasClipping () && !animationControlData.animationControl) { if (fabs (polyNormThresholdValue) < decalTemplate->GetPerpendicularFaceThreshold ()) { doFaceOffset = true; csVector3 faceHighVert, faceLowVert; float faceLowDot; faceLowVert = faceHighVert = *poly.GetVertex (0); faceLowDot = faceHighDot = (faceLowVert - relPos) * localNormal; faceCenter = faceLowVert; for (a = 1; a < vertCount; ++a) { const csVector3 * vertPos = poly.GetVertex (a); faceCenter += *vertPos; float dot = (*vertPos - relPos) * localNormal; if (dot > faceHighDot) { faceHighVert = *vertPos; faceHighDot = dot; } if (dot < faceLowDot) { faceLowVert = *vertPos; faceLowDot = dot; } } invHighLowFaceDist = 1.0f / (faceHighDot - faceLowDot); faceBottomOffset = -decalTemplate->GetPerpendicularFaceOffset () * polyNorm; faceCenter /= (float)vertCount; } } const csVector2 & minTexCoord = decalTemplate->GetMinTexCoord (); csVector2 texCoordRange = decalTemplate->GetMaxTexCoord () - minTexCoord; tri[0] = (int)vertexCount; for (a = 0; a < vertCount; ++a) { csVector3 vertPos = *poly.GetVertex (a); float distToPos = (vertPos - relPos) * localNormal; if (decalTemplate->HasClipping () && !animationControlData.animationControl) { if (doFaceOffset) { // linear interpolation where high vert goes nowhere and low vert is // full offset float offsetVal = (faceHighDot - distToPos) * invHighLowFaceDist; vertPos += offsetVal * faceBottomOffset; // spread out the base to avoid vertical seams vertPos += (vertPos - faceCenter).Unit () * (decalTemplate->GetPerpendicularFaceOffset () * 2.0f); } } vertPos += vertOffset; csVector3 relVert = vertPos - relPos; size_t vertIdx = vertexCount+a; // copy over vertex data vertexBuffer->CopyInto (&vertPos, 1, vertIdx); // copy over color csColor4 color; if (-distToPos >= 0.0f) { float t = 0.0f; if (topPlaneDist >= 0.01f) t = -distToPos / topPlaneDist; color = decalTemplate->GetMainColor () * (1.0f - t) + decalTemplate->GetTopColor () * t; } else { float t = 0.0f; if (bottomPlaneDist >= 0.01f) t = distToPos / bottomPlaneDist; color = decalTemplate->GetMainColor () * (1.0f - t) + decalTemplate->GetBottomColor () * t; } colorBuffer->CopyInto (&color, 1, vertIdx); // create the index buffer for each triangle in the poly if (a >= 2) { tri[1] = (int)vertIdx-1; tri[2] = (int)vertIdx; indexBuffer->CopyInto (&tri, 3, indexCount); indexCount += 3; } // generate uv coordinates csVector2 texCoord ( minTexCoord.x + texCoordRange.x * 0.5f + texCoordRange.x * localRight * invWidth * relVert, minTexCoord.y + texCoordRange.y * 0.5f - texCoordRange.y * localUp * invHeight * relVert); texCoordBuffer->CopyInto (&texCoord, 1, vertIdx); // TODO: compute tangents/binormals // copy over normal normalBuffer->CopyInto (&localNormal, 1, vertIdx); } vertexCount += vertCount; if (indices) animationControlData.animatedIndices.Merge (*indices); }