ArabDesert/Assets/harry_t/ht8b_editor/ht8b_config.cs

316 lines
11 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;
using UnityEditor;
#if UNITY_EDITOR
using UnityEditor.SceneManagement;
#endif
[CreateAssetMenu(fileName = "config", menuName = "ht8b/config", order = 1)]
[System.Serializable]
public class ht8b_config : ScriptableObject
{
public Color _colourDefault;
public Color _colourFoul;
public Color _8ball_fabric_colour;
public Color _8ball_team_colour_0;
public Color _8ball_team_colour_1;
public Color _9ball_fabric_colour;
public Color[] _9ball_colours = new Color[9];
public Color _4ball_fabric_colour;
public Color _4ball_team_colour_0;
public Color _4ball_team_colour_1;
public Color _4ball_objective_colour;
public Texture2D _src_ball_content;
public Texture2D _src_ball_spinmarkers;
public Material _table_surface_mat; // Interactive surface material
public Material _ball_mat;
public GameObject _table_setup_prefab; // 'Visual prefab' setup
public GameObject _collision_data_prefab;
public float _edge_gap;
public ht8b_collision_data_t cdata;
public quest_stuff_data quest_switch_data;
#if UNITY_EDITOR
private static void Image_ApplyTones_Mul( ref Color[] source, ref Color[] dest, Color R, Color G, Color B )
{
for( int i = 0; i < source.Length; i ++ )
{
Color pSrc = source[i];
ref Color pOut = ref dest[i];
pOut = Color.white;
pOut = pOut * ( 1F-pSrc.r ) + R * pSrc.r;
pOut = pOut * ( 1F-pSrc.g ) + G * pSrc.g;
pOut = pOut * ( 1F-pSrc.b ) + B * pSrc.b;
pOut.a = 1F;
}
}
private static void Image_BlendAlphaOver( ref Color[] dst, ref Color[] src )
{
for( int i = 0; i < dst.Length; i ++ )
{
// ADD // ONE_MINUS_SRC_ALPHA // SRC_ALPHA
dst[i] = (src[i]*src[i].a) + (dst[i]*(1F-src[i].a));
}
}
private static void Image_ColourSqr( ref Color[] dst, int imgw, int imgh, int x, int y, int w, int h, Color src )
{
Color withoutAlpha = src;
withoutAlpha.a = 1.0f;
for( int _y = y; _y < y + h; _y ++ )
{
for( int _x = x; _x < x + w; _x ++ )
{
ref Color pDst = ref dst[ _y * imgw + _x ];
float alpha = Mathf.Clamp01( pDst.r + pDst.g + pDst.b );
pDst = Color.white * ( 1F-alpha ) + src * alpha;
pDst.a = 1F;
}
}
}
private static void Image_FillSqr( ref Color[] dst, int imgw, int imgh, int x, int y, int w, int h, Color src )
{
for( int _y = y; _y < y + h; _y ++ )
{
for( int _x = x; _x < x + w; _x ++ )
{
dst[ _y * imgw + _x ] = src;
}
}
}
// RGB invert
private static void Image_Invert( ref Color[] dst )
{
for( int i = 0; i < dst.Length; i ++ )
{
ref Color c = ref dst[i];
c.r = 1F - c.r;
c.g = 1F - c.g;
c.b = 1F - c.b;
}
}
private static void WriteTex2dAsset( ref Color[] src, int x, int y, string path )
{
Texture2D writetex = new Texture2D( x,y, TextureFormat.RGBA32, false );
writetex.SetPixels( src, 0 );
string output_path = $"{Application.dataPath}/harry_t/ht8b_materials/procedural/{path}.png";
File.WriteAllBytes( output_path, writetex.EncodeToPNG() );
}
public void RenderProcedural_8ball()
{
Color[] _spinmarker = this._src_ball_spinmarkers.GetPixels();
Color[] _8ball_texture = this._src_ball_content.GetPixels();
Image_ApplyTones_Mul( ref _8ball_texture, ref _8ball_texture, this._8ball_team_colour_0, this._8ball_team_colour_1, Color.black );
Image_BlendAlphaOver( ref _8ball_texture, ref _spinmarker );
WriteTex2dAsset( ref _8ball_texture, this._src_ball_content.width, this._src_ball_content.height, "tballs_8ball" );
}
public void RenderProcedural_9ball_4ball()
{
Color[] _spinmarker = this._src_ball_spinmarkers.GetPixels();
Color[] _9ball_texture = this._src_ball_content.GetPixels();
int box_width = this._src_ball_content.width >> 2;
int box_height = this._src_ball_content.height >> 2;
int cx = 1;
int cy = 3;
for( int i = 0; i < 9; i ++ )
{
Image_ColourSqr( ref _9ball_texture,
this._src_ball_content.width, this._src_ball_content.height,
box_width*(cx ++), box_height*(cy),
box_width, box_height,
this._9ball_colours[ i ]
);
if( cx >= 4 )
{
cx = 0;
cy --;
}
}
// 4 ball section
Image_FillSqr( ref _9ball_texture,
this._src_ball_content.width, this._src_ball_content.height,
box_width*0,0,
box_width,box_height,
this._4ball_team_colour_0
);
Image_FillSqr( ref _9ball_texture,
this._src_ball_content.width, this._src_ball_content.height,
box_width*1,0,
box_width,box_height,
this._4ball_team_colour_1
);
Image_FillSqr( ref _9ball_texture,
this._src_ball_content.width, this._src_ball_content.height,
box_width*2,0,
box_width*2,box_height,
this._4ball_objective_colour
);
Image_BlendAlphaOver( ref _9ball_texture, ref _spinmarker );
WriteTex2dAsset( ref _9ball_texture, this._src_ball_content.width, this._src_ball_content.height, "tballs_9ball" );
}
public void RenderProceduralTextures()
{
if( !this._src_ball_content || !this._src_ball_spinmarkers )
{
Debug.LogError( "Missing some source content supplied for texture bake!!" );
return;
}
RenderProcedural_8ball();
RenderProcedural_9ball_4ball();
AssetDatabase.Refresh();
}
private static void store_transform( Transform src, Transform dest )
{
dest.position = src.position;
dest.rotation = src.rotation;
}
public void ApplyConfig( Transform root )
{
Transform table_folder = root.Find( "intl.table" );
{
List<GameObject> destroy_list = new List<GameObject>();
foreach( Transform t in table_folder )
{
destroy_list.Add( t.gameObject );
}
for( int i = 0; i < destroy_list.Count; i ++ )
{
DestroyImmediate( destroy_list[i] );
}
}
GameObject table_instance = (GameObject)PrefabUtility.InstantiatePrefab( this._table_setup_prefab, table_folder );
table_instance.name = "table_artwork";
// Apply transforms to other components
Transform menu_transform = root.Find( "intl.ui_menu" );
store_transform( table_instance.transform.Find( ".MENU" ), menu_transform );
menu_transform.transform.position += menu_transform.right * 0.4f;
store_transform( table_instance.transform.Find( ".CUE_0" ), root.Find( "intl.cue-0" ) );
store_transform( table_instance.transform.Find( ".CUE_1" ), root.Find( "intl.cue-1" ) );
// Table surface
Transform gamespace = root.Find( "intl.balls" );
gamespace.localPosition = table_instance.transform.Find( ".TABLE_SURFACE" ).localPosition + Vector3.up * 0.03f;
gamespace.GetChild(0).GetComponent<MeshRenderer>().sharedMaterials[1].SetFloat( "_Floor", gamespace.position.y );
// Player names
Transform score_info_root = root.transform.Find( "intl.scorecardinfo" );
score_info_root.Find( "player0-name" ).gameObject.GetComponent<RectTransform>().localPosition = table_instance.transform.Find( ".NAME_0" ).localPosition;
score_info_root.Find( "player1-name" ).gameObject.GetComponent<RectTransform>().localPosition = table_instance.transform.Find( ".NAME_1" ).localPosition;
int ht8b_layerid = LayerMask.NameToLayer( "ht8b" );
// Override layers for desktop rendering
table_instance.layer = ht8b_layerid;
foreach( Transform t in table_instance.transform )
{
t.gameObject.layer = ht8b_layerid;
}
GameObject collision_instance = (GameObject)PrefabUtility.InstantiatePrefab( this._collision_data_prefab, table_instance.transform );
collision_instance.name = "collision.vfx";
collision_instance.SetActive( false );
// Apply script values
ht8b ht8b_script = root.gameObject.GetComponent<ht8b>();
VRC.Udon.UdonBehaviour behaviour = UdonSharpEditor.UdonSharpEditorUtility.GetBackingUdonBehaviour( ht8b_script );
// Collision data
behaviour.publicVariables.TrySetVariableValue( "k_TABLE_WIDTH", this.cdata.k_TABLE_WIDTH );
behaviour.publicVariables.TrySetVariableValue( "k_TABLE_HEIGHT", this.cdata.k_TABLE_HEIGHT );
behaviour.publicVariables.TrySetVariableValue( "k_POCKET_RADIUS", this.cdata.k_POCKET_RADIUS );
behaviour.publicVariables.TrySetVariableValue( "k_CUSHION_RADIUS", this.cdata.k_CUSHION_RADIUS );
behaviour.publicVariables.TrySetVariableValue( "k_INNER_RADIUS", this.cdata.k_INNER_RADIUS );
// Pockets
behaviour.publicVariables.TrySetVariableValue( "k_vE", this.cdata._cornerpocket );
behaviour.publicVariables.TrySetVariableValue( "k_vF", this.cdata._sidepocket );
// Global colours
behaviour.publicVariables.TrySetVariableValue( "k_colour_foul", this._colourFoul * 1.5f );
behaviour.publicVariables.TrySetVariableValue( "k_colour_default", this._colourDefault * 1.5f );
behaviour.publicVariables.TrySetVariableValue( "k_teamColour_spots", this._8ball_team_colour_0 * 1.5f );
behaviour.publicVariables.TrySetVariableValue( "k_teamColour_stripes", this._8ball_team_colour_1 * 1.5f );
behaviour.publicVariables.TrySetVariableValue( "k_colour4Ball_team_0", this._4ball_team_colour_0 * 1.5f );
behaviour.publicVariables.TrySetVariableValue( "k_colour4Ball_team_1", this._4ball_team_colour_1 * 1.5f );
behaviour.publicVariables.TrySetVariableValue( "k_fabricColour_8ball", this._8ball_fabric_colour );
behaviour.publicVariables.TrySetVariableValue( "k_fabricColour_9ball", this._9ball_fabric_colour );
behaviour.publicVariables.TrySetVariableValue( "k_fabricColour_4ball", this._4ball_fabric_colour );
// Materials
behaviour.publicVariables.TrySetVariableValue( "tableMaterial", this._table_surface_mat );
behaviour.publicVariables.TrySetVariableValue( "ballMaterial", this._ball_mat );
// Textures
behaviour.publicVariables.TrySetVariableValue( "textureSets", new Texture[]
{
(Texture)AssetDatabase.LoadAssetAtPath( "Assets/harry_t/ht8b_materials/procedural/tballs_8ball.png", typeof(Texture) ),
(Texture)AssetDatabase.LoadAssetAtPath( "Assets/harry_t/ht8b_materials/procedural/tballs_9ball.png", typeof(Texture) )
}
);
Undo.RecordObject( behaviour, "[ht8b] Modify Public Variables" );
EditorSceneManager.MarkSceneDirty( behaviour.gameObject.scene );
PrefabUtility.RecordPrefabInstancePropertyModifications( behaviour );
}
#endif
}