Merged in euclid-13490 (pull request #450)
SL-13490 fix debug normals under non-uniform scale Approved-by: Michael Pohoreskimaster
commit
2a5abb4d6a
|
|
@ -9091,7 +9091,7 @@
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0.03</real>
|
||||
<real>0.1</real>
|
||||
</map>
|
||||
<key>RenderDebugPipeline</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -2253,52 +2253,98 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
|
|||
}
|
||||
}
|
||||
|
||||
void renderNormals(LLDrawable* drawablep)
|
||||
void renderNormals(LLDrawable *drawablep)
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
if (!drawablep->isVisible())
|
||||
return;
|
||||
|
||||
LLVOVolume* vol = drawablep->getVOVolume();
|
||||
if (vol)
|
||||
{
|
||||
LLVolume* volume = vol->getVolume();
|
||||
gGL.pushMatrix();
|
||||
gGL.multMatrix((F32*) vol->getRelativeXform().mMatrix);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
LLVector4a scale(gSavedSettings.getF32("RenderDebugNormalScale"));
|
||||
LLVOVolume *vol = drawablep->getVOVolume();
|
||||
|
||||
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
|
||||
{
|
||||
const LLVolumeFace& face = volume->getVolumeFace(i);
|
||||
if (vol)
|
||||
{
|
||||
LLVolume *volume = vol->getVolume();
|
||||
|
||||
for (S32 j = 0; j < face.mNumVertices; ++j)
|
||||
{
|
||||
gGL.begin(LLRender::LINES);
|
||||
LLVector4a n,p;
|
||||
|
||||
n.setMul(face.mNormals[j], scale);
|
||||
p.setAdd(face.mPositions[j], n);
|
||||
|
||||
gGL.diffuseColor4f(1,1,1,1);
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
|
||||
if (face.mTangents)
|
||||
{
|
||||
n.setMul(face.mTangents[j], scale);
|
||||
p.setAdd(face.mPositions[j], n);
|
||||
|
||||
gGL.diffuseColor4f(0,1,1,1);
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
}
|
||||
// Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied.
|
||||
//
|
||||
// SL-13490, using pos + normal to compute the 2nd vertex of a normal line segment doesn't
|
||||
// work when there's a non-uniform scale in the mix. Normals require MVP-inverse-transpose
|
||||
// transform. We get that effect here by pre-applying the inverse scale (twice, because
|
||||
// one forward scale will be re-applied via the MVP in the vertex shader)
|
||||
|
||||
gGL.popMatrix();
|
||||
}
|
||||
LLVector3 scale_v3 = vol->getScale();
|
||||
LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
|
||||
obj_scale.normalize3();
|
||||
|
||||
float draw_length = gSavedSettings.getF32("RenderDebugNormalScale");
|
||||
|
||||
// Create inverse-scale vector for normals
|
||||
LLVector4a inv_scale(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ]);
|
||||
inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
|
||||
inv_scale.normalize3fast();
|
||||
|
||||
gGL.pushMatrix();
|
||||
gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
|
||||
{
|
||||
const LLVolumeFace &face = volume->getVolumeFace(i);
|
||||
|
||||
gGL.flush();
|
||||
gGL.diffuseColor4f(1, 1, 0, 1);
|
||||
gGL.begin(LLRender::LINES);
|
||||
for (S32 j = 0; j < face.mNumVertices; ++j)
|
||||
{
|
||||
LLVector4a n, p;
|
||||
|
||||
n.setMul(face.mNormals[j], 1.0);
|
||||
n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
|
||||
n.normalize3fast();
|
||||
|
||||
// Since we send 2 vertices instead of a vertex and a vector, the drawn normal length ends up
|
||||
// getting stretched along with the object. To minimize that effect (imperfectly), reduce its
|
||||
// length by a dot factor with the dominant scale direction.
|
||||
float mvp_scale_factor = 0.95 * abs(n.dot3(obj_scale).getF32());
|
||||
n.mul((1.0 - mvp_scale_factor) * draw_length);
|
||||
p.setAdd(face.mPositions[j], n);
|
||||
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
|
||||
// Tangents are simple vectors and do not require reorientation via pre-scaling
|
||||
if (face.mTangents)
|
||||
{
|
||||
gGL.flush();
|
||||
gGL.diffuseColor4f(0, 1, 1, 1);
|
||||
gGL.begin(LLRender::LINES);
|
||||
for (S32 j = 0; j < face.mNumVertices; ++j)
|
||||
{
|
||||
LLVector4a t, p;
|
||||
|
||||
t.setMul(face.mTangents[j], 1.0f);
|
||||
t.normalize3fast();
|
||||
|
||||
// Since we send 2 vertices instead of a vertex and a vector, the drawn tangent length ends up
|
||||
// getting stretched along with the object. To minimize that effect (imperfectly), reduce its
|
||||
// length by a dot factor with the dominant scale direction.
|
||||
float mvp_scale_factor = 0.95 * abs(t.dot3(obj_scale).getF32());
|
||||
t.mul((1.0 - mvp_scale_factor) * draw_length);
|
||||
p.setAdd(face.mPositions[j], t);
|
||||
|
||||
gGL.vertex3fv(face.mPositions[j].getF32ptr());
|
||||
gGL.vertex3fv(p.getF32ptr());
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
}
|
||||
|
||||
gGL.popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& scale)
|
||||
|
|
|
|||
Loading…
Reference in New Issue