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() );
|
y() = static_cast<Element>( other.y() );
|
||||||
z() = static_cast<Element>( other.z() );
|
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_ ){
|
BasicVector3( const Element& x_, const Element& y_, const Element& z_ ){
|
||||||
x() = x_;
|
x() = x_;
|
||||||
y() = y_;
|
y() = y_;
|
||||||
|
|
|
||||||
|
|
@ -1581,7 +1581,7 @@ double Det3x3( double a00, double a01, double a02,
|
||||||
+ a02 * ( a10 * a21 - a11 * a20 );
|
+ 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 xyI[2], xyJ[2], xyK[2];
|
||||||
double stI[2], stJ[2], stK[2];
|
double stI[2], stJ[2], stK[2];
|
||||||
double D, D0, D1, D2;
|
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][0] = D0 / D;
|
||||||
bp.coords[i][1] = D1 / 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";
|
// 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
|
#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 ){
|
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 );
|
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_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_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_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 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 );
|
void ShiftScaleRotate_fromFace( texdef_t& shiftScaleRotate, const TextureProjection& projection );
|
||||||
|
|
|
||||||
|
|
@ -604,42 +604,52 @@ void Patch::SetTextureRepeat( float s, float t ){
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Vector3 Patch::Calculate_AvgNormal(){
|
void Patch::Calculate_AvgAxes( Vector3& wDir, Vector3& hDir ) const {
|
||||||
Vector3 wDir( 0, 0, 0 ), hDir( 0, 0, 0 );
|
wDir = hDir = g_vector3_identity;
|
||||||
for ( std::size_t i = 0; i < m_height; ++i ){
|
for ( std::size_t r = 0; r < m_height; ++r ){
|
||||||
wDir += ctrlAt( i, m_width - 1 ).m_vertex - ctrlAt( i, 0 ).m_vertex;
|
wDir += ctrlAt( r, m_width - 1 ).m_vertex - ctrlAt( r, 0 ).m_vertex;
|
||||||
}
|
}
|
||||||
for ( std::size_t i = 0; i < m_width; ++i ){
|
for ( std::size_t c = 0; c < m_width; ++c ){
|
||||||
hDir += ctrlAt( m_height - 1, i ).m_vertex - ctrlAt( 0, i ).m_vertex;
|
hDir += ctrlAt( m_height - 1, c ).m_vertex - ctrlAt( 0, c ).m_vertex;
|
||||||
}
|
}
|
||||||
/* fallback */
|
/* fallback to longest hord */
|
||||||
if ( vector3_equal_epsilon( wDir, g_vector3_identity, 1e-3f ) || vector3_equal_epsilon( hDir, g_vector3_identity, 1e-3f ) ) {
|
if ( vector3_equal_epsilon( wDir, g_vector3_identity, 1.f ) ){
|
||||||
for ( std::size_t i = 0; i < m_height; ++i ){
|
float bestLength = 0;
|
||||||
for ( std::size_t j = 0; j < m_width - 1; ++j ){
|
for ( std::size_t r = 0; r < m_height; ++r ){
|
||||||
wDir = ctrlAt( i, j + 1 ).m_vertex - ctrlAt( i, j ).m_vertex;
|
for ( std::size_t c = 0; c < m_width - 1; ++c ){
|
||||||
if ( !vector3_equal_epsilon( wDir, g_vector3_identity, 1e-3f ) )
|
const Vector3 dir = ctrlAt( r, c + 1 ).m_vertex - ctrlAt( r, c ).m_vertex;
|
||||||
goto break1;
|
const float length = vector3_length( dir );
|
||||||
}
|
if ( length - bestLength > 1 ){
|
||||||
}
|
bestLength = length;
|
||||||
break1:
|
wDir = dir;
|
||||||
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;
|
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_epsilon( vector3_cross( wDir, hDir ), g_vector3_identity, 0.1f ) ) {
|
||||||
if ( vector3_equal( normal, g_vector3_identity ) ) {
|
wDir = g_vector3_axis_x;
|
||||||
normal = Vector3( 0, 0, 1 );
|
hDir = g_vector3_axis_y;
|
||||||
}
|
}
|
||||||
else{
|
}
|
||||||
vector3_normalise( normal );
|
|
||||||
}
|
Vector3 Patch::Calculate_AvgNormal() const {
|
||||||
return normal;
|
Vector3 wDir, hDir;
|
||||||
|
Calculate_AvgAxes( wDir, hDir );
|
||||||
|
return vector3_normalised( vector3_cross( wDir, hDir ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int texture_axis( const Vector3& normal ){
|
inline int texture_axis( const Vector3& normal ){
|
||||||
|
|
@ -693,16 +703,16 @@ void Patch::NaturalTexture(){
|
||||||
undoSave();
|
undoSave();
|
||||||
|
|
||||||
{
|
{
|
||||||
float fSize = (float)m_state->getTexture().width * Texdef_getDefaultTextureScale();
|
const double texSize = (double)m_state->getTexture().width * Texdef_getDefaultTextureScale();
|
||||||
|
|
||||||
double texBest = 0;
|
double texBest = 0;
|
||||||
double tex = 0;
|
double tex = 0;
|
||||||
PatchControl* pWidth = m_ctrl.data();
|
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;
|
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 );
|
pHeight->m_texcoord[0] = static_cast<float>( tex );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -711,12 +721,11 @@ void Patch::NaturalTexture(){
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PatchControl* pHeight = pWidth;
|
const 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 )
|
||||||
{
|
{
|
||||||
Vector3 v( vector3_subtracted( pHeight->m_vertex, ( pHeight + 1 )->m_vertex ) );
|
const double length = tex + ( vector3_length( pHeight->m_vertex - ( pHeight + 1 )->m_vertex ) / texSize );
|
||||||
double length = tex + ( vector3_length( v ) / fSize );
|
if ( fabs( length ) > fabs( texBest ) ) { // comparing abs values supports possible negative Texdef_getDefaultTextureScale()
|
||||||
if ( fabs( length ) > texBest ) {
|
|
||||||
texBest = length;
|
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 texBest = 0;
|
||||||
double tex = 0;
|
double tex = 0;
|
||||||
PatchControl* pHeight = m_ctrl.data();
|
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;
|
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 );
|
pWidth->m_texcoord[1] = static_cast<float>( tex );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -745,12 +754,11 @@ void Patch::NaturalTexture(){
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PatchControl* pWidth = pHeight;
|
const 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 )
|
||||||
{
|
{
|
||||||
Vector3 v( vector3_subtracted( pWidth->m_vertex, ( pWidth + m_width )->m_vertex ) );
|
const double length = tex + ( vector3_length( pWidth->m_vertex - ( pWidth + m_width )->m_vertex ) / texSize );
|
||||||
double length = tex + ( vector3_length( v ) / fSize );
|
if ( fabs( length ) > fabs( texBest ) ) {
|
||||||
if ( fabs( length ) > texBest ) {
|
|
||||||
texBest = length;
|
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 SetTextureRepeat( float s, float t ); // call with s=1 t=1 for FIT
|
||||||
void CapTexture();
|
void CapTexture();
|
||||||
void NaturalTexture();
|
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( TextureProjection projection, const Vector3& normal );
|
||||||
void ProjectTexture( const texdef_t& texdef, const Vector3* direction );
|
void ProjectTexture( const texdef_t& texdef, const Vector3* direction );
|
||||||
void createThickenedOpposite(const Patch& sourcePatch, const float thickness, const int axis, bool& no12, bool& no34 );
|
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