ArabDesert/Assets/harry_t/table_configurator.cs

487 lines
13 KiB
C#

#define HT8B_DRAW_REGIONS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[ExecuteInEditMode]
public class table_configurator : MonoBehaviour
{
[HideInInspector]
public ht8b_collision_data_t cdata;
float k_MINOR_REGION_CONST;
float r_k_CUSHION_RADIUS;
const float k_BALL_RADIUS = 0.03f;
Vector3 k_vA = new Vector3();
Vector3 k_vB = new Vector3();
Vector3 k_vC = new Vector3();
Vector3 k_vD = new Vector3();
Vector3 k_vX = new Vector3();
Vector3 k_vY = new Vector3();
Vector3 k_vZ = new Vector3();
Vector3 k_vW = new Vector3();
Vector3 k_pK = new Vector3();
Vector3 k_pL = new Vector3();
Vector3 k_pM = new Vector3();
Vector3 k_pN = new Vector3();
Vector3 k_pO = new Vector3();
Vector3 k_pP = new Vector3();
Vector3 k_pQ = new Vector3();
Vector3 k_pR = new Vector3();
Vector3 k_pT = new Vector3();
Vector3 k_pS = new Vector3();
Vector3 k_pU = new Vector3();
Vector3 k_pV = new Vector3();
Vector3 k_vA_vD = new Vector3();
Vector3 k_vA_vD_normal = new Vector3();
Vector3 k_vB_vY = new Vector3();
Vector3 k_vB_vY_normal = new Vector3();
Vector3 k_vC_vZ_normal = new Vector3();
Vector3 k_vA_vB_normal = new Vector3( 0.0f, 0.0f, -1.0f );
Vector3 k_vC_vW_normal = new Vector3( -1.0f, 0.0f, 0.0f );
//public Vector3 k_vE = new Vector3(1.087f,0.0f,0.627f);
//public Vector3 k_vF = new Vector3(0.0f,0.0f,0.665f);
// Stub
void _phy_bounce_cushion( int id, Vector3 N ) {}
string _encode_table_collider()
{
return "";
}
void _phy_table_init()
{
// Handy values
k_MINOR_REGION_CONST = cdata.k_TABLE_WIDTH - cdata.k_TABLE_HEIGHT;
// Major source vertices
k_vA.x = cdata.k_POCKET_RADIUS * 0.92f;
k_vA.z = cdata.k_TABLE_HEIGHT;
k_vB.x = cdata.k_TABLE_WIDTH-cdata.k_POCKET_RADIUS;
k_vB.z = cdata.k_TABLE_HEIGHT;
k_vC.x = cdata.k_TABLE_WIDTH;
k_vC.z = cdata.k_TABLE_HEIGHT-cdata.k_POCKET_RADIUS;
k_vD.x = k_vA.x - 0.016f;
k_vD.z = k_vA.z + 0.06f;
// Aux points
k_vX = k_vD + Vector3.forward;
k_vW = k_vC;
k_vW.z = 0.0f;
k_vY = k_vB;
k_vY.x += 1.0f;
k_vY.z += 1.0f;
k_vZ = k_vC;
k_vZ.x += 1.0f;
k_vZ.z += 1.0f;
// Normals
k_vA_vD = k_vD - k_vA;
k_vA_vD = k_vA_vD.normalized;
k_vA_vD_normal.x = -k_vA_vD.z;
k_vA_vD_normal.z = k_vA_vD.x;
k_vB_vY = k_vB - k_vY;
k_vB_vY = k_vB_vY.normalized;
k_vB_vY_normal.x = -k_vB_vY.z;
k_vB_vY_normal.z = k_vB_vY.x;
k_vC_vZ_normal = -k_vB_vY_normal;
// Minkowski difference
k_pN = k_vA;
k_pN.z -= r_k_CUSHION_RADIUS;
k_pM = k_vA + k_vA_vD_normal * r_k_CUSHION_RADIUS;
k_pL = k_vD + k_vA_vD_normal * r_k_CUSHION_RADIUS;
k_pK = k_vD;
k_pK.x -= r_k_CUSHION_RADIUS;
k_pO = k_vB;
k_pO.z -= r_k_CUSHION_RADIUS;
k_pP = k_vB + k_vB_vY_normal * r_k_CUSHION_RADIUS;
k_pQ = k_vC + k_vC_vZ_normal * r_k_CUSHION_RADIUS;
k_pR = k_vC;
k_pR.x -= r_k_CUSHION_RADIUS;
k_pT = k_vX;
k_pT.x -= r_k_CUSHION_RADIUS;
k_pS = k_vW;
k_pS.x -= r_k_CUSHION_RADIUS;
k_pU = k_vY + k_vB_vY_normal * r_k_CUSHION_RADIUS;
k_pV = k_vZ + k_vC_vZ_normal * r_k_CUSHION_RADIUS;
k_pS = k_vW;
k_pS.x -= r_k_CUSHION_RADIUS;
}
string _obj_vec_str( Vector3 v )
{
return $"v {v.x} {v.y} {v.z}\n";
}
void _phy_draw_circle( Vector3 at, float r, Color colour )
{
Vector3 last = at + Vector3.forward * r;
Vector3 cur = Vector3.zero;
for( int i = 1; i < 32; i ++ )
{
float angle = ((float)i/31.0f)*6.283185307179586f;
cur.x = at.x + Mathf.Sin( angle ) * r;
cur.z = at.z + Mathf.Cos( angle ) * r;
_drawline_multi( last, cur, colour );
last = cur;
}
}
void _drawline_applyparent( Vector3 from, Vector3 to, Color colour )
{
Debug.DrawLine( this.transform.parent.TransformPoint( from ), this.transform.parent.TransformPoint( to ), colour );
}
// Reflective, stacked by n
void _drawline_multi( Vector3 from, Vector3 to, Color colour )
{
Vector3 reflect_x = new Vector3( -1.0f, 1.0f, 1.0f );
Vector3 reflect_z = new Vector3( 1.0f, 1.0f, -1.0f );
Vector3 reflect_xz = Vector3.Scale( reflect_x, reflect_z );
for( int n = -4; n <= 4; n ++ )
{
Vector3 height = Vector3.up * (float)n * 0.006f;
_drawline_applyparent( from + height, to + height, colour );
_drawline_applyparent( Vector3.Scale( from, reflect_x ) + height, Vector3.Scale( to, reflect_x ) + height, colour );
_drawline_applyparent( Vector3.Scale( from, reflect_z ) + height, Vector3.Scale( to, reflect_z ) + height, colour );
_drawline_applyparent( Vector3.Scale( from, reflect_xz ) + height, Vector3.Scale( to, reflect_xz ) + height, colour );
}
}
Vector3 _sign_pos = new Vector3(0.0f,1.0f,0.0f);
void _phy_ball_table_new()
{
Vector3 A, N, a_to_v;
float dot;
A = this.transform.localPosition;
int id = 0;
_sign_pos.x = Mathf.Sign( A.x );
_sign_pos.z = Mathf.Sign( A.z );
A = Vector3.Scale( A, _sign_pos );
#if HT8B_DRAW_REGIONS
r_k_CUSHION_RADIUS = cdata.k_CUSHION_RADIUS-k_BALL_RADIUS;
_phy_table_init();
_drawline_multi( k_pT, k_pK, Color.yellow );
_drawline_multi( k_pK, k_pL, Color.yellow );
_drawline_multi( k_pL, k_pM, Color.yellow );
_drawline_multi( k_pM, k_pN, Color.yellow );
_drawline_multi( k_pN, k_pO, Color.yellow );
_drawline_multi( k_pO, k_pP, Color.yellow );
_drawline_multi( k_pP, k_pU, Color.yellow );
_drawline_multi( k_pV, k_pQ, Color.yellow );
_drawline_multi( k_pQ, k_pR, Color.yellow );
_drawline_multi( k_pR, k_pS, Color.yellow );
if( _phy_ball_pockets() )
{
_phy_draw_circle( cdata._cornerpocket, cdata.k_INNER_RADIUS, Color.green );
_phy_draw_circle( cdata._sidepocket, cdata.k_INNER_RADIUS, Color.green );
}
else
{
_phy_draw_circle( cdata._cornerpocket, cdata.k_INNER_RADIUS, Color.red );
_phy_draw_circle( cdata._sidepocket, cdata.k_INNER_RADIUS, Color.red );
}
r_k_CUSHION_RADIUS = cdata.k_CUSHION_RADIUS;
_phy_table_init();
#endif
if( A.x > k_vA.x ) // Major Regions
{
if( A.x > A.z + k_MINOR_REGION_CONST ) // Minor B
{
if( A.z < cdata.k_TABLE_HEIGHT-cdata.k_POCKET_RADIUS )
{
// Region H
#if HT8B_DRAW_REGIONS
_drawline_applyparent( new Vector3( 0.0f, 0.0f, 0.0f ), new Vector3( cdata.k_TABLE_WIDTH, 0.0f, 0.0f ), Color.red );
_drawline_applyparent( k_vC, k_vC + k_vC_vW_normal, Color.red );
#endif
if( A.x > cdata.k_TABLE_WIDTH - cdata.k_CUSHION_RADIUS )
{
// Static resolution
A.x = cdata.k_TABLE_WIDTH - cdata.k_CUSHION_RADIUS;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( k_vC_vW_normal, _sign_pos ) );
}
}
else
{
a_to_v = A - k_vC;
if( Vector3.Dot( a_to_v, k_vB_vY ) > 0.0f )
{
// Region I ( VORONI )
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vC, k_pR, Color.green );
_drawline_applyparent( k_vC, k_pQ, Color.green );
#endif
if( a_to_v.magnitude < cdata.k_CUSHION_RADIUS )
{
// Static resolution
N = a_to_v.normalized;
A = k_vC + N * cdata.k_CUSHION_RADIUS;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( N, _sign_pos ) );
}
}
else
{
// Region J
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vC, k_vB, Color.red );
_drawline_applyparent( k_pQ, k_pV, Color.blue );
#endif
a_to_v = A - k_pQ;
if( Vector3.Dot( k_vC_vZ_normal, a_to_v ) < 0.0f )
{
// Static resolution
dot = Vector3.Dot( a_to_v, k_vB_vY );
A = k_pQ + dot * k_vB_vY;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( k_vC_vZ_normal, _sign_pos ) );
}
}
}
}
else // Minor A
{
if( A.x < k_vB.x )
{
// Region A
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vA, k_vA + k_vA_vB_normal, Color.red );
_drawline_applyparent( k_vB, k_vB + k_vA_vB_normal, Color.red );
#endif
if( A.z > k_pN.z )
{
// Static resolution
A.z = k_pN.z;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( k_vA_vB_normal, _sign_pos ) );
}
}
else
{
a_to_v = A - k_vB;
if( Vector3.Dot( a_to_v, k_vB_vY ) > 0.0f )
{
// Region F ( VERONI )
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vB, k_pO, Color.green );
_drawline_applyparent( k_vB, k_pP, Color.green );
#endif
if( a_to_v.magnitude < cdata.k_CUSHION_RADIUS )
{
// Static resolution
N = a_to_v.normalized;
A = k_vB + N * cdata.k_CUSHION_RADIUS;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( N, _sign_pos ) );
}
}
else
{
// Region G
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vB, k_vC, Color.red );
_drawline_applyparent( k_pP, k_pU, Color.blue );
#endif
a_to_v = A - k_pP;
if( Vector3.Dot( k_vB_vY_normal, a_to_v ) < 0.0f )
{
// Static resolution
dot = Vector3.Dot( a_to_v, k_vB_vY );
A = k_pP + dot * k_vB_vY;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( k_vB_vY_normal, _sign_pos ) );
}
}
}
}
}
else
{
a_to_v = A - k_vA;
if( Vector3.Dot( a_to_v, k_vA_vD ) > 0.0f )
{
a_to_v = A - k_vD;
if( Vector3.Dot( a_to_v, k_vA_vD ) > 0.0f )
{
if( A.z > k_pK.z )
{
// Region E
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vD, k_vD + k_vC_vW_normal, Color.red );
#endif
if( A.x > k_pK.x )
{
// Static resolution
A.x = k_pK.x;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( k_vC_vW_normal, _sign_pos ) );
}
}
else
{
// Region D ( VORONI )
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vD, k_vD + k_vC_vW_normal, Color.green );
_drawline_applyparent( k_vD, k_vD + k_vA_vD_normal, Color.green );
#endif
if( a_to_v.magnitude < cdata.k_CUSHION_RADIUS )
{
// Static resolution
N = a_to_v.normalized;
A = k_vD + N * cdata.k_CUSHION_RADIUS;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( N, _sign_pos ) );
}
}
}
else
{
// Region C
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vA, k_vA + k_vA_vD_normal, Color.red );
_drawline_applyparent( k_vD, k_vD + k_vA_vD_normal, Color.red );
_drawline_applyparent( k_pL, k_pM, Color.blue );
#endif
a_to_v = A - k_pL;
if( Vector3.Dot( k_vA_vD_normal, a_to_v ) < 0.0f )
{
// Static resolution
dot = Vector3.Dot( a_to_v, k_vA_vD );
A = k_pL + dot * k_vA_vD;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( k_vA_vD_normal, _sign_pos ) );
}
}
}
else
{
// Region B ( VORONI )
#if HT8B_DRAW_REGIONS
_drawline_applyparent( k_vA, k_vA + k_vA_vB_normal, Color.green );
_drawline_applyparent( k_vA, k_vA + k_vA_vD_normal, Color.green );
#endif
if( a_to_v.magnitude < cdata.k_CUSHION_RADIUS )
{
// Static resolution
N = a_to_v.normalized;
A = k_vA + N * cdata.k_CUSHION_RADIUS;
// Dynamic
_phy_bounce_cushion( id, Vector3.Scale( N, _sign_pos ) );
}
}
}
A = Vector3.Scale( A, _sign_pos );
this.transform.localPosition = A;
}
bool _phy_ball_pockets()
{
Vector3 A;
A = this.transform.localPosition;
_sign_pos.x = Mathf.Sign( A.x );
_sign_pos.z = Mathf.Sign( A.z );
A = Vector3.Scale( A, _sign_pos );
if( Vector3.Distance( A, cdata._cornerpocket ) < cdata.k_INNER_RADIUS )
{
return true;
}
if( Vector3.Distance( A, cdata._sidepocket ) < cdata.k_INNER_RADIUS )
{
return true;
}
if( A.z > cdata._sidepocket.z )
{
return true;
}
if( A.z > -A.x + cdata._cornerpocket.x + cdata._cornerpocket.z )
{
return true;
}
return false;
}
// Update is called once per frame
void Update()
{
_phy_ball_table_new();
}
void Start()
{
}
}