Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

144 lines
4.0 KiB

//=========== Copyright © Valve Corporation, All rights reserved. ============//
//
// Purpose: Quadric math functionality used for squared distance error metrics.
//
//===========================================================================//
#ifndef QUADRIC_H
#define QUADRIC_H
#if defined( COMPILER_MSVC )
#pragma once
#endif
#include "vector.h"
#include "cholesky.h"
// this class holds a quadric error function and implements integrating and evaluating these functions.
// see "Surface Simplfication using Quadric Error metrics. Garland, Heckbert"
// http://mgarland.org/files/papers/quadric2.pdf (updated version)
// NOTE: This will be expanded using Hughes Hoppe's method for including interpolated vertex attributes in a future version
class CQuadricError
{
public:
CQuadricError() {}
// used this to track down error
void CheckDebug()
{
Assert( IsFinite(m_coefficients[0]) );
}
// integrate these by summing coefficients
FORCEINLINE CQuadricError& operator+=(const CQuadricError &inError)
{
for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
{
m_coefficients[i] += inError.m_coefficients[i];
}
return *this;
}
CQuadricError operator+(const CQuadricError& inError0 ) const
{
CQuadricError tmp;
for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
{
tmp.m_coefficients[i] = inError0.m_coefficients[i] + m_coefficients[i];
}
return tmp;
}
// assignment
CQuadricError& operator=(const CQuadricError &inError0)
{
for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
{
m_coefficients[i] = inError0.m_coefficients[i];
}
return *this;
}
CQuadricError& operator*=( float flScale )
{
for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
{
m_coefficients[i] *= flScale;
}
return *this;
}
// solves for the point with minimum error (inverts the matrix)
Vector SolveForMinimumError()
{
matrix3x4_t tmp(
m_coefficients[0], m_coefficients[1]*0.5f, m_coefficients[2]*0.5f, m_coefficients[3]*0.5f,
m_coefficients[1]*0.5f, m_coefficients[4], m_coefficients[5]*0.5f, m_coefficients[6]*0.5f,
m_coefficients[2]*0.5f, m_coefficients[5]*0.5f, m_coefficients[7], m_coefficients[8]*0.5f );
return CholeskySolve( tmp );
}
// clear all coefficients
void SetToZero()
{
for ( int i = 0; i < ARRAYSIZE(m_coefficients); i++ )
{
m_coefficients[i] = 0.0f;
}
}
// usually these are initialized by summing quadrics for the planes coincident at each vert (one per triangle)
// these are helpers to do that
void InitFromPlane( const Vector &vNormal, float flDist, float flScale )
{
float flScale2 = flScale * 2.0f;
m_coefficients[0] = vNormal.x * vNormal.x * flScale; // a^2
m_coefficients[1] = vNormal.x * vNormal.y * flScale2; // 2ab
m_coefficients[2] = vNormal.x * vNormal.z * flScale2; // 2ac
m_coefficients[3] = vNormal.x * flDist * flScale2; // 2ad
m_coefficients[4] = vNormal.y * vNormal.y * flScale; // b^2
m_coefficients[5] = vNormal.y * vNormal.z * flScale2; // 2bc
m_coefficients[6] = vNormal.y * flDist * flScale2; // 2bd
m_coefficients[7] = vNormal.z * vNormal.z * flScale; // c^2
m_coefficients[8] = vNormal.z * flDist * flScale2; // cd
m_coefficients[9] = flDist * flDist * flScale; // d^2
}
void InitFromTriangle( const Vector &v0, const Vector &v1, const Vector &v2, float flMinArea )
{
Vector vNormal = CrossProduct( v2 - v0, v1 - v0 );
float flArea = 0.5f * vNormal.NormalizeInPlace();
flArea = MAX(flMinArea, flArea);
float flDist = -DotProduct(vNormal, v0);
InitFromPlane( vNormal, flDist, flArea );
}
// this evaluates the error at a point in space
inline float ComputeError( const Vector &v0 )
{
float x = v0.x;
float y = v0.y;
float z = v0.z;
float flVertex[9];
flVertex[0] = x * x;
flVertex[1] = x * y;
flVertex[2] = x * z;
flVertex[3] = x;
flVertex[4] = y * y;
flVertex[5] = y * z;
flVertex[6] = y;
flVertex[7] = z * z;
flVertex[8] = z;
float flTotal = m_coefficients[9];
for ( int i = 0; i < 9; i++ )
{
flTotal += flVertex[i] * m_coefficients[i];
}
return flTotal;
}
private:
float m_coefficients[10];
};
#endif // QUADRIC_H