UV Tool: add patch support
patch controls move modifiers: shift = only move along the axis with the biggest move, ctrl = snap hard to grid and povit lines fix a couple of Patch::Calculate_AvgNormal() and Patch::NaturalTexture() problems
This commit is contained in:
parent
684187c4ec
commit
2426697f65
|
|
@ -59,6 +59,12 @@ BasicVector3( const BasicVector3<OtherElement>& other ){
|
|||
y() = static_cast<Element>( other.y() );
|
||||
z() = static_cast<Element>( other.z() );
|
||||
}
|
||||
template<typename OtherElement>
|
||||
explicit BasicVector3( const BasicVector2<OtherElement>& vec2 ){
|
||||
x() = static_cast<Element>( vec2.x() );
|
||||
y() = static_cast<Element>( vec2.y() );
|
||||
z() = 0;
|
||||
}
|
||||
BasicVector3( const Element& x_, const Element& y_, const Element& z_ ){
|
||||
x() = x_;
|
||||
y() = y_;
|
||||
|
|
|
|||
|
|
@ -1581,7 +1581,7 @@ double Det3x3( double a00, double a01, double a02,
|
|||
+ a02 * ( a10 * a21 - a11 * a20 );
|
||||
}
|
||||
|
||||
void BP_from_ST( brushprimit_texdef_t& bp, const DoubleVector3 points[3], const DoubleVector3 st[3], const DoubleVector3& normal ){
|
||||
void BP_from_ST( brushprimit_texdef_t& bp, const DoubleVector3 points[3], const DoubleVector3 st[3], const DoubleVector3& normal, const bool normalize = true ){
|
||||
double xyI[2], xyJ[2], xyK[2];
|
||||
double stI[2], stJ[2], stK[2];
|
||||
double D, D0, D1, D2;
|
||||
|
|
@ -1627,7 +1627,7 @@ void BP_from_ST( brushprimit_texdef_t& bp, const DoubleVector3 points[3], const
|
|||
);
|
||||
bp.coords[i][0] = D0 / D;
|
||||
bp.coords[i][1] = D1 / D;
|
||||
bp.coords[i][2] = fmod( D2 / D, 1.0 );
|
||||
bp.coords[i][2] = normalize? fmod( D2 / D, 1.0 ) : ( D2 / D );
|
||||
}
|
||||
// globalOutputStream() << "BP out: ( " << bp.coords[0][0] << " " << bp.coords[0][1] << " " << bp.coords[0][2] << " ) ( " << bp.coords[1][0] << " " << bp.coords[1][1] << " " << bp.coords[1][2] << " )\n";
|
||||
}
|
||||
|
|
@ -2172,6 +2172,22 @@ void Texdef_from_ST( TextureProjection& projection, const DoubleVector3 points[3
|
|||
}
|
||||
}
|
||||
|
||||
void Texdef_Construct_local2tex_from_ST( const DoubleVector3 points[3], const DoubleVector3 st[3], Matrix4& local2tex ){
|
||||
const Plane3 plane( plane3_for_points( points ) );
|
||||
brushprimit_texdef_t bp;
|
||||
BP_from_ST( bp, points, st, plane.normal(), false );
|
||||
|
||||
BPTexdef_toTransform( bp, local2tex );
|
||||
{
|
||||
// Texdef_basisForNormal
|
||||
Matrix4 basis = g_matrix4_identity;
|
||||
ComputeAxisBase( plane.normal(), vector4_to_vector3( basis.x() ), vector4_to_vector3( basis.y() ) );
|
||||
vector4_to_vector3( basis.z() ) = plane.normal();
|
||||
matrix4_transpose( basis );
|
||||
matrix4_multiply_by_matrix4( local2tex, basis );
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Texdef_getTexAxes( const TextureProjection& projection, const Plane3& plane, std::size_t width, std::size_t height, Matrix4& local2tex, Matrix4& tex2local, Matrix4& basis ){
|
||||
Texdef_Construct_local2tex( projection, width, height, plane.normal(), local2tex );
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, st
|
|||
void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat, bool only_dimension );
|
||||
void Texdef_Construct_local2tex( const TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, Matrix4& local2tex );
|
||||
void Texdef_Construct_local2tex4projection( const texdef_t& texdef, std::size_t width, std::size_t height, const Vector3& normal, const Vector3* direction, Matrix4& local2tex );
|
||||
void Texdef_Construct_local2tex_from_ST( const DoubleVector3 points[3], const DoubleVector3 st[3], Matrix4& local2tex );
|
||||
void Texdef_EmitTextureCoordinates( const TextureProjection& projection, std::size_t width, std::size_t height, Winding& w, const Vector3& normal, const Matrix4& localToWorld );
|
||||
|
||||
void ShiftScaleRotate_fromFace( texdef_t& shiftScaleRotate, const TextureProjection& projection );
|
||||
|
|
|
|||
|
|
@ -604,42 +604,52 @@ void Patch::SetTextureRepeat( float s, float t ){
|
|||
}
|
||||
*/
|
||||
|
||||
Vector3 Patch::Calculate_AvgNormal(){
|
||||
Vector3 wDir( 0, 0, 0 ), hDir( 0, 0, 0 );
|
||||
for ( std::size_t i = 0; i < m_height; ++i ){
|
||||
wDir += ctrlAt( i, m_width - 1 ).m_vertex - ctrlAt( i, 0 ).m_vertex;
|
||||
void Patch::Calculate_AvgAxes( Vector3& wDir, Vector3& hDir ) const {
|
||||
wDir = hDir = g_vector3_identity;
|
||||
for ( std::size_t r = 0; r < m_height; ++r ){
|
||||
wDir += ctrlAt( r, m_width - 1 ).m_vertex - ctrlAt( r, 0 ).m_vertex;
|
||||
}
|
||||
for ( std::size_t i = 0; i < m_width; ++i ){
|
||||
hDir += ctrlAt( m_height - 1, i ).m_vertex - ctrlAt( 0, i ).m_vertex;
|
||||
for ( std::size_t c = 0; c < m_width; ++c ){
|
||||
hDir += ctrlAt( m_height - 1, c ).m_vertex - ctrlAt( 0, c ).m_vertex;
|
||||
}
|
||||
/* fallback */
|
||||
if ( vector3_equal_epsilon( wDir, g_vector3_identity, 1e-3f ) || vector3_equal_epsilon( hDir, g_vector3_identity, 1e-3f ) ) {
|
||||
for ( std::size_t i = 0; i < m_height; ++i ){
|
||||
for ( std::size_t j = 0; j < m_width - 1; ++j ){
|
||||
wDir = ctrlAt( i, j + 1 ).m_vertex - ctrlAt( i, j ).m_vertex;
|
||||
if ( !vector3_equal_epsilon( wDir, g_vector3_identity, 1e-3f ) )
|
||||
goto break1;
|
||||
}
|
||||
}
|
||||
break1:
|
||||
for ( std::size_t i = 0; i < m_width; ++i ){
|
||||
for ( std::size_t j = 0; j < m_height; ++j ){
|
||||
hDir = ctrlAt( j + 1, i ).m_vertex - ctrlAt( j, i ).m_vertex;
|
||||
if ( !vector3_equal_epsilon( hDir, g_vector3_identity, 1e-3f ) )
|
||||
goto break2;
|
||||
/* fallback to longest hord */
|
||||
if ( vector3_equal_epsilon( wDir, g_vector3_identity, 1.f ) ){
|
||||
float bestLength = 0;
|
||||
for ( std::size_t r = 0; r < m_height; ++r ){
|
||||
for ( std::size_t c = 0; c < m_width - 1; ++c ){
|
||||
const Vector3 dir = ctrlAt( r, c + 1 ).m_vertex - ctrlAt( r, c ).m_vertex;
|
||||
const float length = vector3_length( dir );
|
||||
if ( length - bestLength > 1 ){
|
||||
bestLength = length;
|
||||
wDir = dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( vector3_equal_epsilon( hDir, g_vector3_identity, 1.f ) ){
|
||||
float bestLength = 0;
|
||||
for ( std::size_t c = 0; c < m_width; ++c ){
|
||||
for ( std::size_t r = 0; r < m_height - 1; ++r ){
|
||||
const Vector3 dir = ctrlAt( r + 1, c ).m_vertex - ctrlAt( r, c ).m_vertex;
|
||||
const float length = vector3_length( dir );
|
||||
if ( length - bestLength > 1 ){
|
||||
bestLength = length;
|
||||
hDir = dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break2:
|
||||
|
||||
Vector3 normal( vector3_cross( wDir, hDir ) );
|
||||
if ( vector3_equal( normal, g_vector3_identity ) ) {
|
||||
normal = Vector3( 0, 0, 1 );
|
||||
if ( vector3_equal_epsilon( vector3_cross( wDir, hDir ), g_vector3_identity, 0.1f ) ) {
|
||||
wDir = g_vector3_axis_x;
|
||||
hDir = g_vector3_axis_y;
|
||||
}
|
||||
else{
|
||||
vector3_normalise( normal );
|
||||
}
|
||||
return normal;
|
||||
}
|
||||
|
||||
Vector3 Patch::Calculate_AvgNormal() const {
|
||||
Vector3 wDir, hDir;
|
||||
Calculate_AvgAxes( wDir, hDir );
|
||||
return vector3_normalised( vector3_cross( wDir, hDir ) );
|
||||
}
|
||||
|
||||
inline int texture_axis( const Vector3& normal ){
|
||||
|
|
@ -693,16 +703,16 @@ void Patch::NaturalTexture(){
|
|||
undoSave();
|
||||
|
||||
{
|
||||
float fSize = (float)m_state->getTexture().width * Texdef_getDefaultTextureScale();
|
||||
const double texSize = (double)m_state->getTexture().width * Texdef_getDefaultTextureScale();
|
||||
|
||||
double texBest = 0;
|
||||
double tex = 0;
|
||||
PatchControl* pWidth = m_ctrl.data();
|
||||
for ( std::size_t w = 0; w < m_width; w++, pWidth++ )
|
||||
for ( std::size_t w = 0; w < m_width; ++w, ++pWidth )
|
||||
{
|
||||
{
|
||||
PatchControl* pHeight = pWidth;
|
||||
for ( std::size_t h = 0; h < m_height; h++, pHeight += m_width )
|
||||
for ( std::size_t h = 0; h < m_height; ++h, pHeight += m_width )
|
||||
pHeight->m_texcoord[0] = static_cast<float>( tex );
|
||||
}
|
||||
|
||||
|
|
@ -711,12 +721,11 @@ void Patch::NaturalTexture(){
|
|||
}
|
||||
|
||||
{
|
||||
PatchControl* pHeight = pWidth;
|
||||
for ( std::size_t h = 0; h < m_height; h++, pHeight += m_width )
|
||||
const PatchControl* pHeight = pWidth;
|
||||
for ( std::size_t h = 0; h < m_height; ++h, pHeight += m_width )
|
||||
{
|
||||
Vector3 v( vector3_subtracted( pHeight->m_vertex, ( pHeight + 1 )->m_vertex ) );
|
||||
double length = tex + ( vector3_length( v ) / fSize );
|
||||
if ( fabs( length ) > texBest ) {
|
||||
const double length = tex + ( vector3_length( pHeight->m_vertex - ( pHeight + 1 )->m_vertex ) / texSize );
|
||||
if ( fabs( length ) > fabs( texBest ) ) { // comparing abs values supports possible negative Texdef_getDefaultTextureScale()
|
||||
texBest = length;
|
||||
}
|
||||
}
|
||||
|
|
@ -727,16 +736,16 @@ void Patch::NaturalTexture(){
|
|||
}
|
||||
|
||||
{
|
||||
float fSize = -(float)m_state->getTexture().height * Texdef_getDefaultTextureScale();
|
||||
const double texSize = -(double)m_state->getTexture().height * Texdef_getDefaultTextureScale();
|
||||
|
||||
double texBest = 0;
|
||||
double tex = 0;
|
||||
PatchControl* pHeight = m_ctrl.data();
|
||||
for ( std::size_t h = 0; h < m_height; h++, pHeight += m_width )
|
||||
for ( std::size_t h = 0; h < m_height; ++h, pHeight += m_width )
|
||||
{
|
||||
{
|
||||
PatchControl* pWidth = pHeight;
|
||||
for ( std::size_t w = 0; w < m_width; w++, pWidth++ )
|
||||
for ( std::size_t w = 0; w < m_width; ++w, ++pWidth )
|
||||
pWidth->m_texcoord[1] = static_cast<float>( tex );
|
||||
}
|
||||
|
||||
|
|
@ -745,12 +754,11 @@ void Patch::NaturalTexture(){
|
|||
}
|
||||
|
||||
{
|
||||
PatchControl* pWidth = pHeight;
|
||||
for ( std::size_t w = 0; w < m_width; w++, pWidth++ )
|
||||
const PatchControl* pWidth = pHeight;
|
||||
for ( std::size_t w = 0; w < m_width; ++w, ++pWidth )
|
||||
{
|
||||
Vector3 v( vector3_subtracted( pWidth->m_vertex, ( pWidth + m_width )->m_vertex ) );
|
||||
double length = tex + ( vector3_length( v ) / fSize );
|
||||
if ( fabs( length ) > texBest ) {
|
||||
const double length = tex + ( vector3_length( pWidth->m_vertex - ( pWidth + m_width )->m_vertex ) / texSize );
|
||||
if ( fabs( length ) > fabs( texBest ) ) {
|
||||
texBest = length;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -930,7 +930,8 @@ void RotateTexture( float angle );
|
|||
void SetTextureRepeat( float s, float t ); // call with s=1 t=1 for FIT
|
||||
void CapTexture();
|
||||
void NaturalTexture();
|
||||
Vector3 Calculate_AvgNormal();
|
||||
Vector3 Calculate_AvgNormal() const;
|
||||
void Calculate_AvgAxes( Vector3& wDir, Vector3& hDir ) const;
|
||||
void ProjectTexture( TextureProjection projection, const Vector3& normal );
|
||||
void ProjectTexture( const texdef_t& texdef, const Vector3* direction );
|
||||
void createThickenedOpposite(const Patch& sourcePatch, const float thickness, const int axis, bool& no12, bool& no34 );
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user