Radiant:
binds... * ctrl + shift + m3/drag: project tex from face in tex clipboard to brushes(BP format) and curves misc... * fixed and improved normal finding in patch texture autocap algorithm * removed axis cycling in patch cap texture; using autocap * patch cap texture: project, using brush texture projection math of current mapformat to make it seamless with brushes by default * Surface inspector->Project functions work for curves (in AP map format too)
This commit is contained in:
parent
b0c4caa9d1
commit
da43652df1
|
|
@ -598,6 +598,10 @@ void ProjectTexture( const Plane3& plane, const texdef_t& texdef, const Vector3*
|
|||
Texdef_ProjectTexture( m_projection, m_shader.width(), m_shader.height(), plane, texdef, direction );
|
||||
}
|
||||
|
||||
void ProjectTexture( const Plane3& plane, const TextureProjection& projection, const Vector3& normal ){
|
||||
Texdef_ProjectTexture( m_projection, m_shader.width(), m_shader.height(), plane, projection, normal );
|
||||
}
|
||||
|
||||
void fit( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat ){
|
||||
Texdef_FitTexture( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat );
|
||||
}
|
||||
|
|
@ -1213,6 +1217,12 @@ void ProjectTexture( const texdef_t& texdef, const Vector3* direction ){
|
|||
texdefChanged();
|
||||
}
|
||||
|
||||
void ProjectTexture( const TextureProjection& projection, const Vector3& normal ){
|
||||
undoSave();
|
||||
m_texdef.ProjectTexture( m_plane.plane3(), projection, normal );
|
||||
texdefChanged();
|
||||
}
|
||||
|
||||
void FitTexture( float s_repeat, float t_repeat ){
|
||||
undoSave();
|
||||
m_texdef.fit( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat );
|
||||
|
|
|
|||
|
|
@ -256,6 +256,15 @@ void Texdef_basisForNormal( const TextureProjection& projection, const Vector3&
|
|||
}
|
||||
}
|
||||
|
||||
void Texdef_Construct_local2tex( const TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, Matrix4& local2tex ){
|
||||
Texdef_toTransform( projection, (float)width, (float)height, local2tex );
|
||||
{
|
||||
Matrix4 xyz2st;
|
||||
Texdef_basisForNormal( projection, normal, xyz2st );
|
||||
matrix4_multiply_by_matrix4( local2tex, xyz2st );
|
||||
}
|
||||
}
|
||||
|
||||
void Texdef_EmitTextureCoordinates( const TextureProjection& projection, std::size_t width, std::size_t height, Winding& w, const Vector3& normal, const Matrix4& localToWorld ){
|
||||
if ( w.numpoints < 3 ) {
|
||||
return;
|
||||
|
|
@ -1552,8 +1561,7 @@ void Q3_to_BP( const texdef_t& texdef, float width, float height, const Vector3&
|
|||
|
||||
|
||||
/// for arbitrary texture projections
|
||||
void Emit3TextureCoordinates( const texdef_t& texdef, std::size_t width, std::size_t height, const Vector3& normal, DoubleVector3 points[3], DoubleVector3 st[3], 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 ){
|
||||
Texdef_toTransform( texdef, (float)width, (float)height, local2tex );
|
||||
{
|
||||
if( direction ){ //arbitrary
|
||||
|
|
@ -1570,14 +1578,6 @@ void Emit3TextureCoordinates( const texdef_t& texdef, std::size_t width, std::si
|
|||
matrix4_multiply_by_matrix4( local2tex, xyz2st );
|
||||
}
|
||||
}
|
||||
|
||||
for ( std::size_t i = 0; i < 3; ++i )
|
||||
{
|
||||
DoubleVector3 texcoord = matrix4_transformed_point( local2tex, points[i] );
|
||||
//globalOutputStream() << texcoord << "\n";
|
||||
st[i][0] = texcoord[0];
|
||||
st[i][1] = texcoord[1];
|
||||
}
|
||||
}
|
||||
|
||||
void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, const texdef_t& texdef, const Vector3* direction ){
|
||||
|
|
@ -1602,7 +1602,16 @@ void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, st
|
|||
points[0] = anchor;
|
||||
points[1] = texX + anchor;
|
||||
points[2] = texY + anchor;
|
||||
Emit3TextureCoordinates( texdef, width, height, plane.normal(), points, st, direction );
|
||||
|
||||
Matrix4 local2tex;
|
||||
Texdef_Construct_local2tex4projection( texdef, width, height, plane.normal(), direction, local2tex );
|
||||
for ( std::size_t i = 0; i < 3; ++i )
|
||||
{
|
||||
DoubleVector3 texcoord = matrix4_transformed_point( local2tex, points[i] );
|
||||
//globalOutputStream() << texcoord << "\n";
|
||||
st[i][0] = texcoord[0];
|
||||
st[i][1] = texcoord[1];
|
||||
}
|
||||
// compute texture matrix
|
||||
projection.m_brushprimit_texdef.coords[0][2] = st[0][0];
|
||||
projection.m_brushprimit_texdef.coords[1][2] = st[0][1];
|
||||
|
|
@ -1613,3 +1622,55 @@ void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, st
|
|||
|
||||
Texdef_normalise( projection, (float)width, (float)height );
|
||||
}
|
||||
|
||||
void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, TextureProjection other_proj, const Vector3& other_normal ){
|
||||
if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_BRUSHPRIMITIVES ) {
|
||||
other_proj.m_brushprimit_texdef.addScale( width, height );
|
||||
|
||||
DoubleVector3 texX, texY;
|
||||
|
||||
// compute axis base
|
||||
ComputeAxisBase( plane.normal(), texX, texY );
|
||||
// compute projection vector
|
||||
const DoubleVector3 anchor = plane.normal() * plane.dist();
|
||||
|
||||
// (0,0) in plane axis base is (0,0,0) in world coordinates + projection on the affine plane
|
||||
// (1,0) in plane axis base is texX in world coordinates + projection on the affine plane
|
||||
// (0,1) in plane axis base is texY in world coordinates + projection on the affine plane
|
||||
// use old texture code to compute the ST coords of these points
|
||||
// ST of (0,0) (1,0) (0,1)
|
||||
DoubleVector3 points[3];
|
||||
DoubleVector3 st[3];
|
||||
|
||||
points[0] = anchor;
|
||||
points[1] = texX + anchor;
|
||||
points[2] = texY + anchor;
|
||||
|
||||
Matrix4 local2tex;
|
||||
Texdef_Construct_local2tex( other_proj, width, height, other_normal, local2tex );
|
||||
for ( std::size_t i = 0; i < 3; ++i )
|
||||
{
|
||||
DoubleVector3 texcoord = matrix4_transformed_point( local2tex, points[i] );
|
||||
//globalOutputStream() << texcoord << "\n";
|
||||
st[i][0] = texcoord[0];
|
||||
st[i][1] = texcoord[1];
|
||||
}
|
||||
// compute texture matrix
|
||||
projection.m_brushprimit_texdef.coords[0][2] = st[0][0];
|
||||
projection.m_brushprimit_texdef.coords[1][2] = st[0][1];
|
||||
projection.m_brushprimit_texdef.coords[0][0] = st[1][0] - st[0][0];
|
||||
projection.m_brushprimit_texdef.coords[1][0] = st[1][1] - st[0][1];
|
||||
projection.m_brushprimit_texdef.coords[0][1] = st[2][0] - st[0][0];
|
||||
projection.m_brushprimit_texdef.coords[1][1] = st[2][1] - st[0][1];
|
||||
|
||||
Texdef_normalise( projection, (float)width, (float)height );
|
||||
}
|
||||
else
|
||||
{
|
||||
Texdef_Assign( projection.m_texdef, other_proj.m_texdef );
|
||||
if ( g_bp_globals.m_texdefTypeId == TEXDEFTYPEID_HALFLIFE ) {
|
||||
projection.m_basis_s = other_proj.m_basis_s;
|
||||
projection.m_basis_t = other_proj.m_basis_t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,10 @@ void Texdef_Shift( TextureProjection& projection, float s, float t );
|
|||
void Texdef_Scale( TextureProjection& projection, float s, float t );
|
||||
void Texdef_Rotate( TextureProjection& projection, float angle );
|
||||
void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, const texdef_t& texdef, const Vector3* direction );
|
||||
void Texdef_ProjectTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Plane3& plane, TextureProjection other_proj, const Vector3& other_normal );
|
||||
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 );
|
||||
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_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 );
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ void BezierCurveTree_FromCurveList( BezierCurveTree *pTree, GSList *pCurveList,
|
|||
}
|
||||
|
||||
|
||||
int Patch::m_CycleCapIndex = 0;
|
||||
//int Patch::m_CycleCapIndex = 0;
|
||||
|
||||
|
||||
void Patch::setDims( std::size_t w, std::size_t h ){
|
||||
|
|
@ -600,12 +600,31 @@ 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;
|
||||
}
|
||||
for ( std::size_t i = 0; i < m_width; ++i ){
|
||||
hDir += ctrlAt( m_height - 1, i ).m_vertex - ctrlAt( 0, i ).m_vertex;
|
||||
}
|
||||
Vector3 normal( vector3_cross( wDir, hDir ) );
|
||||
if ( vector3_equal( normal, g_vector3_identity ) ) {
|
||||
normal = Vector3( 0, 0, 1 );
|
||||
}
|
||||
else{
|
||||
vector3_normalise( normal );
|
||||
}
|
||||
return normal;
|
||||
}
|
||||
|
||||
inline int texture_axis( const Vector3& normal ){
|
||||
// axis dominance order: Z, X, Y
|
||||
return ( normal.x() >= normal.y() ) ? ( normal.x() > normal.z() ) ? 0 : 2 : ( normal.y() > normal.z() ) ? 1 : 2;
|
||||
}
|
||||
|
||||
void Patch::CapTexture(){
|
||||
#if 0
|
||||
const PatchControl& p1 = m_ctrl[m_width];
|
||||
const PatchControl& p2 = m_ctrl[m_width * ( m_height - 1 )];
|
||||
const PatchControl& p3 = m_ctrl[( m_width * m_height ) - 1];
|
||||
|
|
@ -636,6 +655,12 @@ void Patch::CapTexture(){
|
|||
normal[2] = fabs( normal[2] );
|
||||
|
||||
ProjectTexture( texture_axis( normal ) );
|
||||
#else
|
||||
Vector3 normal = Calculate_AvgNormal();
|
||||
TextureProjection projection;
|
||||
TexDef_Construct_Default( projection );
|
||||
ProjectTexture( projection, normal );
|
||||
#endif
|
||||
}
|
||||
|
||||
// uses longest parallel chord to calculate texture coords for each row/col
|
||||
|
|
@ -1125,7 +1150,7 @@ void Patch::ConstructSeam( EPatchCap eType, Vector3* p, std::size_t width ){
|
|||
CapTexture();
|
||||
controlPointsChanged();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Patch::ProjectTexture( int nAxis ){
|
||||
undoSave();
|
||||
|
||||
|
|
@ -1161,6 +1186,41 @@ void Patch::ProjectTexture( int nAxis ){
|
|||
|
||||
controlPointsChanged();
|
||||
}
|
||||
#else
|
||||
void Patch::ProjectTexture( TextureProjection projection, const Vector3& normal ){
|
||||
undoSave();
|
||||
|
||||
projection.m_brushprimit_texdef.addScale( m_state->getTexture().width, m_state->getTexture().height );
|
||||
|
||||
Matrix4 local2tex;
|
||||
Texdef_Construct_local2tex( projection, m_state->getTexture().width, m_state->getTexture().height, normal, local2tex );
|
||||
|
||||
for ( PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i )
|
||||
{
|
||||
Vector3 texcoord = matrix4_transformed_point( local2tex, ( *i ).m_vertex );
|
||||
( *i ).m_texcoord[0] = texcoord[0];
|
||||
( *i ).m_texcoord[1] = texcoord[1];
|
||||
}
|
||||
|
||||
controlPointsChanged();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Patch::ProjectTexture( const texdef_t& texdef, const Vector3* direction ){
|
||||
undoSave();
|
||||
|
||||
Matrix4 local2tex;
|
||||
Texdef_Construct_local2tex4projection( texdef, m_state->getTexture().width, m_state->getTexture().height, Calculate_AvgNormal(), direction, local2tex );
|
||||
|
||||
for ( PatchControlIter i = m_ctrl.data(); i != m_ctrl.data() + m_ctrl.size(); ++i )
|
||||
{
|
||||
Vector3 texcoord = matrix4_transformed_point( local2tex, ( *i ).m_vertex );
|
||||
( *i ).m_texcoord[0] = texcoord[0];
|
||||
( *i ).m_texcoord[1] = texcoord[1];
|
||||
}
|
||||
|
||||
controlPointsChanged();
|
||||
}
|
||||
|
||||
void Patch::constructPlane( const AABB& aabb, int axis, std::size_t width, std::size_t height ){
|
||||
setDims( width, height );
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@
|
|||
#include "xml/ixml.h"
|
||||
#include "dragplanes.h"
|
||||
|
||||
#include "brush_primit.h"
|
||||
|
||||
enum EPatchType
|
||||
{
|
||||
ePatchTypeQuake3,
|
||||
|
|
@ -467,7 +469,7 @@ void construct(){
|
|||
public:
|
||||
Callback m_lightsChanged;
|
||||
|
||||
static int m_CycleCapIndex; // = 0;
|
||||
//static int m_CycleCapIndex; // = 0;
|
||||
static EPatchType m_type;
|
||||
|
||||
STRING_CONSTANT( Name, "Patch" );
|
||||
|
|
@ -921,7 +923,9 @@ void RotateTexture( float angle );
|
|||
void SetTextureRepeat( float s, float t ); // call with s=1 t=1 for FIT
|
||||
void CapTexture();
|
||||
void NaturalTexture();
|
||||
void ProjectTexture( int nAxis );
|
||||
Vector3 Calculate_AvgNormal();
|
||||
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 );
|
||||
void createThickenedWall(const Patch& sourcePatch, const Patch& targetPatch, const int wallIndex);
|
||||
|
||||
|
|
|
|||
|
|
@ -291,13 +291,31 @@ class PatchCapTexture
|
|||
{
|
||||
public:
|
||||
void operator()( Patch& patch ) const {
|
||||
patch.ProjectTexture( Patch::m_CycleCapIndex );
|
||||
//patch.ProjectTexture( Patch::m_CycleCapIndex );
|
||||
patch.CapTexture();
|
||||
}
|
||||
};
|
||||
|
||||
void Scene_PatchCapTexture_Selected( scene::Graph& graph ){
|
||||
Scene_forEachVisibleSelectedPatch( PatchCapTexture() );
|
||||
Patch::m_CycleCapIndex = ( Patch::m_CycleCapIndex + 1 ) % 3;
|
||||
//Patch::m_CycleCapIndex = ( Patch::m_CycleCapIndex + 1 ) % 3;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
|
||||
class PatchProjectTexture
|
||||
{
|
||||
const texdef_t& m_texdef;
|
||||
const Vector3* m_direction;
|
||||
public:
|
||||
PatchProjectTexture( const texdef_t& texdef, const Vector3* direction ) : m_texdef( texdef ), m_direction( direction ) {
|
||||
}
|
||||
void operator()( Patch& patch ) const {
|
||||
patch.ProjectTexture( m_texdef, m_direction );
|
||||
}
|
||||
};
|
||||
|
||||
void Scene_PatchProjectTexture_Selected( scene::Graph& graph, const texdef_t& texdef, const Vector3* direction ){
|
||||
Scene_forEachVisibleSelectedPatch( PatchProjectTexture( texdef, direction ) );
|
||||
SceneChangeNotify();
|
||||
}
|
||||
|
||||
|
|
@ -674,12 +692,6 @@ void Patch_Cap(){
|
|||
Scene_PatchDoCap_Selected( GlobalSceneGraph(), TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ) );
|
||||
}
|
||||
|
||||
void Patch_CycleProjection(){
|
||||
UndoableCommand undo( "patchCycleUVProjectionAxis" );
|
||||
|
||||
Scene_PatchCapTexture_Selected( GlobalSceneGraph() );
|
||||
}
|
||||
|
||||
///\todo Unfinished.
|
||||
void Patch_OverlayOn(){
|
||||
}
|
||||
|
|
@ -849,7 +861,7 @@ void Patch_registerCommands(){
|
|||
GlobalCommands_insert( "SmoothCols", FreeCaller<Patch_SmoothCols>(), Accelerator( 'W', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
|
||||
GlobalCommands_insert( "MatrixTranspose", FreeCaller<Patch_Transpose>(), Accelerator( 'M', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
|
||||
GlobalCommands_insert( "CapCurrentCurve", FreeCaller<Patch_Cap>(), Accelerator( 'C', (GdkModifierType)GDK_SHIFT_MASK ) );
|
||||
GlobalCommands_insert( "CycleCapTexturePatch", FreeCaller<Patch_CycleProjection>(), Accelerator( 'N', (GdkModifierType)GDK_SHIFT_MASK ) );
|
||||
GlobalCommands_insert( "PatchCapTexture", FreeCaller<Patch_CapTexture>(), Accelerator( 'N', (GdkModifierType)GDK_SHIFT_MASK ) );
|
||||
// GlobalCommands_insert( "MakeOverlayPatch", FreeCaller<Patch_OverlayOn>(), Accelerator( 'Y' ) );
|
||||
// GlobalCommands_insert( "ClearPatchOverlays", FreeCaller<Patch_OverlayOff>(), Accelerator( 'L', (GdkModifierType)GDK_CONTROL_MASK ) );
|
||||
GlobalCommands_insert( "PatchDeform", FreeCaller<Patch_Deform>() );
|
||||
|
|
@ -928,7 +940,7 @@ void Patch_constructMenu( GtkMenu* menu ){
|
|||
if ( g_Layout_enableDetachableMenus.m_value ) {
|
||||
menu_tearoff( menu_in_menu );
|
||||
}
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Cycle Projection", "CycleCapTexturePatch" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Project", "PatchCapTexture" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Naturalize", "NaturalizePatch" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Invert X", "InvertCurveTextureX" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Invert Y", "InvertCurveTextureY" );
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ void Scene_PatchFindReplaceShader( scene::Graph& graph, const char* find, const
|
|||
void Scene_PatchFindReplaceShader_Selected( scene::Graph& graph, const char* find, const char* replace );
|
||||
|
||||
void Scene_PatchCapTexture_Selected( scene::Graph& graph );
|
||||
class texdef_t;
|
||||
template<typename Element> class BasicVector3;
|
||||
typedef BasicVector3<float> Vector3;
|
||||
void Scene_PatchProjectTexture_Selected( scene::Graph& graph, const texdef_t& texdef, const Vector3* direction );
|
||||
void Scene_PatchNaturalTexture_Selected( scene::Graph& graph );
|
||||
void Scene_PatchTileTexture_Selected( scene::Graph& graph, float s, float t );
|
||||
|
||||
|
|
|
|||
|
|
@ -891,6 +891,7 @@ void Select_Touching( void ){
|
|||
void Select_ProjectTexture( const texdef_t& texdef, const Vector3* direction ){
|
||||
if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
|
||||
Scene_BrushProjectTexture_Selected( GlobalSceneGraph(), texdef, direction );
|
||||
Scene_PatchProjectTexture_Selected( GlobalSceneGraph(), texdef, direction );
|
||||
}
|
||||
Scene_BrushProjectTexture_Component_Selected( GlobalSceneGraph(), texdef, direction );
|
||||
|
||||
|
|
|
|||
|
|
@ -4092,7 +4092,7 @@ const ModifierFlags c_modifier_toggle_face = c_modifier_toggle | c_modifier_face
|
|||
const ModifierFlags c_modifier_replace_face = c_modifier_replace | c_modifier_face;
|
||||
|
||||
const ButtonIdentifier c_button_texture = c_buttonMiddle;
|
||||
const ModifierFlags c_modifier_apply_texture1 = c_modifierControl | c_modifierShift;
|
||||
const ModifierFlags c_modifier_apply_texture1_project = c_modifierControl | c_modifierShift;
|
||||
const ModifierFlags c_modifier_apply_texture2_seamless = c_modifierControl;
|
||||
const ModifierFlags c_modifier_apply_texture3 = c_modifierShift;
|
||||
const ModifierFlags c_modifier_copy_texture = c_modifierNone;
|
||||
|
|
@ -4100,7 +4100,8 @@ const ModifierFlags c_modifier_copy_texture = c_modifierNone;
|
|||
|
||||
|
||||
void Scene_copyClosestTexture( SelectionTest& test );
|
||||
void Scene_applyClosestTexture( SelectionTest& test, bool seamless );
|
||||
void Scene_applyClosestTexture( SelectionTest& test, bool seamless, bool project );
|
||||
void Scene_projectClosestTexture( SelectionTest& test );
|
||||
|
||||
class TexManipulator_
|
||||
{
|
||||
|
|
@ -4118,10 +4119,10 @@ void mouseDown( DeviceVector position ){
|
|||
ConstructSelectionTest( scissored, SelectionBoxForPoint( &position[0], &m_epsilon[0] ) );
|
||||
SelectionVolume volume( scissored );
|
||||
|
||||
if ( m_state == c_modifier_apply_texture1 || m_state == c_modifier_apply_texture2_seamless || m_state == c_modifier_apply_texture3 ) {
|
||||
if ( m_state == c_modifier_apply_texture1_project || m_state == c_modifier_apply_texture2_seamless || m_state == c_modifier_apply_texture3 ) {
|
||||
m_undo_begun = true;
|
||||
GlobalUndoSystem().start();
|
||||
Scene_applyClosestTexture( volume, m_state == c_modifier_apply_texture2_seamless );
|
||||
Scene_applyClosestTexture( volume, m_state == c_modifier_apply_texture2_seamless, m_state == c_modifier_apply_texture1_project );
|
||||
}
|
||||
else if ( m_state == c_modifier_copy_texture ) {
|
||||
Scene_copyClosestTexture( volume );
|
||||
|
|
@ -4134,14 +4135,14 @@ void mouseMoved( DeviceVector position ){
|
|||
ConstructSelectionTest( scissored, SelectionBoxForPoint( &device_constrained( position )[0], &m_epsilon[0] ) );
|
||||
SelectionVolume volume( scissored );
|
||||
|
||||
Scene_applyClosestTexture( volume, m_state == c_modifier_apply_texture2_seamless );
|
||||
Scene_applyClosestTexture( volume, m_state == c_modifier_apply_texture2_seamless, m_state == c_modifier_apply_texture1_project );
|
||||
}
|
||||
}
|
||||
typedef MemberCaller1<TexManipulator_, DeviceVector, &TexManipulator_::mouseMoved> MouseMovedCaller;
|
||||
|
||||
void mouseUp( DeviceVector position ){
|
||||
if( m_undo_begun ){
|
||||
GlobalUndoSystem().finish( "paintTexture" );
|
||||
GlobalUndoSystem().finish( ( m_state == c_modifier_apply_texture1_project ) ? "projectTexture" : "paintTexture" );
|
||||
m_undo_begun = false;
|
||||
}
|
||||
g_mouseMovedCallback.clear();
|
||||
|
|
|
|||
|
|
@ -549,8 +549,8 @@ static void OnBtnReset( GtkWidget *widget, gpointer data ){
|
|||
|
||||
static void OnBtnProject( GtkWidget *widget, gpointer data ){
|
||||
if ( g_bp_globals.m_texdefTypeId != TEXDEFTYPEID_BRUSHPRIMITIVES ) {
|
||||
globalErrorStream() << "function is implemented for BRUSHPRIMITIVES map format only\n";
|
||||
return;
|
||||
globalErrorStream() << "function doesn't work for *brushes* in map formats other than BRUSHPRIMITIVES\n";
|
||||
//return;
|
||||
}
|
||||
getSurfaceInspector().exportData();
|
||||
SurfaceInspector_ProjectTexture();
|
||||
|
|
@ -1453,7 +1453,7 @@ void Face_getTexture( Face& face, CopiedString& shader, TextureProjection& proje
|
|||
typedef Function4<Face&, CopiedString&, TextureProjection&, ContentsFlagsValue&, void, Face_getTexture> FaceGetTexture;
|
||||
|
||||
|
||||
|
||||
/* copied from winding.cpp */
|
||||
inline bool float_is_largest_absolute( double axis, double other ){
|
||||
return fabs( axis ) > fabs( other );
|
||||
}
|
||||
|
|
@ -1502,7 +1502,8 @@ void Face_setTexture_Seamless( Face& face, const char* shader, const TextureProj
|
|||
face.SetShader( shader );
|
||||
|
||||
DoubleLine line = plane3_intersect_plane3( g_faceTextureClipboard.m_plane, face.getPlane().plane3() );
|
||||
Quaternion rotation = Quaternion( vector3_cross( g_faceTextureClipboard.m_plane.normal(), face.getPlane().plane3().normal() ), static_cast<float>( 1.0 + vector3_dot( g_faceTextureClipboard.m_plane.normal(), face.getPlane().plane3().normal() ) ) );
|
||||
Quaternion rotation = Quaternion( vector3_cross( g_faceTextureClipboard.m_plane.normal(), face.getPlane().plane3().normal() ),
|
||||
static_cast<float>( 1.0 + vector3_dot( g_faceTextureClipboard.m_plane.normal(), face.getPlane().plane3().normal() ) ) );
|
||||
//Quaternion rotation = quaternion_for_unit_vectors( g_faceTextureClipboard.m_plane.normal(), face.getPlane().plane3().normal() );
|
||||
//rotation.w() = sqrt( vector3_length_squared( g_faceTextureClipboard.m_plane.normal() ) * vector3_length_squared( face.getPlane().plane3().normal() ) ) + vector3_dot( g_faceTextureClipboard.m_plane.normal(), face.getPlane().plane3().normal() );
|
||||
//globalOutputStream() << "rotation: " << rotation.x() << " " << rotation.y() << " " << rotation.z() << " " << rotation.w() << " " << "\n";
|
||||
|
|
@ -1540,6 +1541,16 @@ void Face_setTexture_Seamless( Face& face, const char* shader, const TextureProj
|
|||
typedef Function4<Face&, const char*, const TextureProjection&, const ContentsFlagsValue&, void, Face_setTexture_Seamless> FaceSetTextureSeamless;
|
||||
|
||||
|
||||
void Face_setTexture_Project( Face& face, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags ){
|
||||
face.SetShader( shader );
|
||||
//face.SetTexdef( projection );
|
||||
face.SetFlags( flags );
|
||||
|
||||
face.ProjectTexture( g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_plane.normal() );
|
||||
}
|
||||
typedef Function4<Face&, const char*, const TextureProjection&, const ContentsFlagsValue&, void, Face_setTexture_Project> FaceSetTextureProject;
|
||||
|
||||
|
||||
void Face_setTexture( Face& face, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags ){
|
||||
face.SetShader( shader );
|
||||
face.SetTexdef( projection );
|
||||
|
|
@ -1555,6 +1566,12 @@ void Patch_getTexture( Patch& patch, CopiedString& shader, TextureProjection& pr
|
|||
}
|
||||
typedef Function4<Patch&, CopiedString&, TextureProjection&, ContentsFlagsValue&, void, Patch_getTexture> PatchGetTexture;
|
||||
|
||||
void Patch_setTexture_Project( Patch& patch, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags ){
|
||||
patch.SetShader( shader );
|
||||
patch.ProjectTexture( g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_plane.normal() );
|
||||
}
|
||||
typedef Function4<Patch&, const char*, const TextureProjection&, const ContentsFlagsValue&, void, Patch_setTexture_Project> PatchSetTextureProject;
|
||||
|
||||
void Patch_setTexture( Patch& patch, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags ){
|
||||
patch.SetShader( shader );
|
||||
}
|
||||
|
|
@ -1571,7 +1588,7 @@ struct Texturable
|
|||
};
|
||||
|
||||
|
||||
void Face_getClosest( Face& face, SelectionTest& test, SelectionIntersection& bestIntersection, Texturable& texturable, bool seamless ){
|
||||
void Face_getClosest( Face& face, SelectionTest& test, SelectionIntersection& bestIntersection, Texturable& texturable, bool seamless, bool project ){
|
||||
if ( face.isFiltered() ) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1580,7 +1597,9 @@ void Face_getClosest( Face& face, SelectionTest& test, SelectionIntersection& be
|
|||
if ( intersection.valid()
|
||||
&& SelectionIntersection_closer( intersection, bestIntersection ) ) {
|
||||
bestIntersection = intersection;
|
||||
if( seamless )
|
||||
if( project )
|
||||
texturable.setTexture = makeCallback3( FaceSetTextureProject(), face );
|
||||
else if( seamless )
|
||||
texturable.setTexture = makeCallback3( FaceSetTextureSeamless(), face );
|
||||
else
|
||||
texturable.setTexture = makeCallback3( FaceSetTexture(), face );
|
||||
|
|
@ -1614,9 +1633,10 @@ class BrushGetClosestFaceVisibleWalker : public scene::Graph::Walker
|
|||
SelectionTest& m_test;
|
||||
Texturable& m_texturable;
|
||||
bool m_seamless;
|
||||
bool m_project;
|
||||
mutable SelectionIntersection m_bestIntersection;
|
||||
public:
|
||||
BrushGetClosestFaceVisibleWalker( SelectionTest& test, Texturable& texturable, bool seamless ) : m_test( test ), m_texturable( texturable ), m_seamless( seamless ){
|
||||
BrushGetClosestFaceVisibleWalker( SelectionTest& test, Texturable& texturable, bool seamless, bool project ) : m_test( test ), m_texturable( texturable ), m_seamless( seamless ), m_project( project ){
|
||||
}
|
||||
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||
if ( path.top().get().visible() ) {
|
||||
|
|
@ -1626,7 +1646,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
|
||||
for ( Brush::const_iterator i = brush->getBrush().begin(); i != brush->getBrush().end(); ++i )
|
||||
{
|
||||
Face_getClosest( *( *i ), m_test, m_bestIntersection, m_texturable, m_seamless );
|
||||
Face_getClosest( *( *i ), m_test, m_bestIntersection, m_texturable, m_seamless, m_project );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1639,7 +1659,10 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
if ( occluded ) {
|
||||
Patch* patch = Node_getPatch( path.top() );
|
||||
if ( patch != 0 ) {
|
||||
m_texturable.setTexture = makeCallback3( PatchSetTexture(), *patch );
|
||||
if( m_project )
|
||||
m_texturable.setTexture = makeCallback3( PatchSetTextureProject(), *patch );
|
||||
else
|
||||
m_texturable.setTexture = makeCallback3( PatchSetTexture(), *patch );
|
||||
m_texturable.getTexture = makeCallback3( PatchGetTexture(), *patch );
|
||||
}
|
||||
else
|
||||
|
|
@ -1657,9 +1680,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
}
|
||||
};
|
||||
|
||||
Texturable Scene_getClosestTexturable( scene::Graph& graph, SelectionTest& test, bool seamless = false ){
|
||||
Texturable Scene_getClosestTexturable( scene::Graph& graph, SelectionTest& test, bool seamless = false, bool project = false ){
|
||||
Texturable texturable;
|
||||
graph.traverse( BrushGetClosestFaceVisibleWalker( test, texturable, seamless ) );
|
||||
graph.traverse( BrushGetClosestFaceVisibleWalker( test, texturable, seamless, project ) );
|
||||
return texturable;
|
||||
}
|
||||
|
||||
|
|
@ -1672,8 +1695,8 @@ bool Scene_getClosestTexture( scene::Graph& graph, SelectionTest& test, CopiedSt
|
|||
return false;
|
||||
}
|
||||
|
||||
void Scene_setClosestTexture( scene::Graph& graph, SelectionTest& test, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags, bool seamless ){
|
||||
Texturable texturable = Scene_getClosestTexturable( graph, test, seamless );
|
||||
void Scene_setClosestTexture( scene::Graph& graph, SelectionTest& test, const char* shader, const TextureProjection& projection, const ContentsFlagsValue& flags, bool seamless, bool project ){
|
||||
Texturable texturable = Scene_getClosestTexturable( graph, test, seamless, project );
|
||||
if ( texturable.setTexture != SetTextureCallback() ) {
|
||||
texturable.setTexture( shader, projection, flags );
|
||||
}
|
||||
|
|
@ -1694,10 +1717,10 @@ void Scene_copyClosestTexture( SelectionTest& test ){
|
|||
}
|
||||
}
|
||||
|
||||
void Scene_applyClosestTexture( SelectionTest& test, bool seamless ){
|
||||
void Scene_applyClosestTexture( SelectionTest& test, bool seamless, bool project ){
|
||||
// UndoableCommand command( "facePaintTexture" );
|
||||
|
||||
Scene_setClosestTexture( GlobalSceneGraph(), test, TextureBrowser_GetSelectedShader( g_TextureBrowser ), g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags, seamless );
|
||||
Scene_setClosestTexture( GlobalSceneGraph(), test, TextureBrowser_GetSelectedShader( g_TextureBrowser ), g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags, seamless, project );
|
||||
|
||||
SceneChangeNotify();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user