Skip to content

Commit

Permalink
Merge pull request #52 from Algoryx/fix-import-agx-file
Browse files Browse the repository at this point in the history
Fixed import of agx files.
  • Loading branch information
nmalg committed Jun 23, 2020
2 parents 8b748c5 + 783544b commit a51a606
Show file tree
Hide file tree
Showing 24 changed files with 1,047 additions and 438 deletions.
6 changes: 6 additions & 0 deletions AGXUnity/FrictionModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ public FrictionModel RestoreLocalDataFrom( agx.FrictionModel native )
SolveType = Convert( native.getSolveType() );
Type = FindType( native );

// TODO: How do we handle oriented when restoring from file?
if ( Type == EType.ConstantNormalForceBoxFriction ) {
NormalForceMagnitude = System.Convert.ToSingle( native.asConstantNormalForceOrientedBoxFrictionModel().getNormalForceMagnitude() );
ScaleNormalForceWithDepth = native.asConstantNormalForceOrientedBoxFrictionModel().getEnableScaleWithDepth();
}

return this;
}

Expand Down
84 changes: 84 additions & 0 deletions AGXUnity/IO/RestoredAssetsRoot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.Collections.Generic;
using UnityEngine;

namespace AGXUnity.IO
{
public class RestoredAssetsRoot : ScriptableObject
{
public enum ContainingType
{
ShapeMaterial,
ContactMaterial,
FrictionModel,
CableProperties,
RenderMaterial,
Mesh,
Unknown // This is last - add entries before this.
}

public static RestoredAssetsRoot Create( string prefixName, ContainingType type )
{
var instance = ScriptableObject.CreateInstance<RestoredAssetsRoot>();
instance.Type = type;
instance.name = FindName( prefixName, type );

return instance;
}

public static string FindName( string prefixName, ContainingType type )
{
return $"{prefixName}_{type}";
}

public static ContainingType FindAssetType( System.Type type )
{
var index = System.Array.IndexOf( s_fileAssetTypeToTypeMap, type );
return index < 0 ? ContainingType.Unknown : (ContainingType)index;
}

public static ContainingType FindAssetType<T>()
{
return FindAssetType( typeof( T ) );
}

public static int FindAssetTypeIndex<T>()
{
return (int)FindAssetType<T>();
}

public static IEnumerable<ContainingType> Types
{
get
{
foreach ( ContainingType type in System.Enum.GetValues( typeof( ContainingType ) ) )
yield return type;
}
}

public static System.Type GetType( ContainingType type )
{
return s_fileAssetTypeToTypeMap[ (int)type ];
}

[SerializeField]
private ContainingType m_type = ContainingType.Unknown;

[HideInInspector]
public ContainingType Type
{
get { return m_type; }
private set { m_type = value; }
}

private static System.Type[] s_fileAssetTypeToTypeMap = new System.Type[]
{
typeof( ShapeMaterial ),
typeof( ContactMaterial ),
typeof( FrictionModel ),
typeof( CableProperties ),
typeof( Material ),
typeof( Mesh ),
null // Unknown assets, the only one valid to be null.
};
}
}
11 changes: 11 additions & 0 deletions AGXUnity/IO/RestoredAssetsRoot.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion AGXUnity/Rendering/DebugRenderManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ private void SynchronizeShape( Collide.Shape shape )

private void SynchronizeScaleIfNodeExist( Collide.Shape shape )
{
var data = shape.gameObject.GetComponent<ShapeDebugRenderData>();
var data = shape.GetComponent<ShapeDebugRenderData>();
if ( data != null )
data.SynchronizeScale( shape );
}
Expand Down
21 changes: 16 additions & 5 deletions AGXUnity/Utils/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ private static void Traverse( Transform transform, Action<GameObject> visitor )
/// </summary>
/// <typeparam name="T">Component type.</typeparam>
/// <returns>Initialized component of type T. Null if not present or not possible to initialize.</returns>
public static T GetInitializedComponent<T>( this GameObject gameObject ) where T : ScriptComponent
public static T GetInitializedComponent<T>( this GameObject gameObject )
where T : ScriptComponent
{
T component = gameObject.GetComponent<T>();
if ( component == null )
Expand All @@ -107,7 +108,8 @@ public static T GetInitializedComponent<T>( this GameObject gameObject ) where T
/// Initialized components of type T. Empty set of none present and throws an exception
/// if one component fails to initialize.
/// </returns>
public static T[] GetInitializedComponents<T>( this GameObject gameObject ) where T : ScriptComponent
public static T[] GetInitializedComponents<T>( this GameObject gameObject )
where T : ScriptComponent
{
T[] components = gameObject.GetComponents<T>();
foreach ( T component in components )
Expand All @@ -122,7 +124,8 @@ public static T[] GetInitializedComponents<T>( this GameObject gameObject ) wher
/// <typeparam name="T">Component type.</typeparam>
/// <param name="includeInactive">True to include inactive components, default false.</param>
/// <returns>Initialized child component of type T. Null if not present or not possible to initialize.</returns>
public static T GetInitializedComponentInChildren<T>( this GameObject gameObject, bool includeInactive = false ) where T : ScriptComponent
public static T GetInitializedComponentInChildren<T>( this GameObject gameObject, bool includeInactive = false )
where T : ScriptComponent
{
T component = gameObject.GetComponentInChildren<T>( includeInactive );
if ( component == null )
Expand All @@ -135,7 +138,8 @@ public static T GetInitializedComponentInChildren<T>( this GameObject gameObject
/// </summary>
/// <typeparam name="T">Component type.</typeparam>
/// <returns>Initialized parent component of type T. Null if not present or not possible to initialize.</returns>
public static T GetInitializedComponentInParent<T>( this GameObject gameObject ) where T : ScriptComponent
public static T GetInitializedComponentInParent<T>( this GameObject gameObject )
where T : ScriptComponent
{
T component = gameObject.GetComponentInParent<T>();
if ( component == null )
Expand All @@ -162,7 +166,9 @@ public static bool HasChild( this GameObject parent, GameObject child )
/// Fetch component if already present or creates new.
/// </summary>
/// <typeparam name="T">Component type.</typeparam>
public static T GetOrCreateComponent<T>( this GameObject gameObject ) where T : Component
/// <returns>Already existing or new component.</returns>
public static T GetOrCreateComponent<T>( this GameObject gameObject )
where T : Component
{
return gameObject.GetComponent<T>() ?? gameObject.AddComponent<T>();
}
Expand Down Expand Up @@ -453,6 +459,11 @@ public static string ToHexStringRGB( this Color color )
/// </summary>
public static partial class Extensions
{
public static string Color( this string str, Color color )
{
return GUI.AddColorTag( str, color );
}

public static System.UInt32 To32BitFnv1aHash( this string str )
{
IEnumerable<byte> bytes = str.ToCharArray().Select( Convert.ToByte );
Expand Down
7 changes: 7 additions & 0 deletions AGXUnity/Utils/Math.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ public static bool Approximately( float a, float b, float epsilon = 0.000001f )
return System.Math.Abs( a - b ) <= epsilon;
}

public static bool Approximately( Vector3 v1, Vector3 v2, float epsilon = 0.000001f )
{
return System.Math.Abs( v1.x - v2.x ) <= epsilon &&
System.Math.Abs( v1.y - v2.y ) <= epsilon &&
System.Math.Abs( v1.z - v2.z ) <= epsilon;
}

public static Vector3 Clamp( Vector3 v, float minValue )
{
return new Vector3( Mathf.Max( v.x, minValue ), Mathf.Max( v.y, minValue ), Mathf.Max( v.z, minValue ) );
Expand Down
98 changes: 89 additions & 9 deletions AGXUnity/Utils/MeshSplitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@ public class SubMeshData
{
private Dictionary<Vector3, int> m_vertexToIndexTable = new Dictionary<Vector3, int>();
private List<Vector3> m_vertices = new List<Vector3>();
private List<Vector2> m_uvs = null;
private List<int> m_indices = new List<int>();
private Mesh m_mesh = null;

public int NumVertices { get { return m_vertices.Count; } }
public int NumIndices { get { return m_indices.Count; } }
public Mesh Mesh { get { return m_mesh; } }

public SubMeshData( int capacity = Int16.MaxValue )
public SubMeshData( bool hasUvs, int capacity = Int16.MaxValue )
{
m_vertices.Capacity = capacity;
m_indices.Capacity = capacity;
if ( hasUvs )
m_uvs = new List<Vector2>( capacity );
}

public void Add( Vector3 v1, Vector3 v2, Vector3 v3 )
Expand All @@ -31,6 +34,35 @@ public void Add( Vector3 v1, Vector3 v2, Vector3 v3 )
Add( v3 );
}

public void Add( Vector3 v1,
Vector3 v2,
Vector3 v3,
Vector2 uv1,
Vector2 uv2,
Vector2 uv3 )
{
Add( v1, uv1 );
Add( v2, uv2 );
Add( v3, uv3 );
}

public void CreateMesh( agx.Vec3Vector vertices,
agx.UInt32Vector indices,
agx.Vec2Vector uvs,
Func<agx.Vec3, Vector3> vertexTransformer )
{
m_vertices.AddRange( from v in vertices select vertexTransformer( v ) );
if ( uvs != null )
m_uvs.AddRange( from uv in uvs select uv.ToVector2() );
for ( int i = 0; i < indices.Count; i += 3 ) {
m_indices.Add( Convert.ToInt32( indices[ i + 0 ] ) );
m_indices.Add( Convert.ToInt32( indices[ i + 2 ] ) );
m_indices.Add( Convert.ToInt32( indices[ i + 1 ] ) );
}

CreateMesh();
}

public void CreateMesh()
{
if ( m_mesh != null )
Expand All @@ -40,12 +72,15 @@ public void CreateMesh()
m_mesh.SetVertices( m_vertices );
m_mesh.SetTriangles( m_indices, 0, false );

if ( m_uvs != null )
m_mesh.SetUVs( 0, m_uvs );

m_mesh.RecalculateBounds();
m_mesh.RecalculateNormals();
m_mesh.RecalculateTangents();
}

private void Add( Vector3 v )
private int Add( Vector3 v )
{
int index;
if ( !m_vertexToIndexTable.TryGetValue( v, out index ) ) {
Expand All @@ -55,23 +90,68 @@ private void Add( Vector3 v )
}

m_indices.Add( index );

return index;
}

private void Add( Vector3 v, Vector2 uv )
{
var index = Add( v );
if ( index >= m_uvs.Count ) {
Debug.Assert( index == m_uvs.Count,
$"Vertex index = {index}, UV count = {m_uvs.Count}" );
m_uvs.Add( uv );
}
}
}

public static MeshSplitter Split( agx.Vec3Vector vertices,
agx.UInt32Vector indices,
Func<agx.Vec3, Vector3> transformer,
int maxNumVertices = Int16.MaxValue )
{
return Split( vertices, indices, null, transformer, maxNumVertices );
}

public static MeshSplitter Split( agx.Vec3Vector vertices, agx.UInt32Vector indices, Func<agx.Vec3, Vector3> transformer, int maxNumVertices = Int16.MaxValue )
public static MeshSplitter Split( agx.Vec3Vector vertices,
agx.UInt32Vector indices,
agx.Vec2Vector uvs,
Func<agx.Vec3, Vector3> vertexTransformer,
int maxNumVertices = Int16.MaxValue )
{
var splitter = new MeshSplitter();

if ( vertices.Count < maxNumVertices ) {
splitter.m_subMeshData.Add( new SubMeshData( uvs != null, vertices.Count ) );
splitter.m_subMeshData.Last().CreateMesh( vertices, indices, uvs, vertexTransformer );
return splitter;
}

// This works but isn't correct. It's not possible to recover
// the triangles list for a mesh with #vertices < MaxValue.
splitter.m_vertices = new List<Vector3>( vertices.Count );
for ( int i = 0; i < vertices.Count; ++i )
splitter.m_vertices.Add( transformer( vertices[ i ] ) );
splitter.m_vertices.Add( vertexTransformer( vertices[ i ] ) );

var hasUvs = uvs != null && uvs.Count == vertices.Count;
for ( int i = 0; i < indices.Count; i += 3 ) {
if ( i == 0 || splitter.m_subMeshData.Last().NumVertices >= maxNumVertices )
splitter.m_subMeshData.Add( new SubMeshData( maxNumVertices ) );

splitter.m_subMeshData.Last().Add( splitter.m_vertices[ Convert.ToInt32( indices[ i + 0 ] ) ],
splitter.m_vertices[ Convert.ToInt32( indices[ i + 2 ] ) ],
splitter.m_vertices[ Convert.ToInt32( indices[ i + 1 ] ) ] );
splitter.m_subMeshData.Add( new SubMeshData( hasUvs,
maxNumVertices ) );

if ( hasUvs ) {
splitter.m_subMeshData.Last().Add( splitter.m_vertices[ Convert.ToInt32( indices[ i + 0 ] ) ],
splitter.m_vertices[ Convert.ToInt32( indices[ i + 2 ] ) ],
splitter.m_vertices[ Convert.ToInt32( indices[ i + 1 ] ) ],
uvs[ Convert.ToInt32( indices[ i + 0 ] ) ].ToVector2(),
uvs[ Convert.ToInt32( indices[ i + 2 ] ) ].ToVector2(),
uvs[ Convert.ToInt32( indices[ i + 1 ] ) ].ToVector2() );
}
else {
splitter.m_subMeshData.Last().Add( splitter.m_vertices[ Convert.ToInt32( indices[ i + 0 ] ) ],
splitter.m_vertices[ Convert.ToInt32( indices[ i + 2 ] ) ],
splitter.m_vertices[ Convert.ToInt32( indices[ i + 1 ] ) ] );
}
}

foreach ( var data in splitter.m_subMeshData )
Expand Down
Loading

0 comments on commit a51a606

Please sign in to comment.