Skip to content
Permalink
Browse files

Static mesh base

  • Loading branch information
Eideren committed Dec 18, 2018
1 parent 0964856 commit cbcc27dc7848bdd212a1c31e2f679abf88824c69
@@ -544,7 +544,7 @@ private void BuildInput(StaticColliderData[] collidersLocal, CollisionFilterGrou

// Convert hull indices to int
int[] indices = new int[hull.Indices.Count];
if (hull.Indices.Count % 3 != 0) throw new InvalidOperationException("Physics hull does not consist of triangles");
if (hull.Indices.Count % 3 != 0) throw new InvalidOperationException($"{shapeType} does not consist of triangles");
for (int i = 0; i < hull.Indices.Count; i += 3)
{
indices[i] = (int)hull.Indices[i];
@@ -554,6 +554,23 @@ private void BuildInput(StaticColliderData[] collidersLocal, CollisionFilterGrou

entityNavigationMeshInputBuilder.AppendArrays(hull.Points.ToArray(), indices, transform);
}
else if (shapeType == typeof(StaticMeshColliderShape))
{
var mesh = (StaticMeshColliderShape)shape;
Matrix transform = mesh.PositiveCenterMatrix * entityWorldMatrix;

// Convert hull indices to int
int[] indices = new int[mesh.Indices.Count];
if (mesh.Indices.Count % 3 != 0) throw new InvalidOperationException($"{shapeType} does not consist of triangles");
for (int i = 0; i < mesh.Indices.Count; i += 3)
{
indices[i] = (int)mesh.Indices[i];
indices[i + 2] = (int)mesh.Indices[i + 1]; // NOTE: Reversed winding to create left handed input
indices[i + 1] = (int)mesh.Indices[i + 2];
}

entityNavigationMeshInputBuilder.AppendArrays(mesh.Points.ToArray(), indices, transform);
}
else if (shapeType == typeof(CompoundColliderShape))
{
// Unroll compound collider shapes
@@ -31,6 +31,8 @@ public enum ColliderShapeTypes

StaticPlane,

StaticMesh,

Cone,
}
}
@@ -41,5 +41,10 @@ public bool Match(object obj)
var other = obj as BoxColliderShapeDesc;
return other?.Is2D == Is2D && other.Size == Size && other.LocalOffset == LocalOffset && other.LocalRotation == LocalRotation;
}

public ColliderShape NewShapeFromDesc()
{
return new BoxColliderShape(Is2D, Size) { LocalOffset = LocalOffset, LocalRotation = LocalRotation };
}
}
}
@@ -64,5 +64,10 @@ public bool Match(object obj)
other.LocalOffset == LocalOffset &&
other.LocalRotation == LocalRotation;
}

public ColliderShape NewShapeFromDesc()
{
return new CapsuleColliderShape(Is2D, Radius, Length, Orientation) { LocalOffset = LocalOffset, LocalRotation = LocalRotation };
}
}
}
@@ -39,5 +39,20 @@ public bool Match(object obj)
// TODO: shouldn't we return true here?
return other.Shape == Shape;
}

public ColliderShape NewShapeFromDesc()
{
if (Shape == null)
{
return null;
}

if (Shape.Shape == null)
{
Shape.Shape = PhysicsColliderShape.Compose(Shape.Descriptions);
}

return this.Shape.Shape;
}
}
}
@@ -58,5 +58,10 @@ public bool Match(object obj)
other.LocalOffset == LocalOffset &&
other.LocalRotation == LocalRotation;
}

public ColliderShape NewShapeFromDesc()
{
return new ConeColliderShape(Height, Radius, Orientation) { LocalOffset = LocalOffset, LocalRotation = LocalRotation };
}
}
}
@@ -129,5 +129,100 @@ public bool Match(object obj)
Math.Abs(other.Alpha - Alpha) < float.Epsilon &&
Math.Abs(other.Threshold - Threshold) < float.Epsilon;
}

public ColliderShape NewShapeFromDesc()
{
if (ConvexHulls == null) return null;
ColliderShape shape;

//Optimize performance and focus on less shapes creation since this shape could be nested

if (ConvexHulls.Count == 1)
{
if (ConvexHulls[0].Count == 1 && ConvexHullsIndices[0][0].Count > 0)
{
shape = new ConvexHullColliderShape(ConvexHulls[0][0], ConvexHullsIndices[0][0], Scaling)
{
NeedsCustomCollisionCallback = true,
};

//shape.UpdateLocalTransformations();
shape.Description = this;

return shape;
}

if (ConvexHulls[0].Count <= 1) return null;

var subCompound = new CompoundColliderShape
{
NeedsCustomCollisionCallback = true,
};

for (var i = 0; i < ConvexHulls[0].Count; i++)
{
var verts = ConvexHulls[0][i];
var indices = ConvexHullsIndices[0][i];

if (indices.Count == 0) continue;

var subHull = new ConvexHullColliderShape(verts, indices, Scaling);
//subHull.UpdateLocalTransformations();
subCompound.AddChildShape(subHull);
}

//subCompound.UpdateLocalTransformations();
subCompound.Description = this;

return subCompound;
}

if (ConvexHulls.Count <= 1) return null;

var compound = new CompoundColliderShape
{
NeedsCustomCollisionCallback = true,
};

for (var i = 0; i < ConvexHulls.Count; i++)
{
var verts = ConvexHulls[i];
var indices = ConvexHullsIndices[i];

if (verts.Count == 1)
{
if (indices[0].Count == 0) continue;

var subHull = new ConvexHullColliderShape(verts[0], indices[0], Scaling);
//subHull.UpdateLocalTransformations();
compound.AddChildShape(subHull);
}
else if (verts.Count > 1)
{
var subCompound = new CompoundColliderShape();

for (var b = 0; b < verts.Count; b++)
{
var subVerts = verts[b];
var subIndex = indices[b];

if (subIndex.Count == 0) continue;

var subHull = new ConvexHullColliderShape(subVerts, subIndex, Scaling);
//subHull.UpdateLocalTransformations();
subCompound.AddChildShape(subHull);
}

//subCompound.UpdateLocalTransformations();

compound.AddChildShape(subCompound);
}
}

//compound.UpdateLocalTransformations();
compound.Description = this;

return compound;
}
}
}
@@ -59,5 +59,10 @@ public bool Match(object obj)
other.LocalOffset == LocalOffset &&
other.LocalRotation == LocalRotation;
}

public ColliderShape NewShapeFromDesc()
{
return new CylinderColliderShape(Height, Radius, Orientation) { LocalOffset = LocalOffset, LocalRotation = LocalRotation };
}
}
}
@@ -8,6 +8,7 @@ namespace Xenko.Physics
public interface IColliderShapeDesc
{
bool Match(object obj);
ColliderShape NewShapeFromDesc();
}

public interface IAssetColliderShapeDesc : IColliderShapeDesc
@@ -38,5 +38,10 @@ public bool Match(object obj)
var other = obj as SphereColliderShapeDesc;
return other?.Is2D == Is2D && Math.Abs(other.Radius - Radius) < float.Epsilon && other.LocalOffset == LocalOffset;
}

public ColliderShape NewShapeFromDesc()
{
return new SphereColliderShape(Is2D, Radius) { LocalOffset = LocalOffset };
}
}
}
@@ -0,0 +1,163 @@
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

using System;
using System.Collections.Generic;
using Xenko.Core;
using Xenko.Core.Mathematics;
using Xenko.Core.Serialization.Contents;
using Xenko.Rendering;

namespace Xenko.Physics
{
[ContentSerializer(typeof(DataContentSerializer<StaticMeshColliderShapeDesc>))]
[DataContract("StaticMeshColliderShapeDesc")]
[Display(500, "Static Mesh")]
public class StaticMeshColliderShapeDesc : IAssetColliderShapeDesc
{
#if XENKO_PLATFORM_WINDOWS_DESKTOP

[Display(Browsable = false)]
#endif
[DataMember(10)]
public List<List<List<Vector3>>> Points; // Multiple meshes -> Multiple Hulls -> Hull points

#if XENKO_PLATFORM_WINDOWS_DESKTOP

[Display(Browsable = false)]
#endif
[DataMember(20)]
public List<List<List<uint>>> Indices; // Multiple meshes -> Multiple Hulls -> Hull tris

/// <userdoc>
/// Model asset from where the engine will derive the collider shape.
/// </userdoc>
[DataMember(30)]
public Model Model;

/// <userdoc>
/// The offset with the real graphic mesh.
/// </userdoc>
[DataMember(31)]
public Vector3 LocalOffset;

/// <userdoc>
/// The local rotation of the collider shape.
/// </userdoc>
[DataMember(32)]
public Quaternion LocalRotation = Quaternion.Identity;

/// <userdoc>
/// The scaling of the collider shape.
/// </userdoc>
[DataMember(45)]
public Vector3 Scaling = Vector3.One;


public bool Match(object obj)
{
var other = obj as StaticMeshColliderShapeDesc;
if (other == null)
return false;

if (other.LocalOffset != LocalOffset || other.LocalRotation != LocalRotation)
return false;

return other.Model == Model &&
other.Scaling == Scaling;
}

public ColliderShape NewShapeFromDesc()
{
if (Points == null) return null;


if (Points.Count == 1)
{
if (Points[0].Count == 1 && Indices[0][0].Count > 0)
{
var shape = new StaticMeshColliderShape(Points[0][0], Indices[0][0], Scaling)
{
NeedsCustomCollisionCallback = true,
};

//shape.UpdateLocalTransformations();
shape.Description = this;

return shape;
}

if (Points[0].Count <= 1) return null;

var subCompound = new CompoundColliderShape
{
NeedsCustomCollisionCallback = true,
};

for (var i = 0; i < Points[0].Count; i++)
{
var verts = Points[0][i];
var indices = Indices[0][i];

if (indices.Count == 0) continue;

var subHull = new StaticMeshColliderShape(verts, indices, Scaling);
//subHull.UpdateLocalTransformations();
subCompound.AddChildShape(subHull);
}

//subCompound.UpdateLocalTransformations();
subCompound.Description = this;

return subCompound;
}

if (Points.Count <= 1) return null;

var compound = new CompoundColliderShape
{
NeedsCustomCollisionCallback = true,
};

for (var i = 0; i < Points.Count; i++)
{
var verts = Points[i];
var indices = Indices[i];

if (verts.Count == 1)
{
if (indices[0].Count == 0) continue;

var subHull = new StaticMeshColliderShape(verts[0], indices[0], Scaling);
//subHull.UpdateLocalTransformations();
compound.AddChildShape(subHull);
}
else if (verts.Count > 1)
{
var subCompound = new CompoundColliderShape();

for (var b = 0; b < verts.Count; b++)
{
var subVerts = verts[b];
var subIndex = indices[b];

if (subIndex.Count == 0) continue;

var subHull = new StaticMeshColliderShape(subVerts, subIndex, Scaling);
//subHull.UpdateLocalTransformations();
subCompound.AddChildShape(subHull);
}

//subCompound.UpdateLocalTransformations();

compound.AddChildShape(subCompound);
}
}

//compound.UpdateLocalTransformations();
compound.Description = this;

return compound;
}
}
}

0 comments on commit cbcc27d

Please sign in to comment.
You can’t perform that action at this time.