Files
2025-05-29 22:31:40 +03:00

654 lines
25 KiB
C#

using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Obi;
/**
* Interface for the Oni particle physics library.
*/
public static class Oni
{
public const int ConstraintTypeCount = 17;
public enum ConstraintType
{
Tether = 0,
Volume = 1,
Chain = 2,
Bending = 3,
Distance = 4,
ShapeMatching = 5,
BendTwist = 6,
StretchShear = 7,
Pin = 8,
ParticleCollision = 9,
Density = 10,
Collision = 11,
Skin = 12,
Aerodynamics = 13,
Stitch = 14,
ParticleFriction = 15,
Friction = 16
};
public enum ShapeType
{
Sphere = 0,
Box = 1,
Capsule = 2,
Heightmap = 3,
TriangleMesh = 4,
EdgeMesh = 5,
SignedDistanceField = 6
}
public enum MaterialCombineMode
{
Average = 0,
Minimum = 1,
Multiply = 2,
Maximum = 3
}
public enum ProfileMask : uint
{
ThreadIdMask = 0xffff0000,
TypeMask = 0x000000ff,
StackLevelMask = 0x0000ff00
}
public struct ProfileInfo
{
public double start;
public double end;
public uint info;
public int pad;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string name;
}
public struct GridCell
{
public Vector3 center;
public Vector3 size;
public int count;
}
[Serializable]
public struct SolverParameters
{
public enum Interpolation
{
None,
Interpolate,
};
public enum Mode
{
Mode3D,
Mode2D,
};
[Tooltip("In 2D mode, particles are simulated on the XY plane only. For use in conjunction with Unity's 2D mode.")]
public Mode mode;
[Tooltip("Same as Rigidbody.interpolation. Set to INTERPOLATE for cloth that is applied on a main character or closely followed by a camera. NONE for everything else.")]
public Interpolation interpolation;
[Tooltip("Simulation gravity expressed in local space.")]
public Vector3 gravity;
[Tooltip("Percentage of velocity lost per second, between 0% (0) and 100% (1).")]
[Range(0, 1)]
public float damping;
[Tooltip("Max ratio between a particle's longest and shortest axis. Use 1 for isotropic (completely round) particles.")]
[Range(1, 5)]
public float maxAnisotropy;
[Tooltip("Mass-normalized kinetic energy threshold below which particle positions aren't updated.")]
public float sleepThreshold;
[Tooltip("Maximum distance between elements (simplices/colliders) for a contact to be generated.")]
public float collisionMargin;
[Tooltip("Maximum depenetration velocity applied to particles that start a frame inside an object. Low values ensure no 'explosive' collision resolution. Should be > 0 unless looking for non-physical effects.")]
public float maxDepenetration;
[Tooltip("Percentage of particle velocities used for continuous collision detection. Set to 0 for purely static collisions, set to 1 for pure continuous collisions.")]
[Range(0, 1)]
public float continuousCollisionDetection;
[Tooltip("Percentage of shock propagation applied to particle-particle collisions. Useful for particle stacking.")]
[Range(0, 1)]
public float shockPropagation;
[Tooltip("Amount of iterations spent on convex optimization for surface collisions.")]
[Range(1, 32)]
public int surfaceCollisionIterations;
[Tooltip("Error threshold at which to stop convex optimization for surface collisions.")]
public float surfaceCollisionTolerance;
public SolverParameters(Interpolation interpolation, Vector4 gravity)
{
this.mode = Mode.Mode3D;
this.gravity = gravity;
this.interpolation = interpolation;
damping = 0;
shockPropagation = 0;
surfaceCollisionIterations = 8;
surfaceCollisionTolerance = 0.005f;
maxAnisotropy = 3;
maxDepenetration = 10;
sleepThreshold = 0.0005f;
collisionMargin = 0.02f;
continuousCollisionDetection = 1;
}
}
[Serializable]
public struct ConstraintParameters
{
public enum EvaluationOrder
{
Sequential,
Parallel
};
[Tooltip("Order in which constraints are evaluated. SEQUENTIAL converges faster but is not very stable. PARALLEL is very stable but converges slowly, requiring more iterations to achieve the same result.")]
public EvaluationOrder evaluationOrder; /**< Constraint evaluation order.*/
[Tooltip("Number of relaxation iterations performed by the constraint solver. A low number of iterations will perform better, but be less accurate.")]
public int iterations; /**< Amount of solver iterations per step for this constraint group.*/
[Tooltip("Over (or under if < 1) relaxation factor used. At 1, no overrelaxation is performed. At 2, constraints double their relaxation rate. High values reduce stability but improve convergence.")]
[Range(0.1f, 2)]
public float SORFactor; /**< Sucessive over-relaxation factor for parallel evaluation order.*/
[Tooltip("Whether this constraint group is solved or not.")]
[MarshalAs(UnmanagedType.I1)]
public bool enabled;
public ConstraintParameters(bool enabled, EvaluationOrder order, int iterations)
{
this.enabled = enabled;
this.iterations = iterations;
this.evaluationOrder = order;
this.SORFactor = 1;
}
}
// In this particular case, size is forced to 144 bytes to ensure 16 byte memory alignment needed by Oni.
[StructLayout(LayoutKind.Sequential, Size = 144)]
public struct Contact
{
public Vector4 pointA;
public Vector4 pointB; /**< Speculative point of contact. */
public Vector4 normal; /**< Normal direction. */
public Vector4 tangent; /**< Tangent direction. */
public Vector4 bitangent; /**< Bitangent direction. */
public float distance; /** distance between both colliding entities at the beginning of the timestep.*/
public float normalImpulse;
public float tangentImpulse;
public float bitangentImpulse;
public float stickImpulse;
public float rollingFrictionImpulse;
public int bodyA; /** simplex index*/
public int bodyB; /** simplex or rigidbody index*/
}
public static GCHandle PinMemory(object data)
{
return GCHandle.Alloc(data, GCHandleType.Pinned);
}
public static void UnpinMemory(GCHandle handle)
{
if (handle.IsAllocated)
handle.Free();
}
#if (UNITY_IOS && !UNITY_EDITOR)
const string LIBNAME = "__Internal";
#elif ((UNITY_ANDROID || UNITY_STANDALONE_LINUX) && !UNITY_EDITOR)
const string LIBNAME = "Oni";
#else
const string LIBNAME = "libOni";
#endif
// platform custom define (https://docs.unity3d.com/Manual/PlatformDependentCompilation.html)
#if (OBI_ONI_SUPPORTED)
[DllImport(LIBNAME)]
public static extern void UpdateColliderGrid(float dt);
[DllImport(LIBNAME)]
public static extern void SetColliders(IntPtr shapes, IntPtr bounds, IntPtr transforms, int count);
[DllImport(LIBNAME)]
public static extern void SetRigidbodies(IntPtr rigidbodies);
[DllImport(LIBNAME)]
public static extern void SetCollisionMaterials(IntPtr materials);
[DllImport(LIBNAME)]
public static extern void SetTriangleMeshData(IntPtr headers, IntPtr nodes, IntPtr triangles, IntPtr vertices);
[DllImport(LIBNAME)]
public static extern void SetEdgeMeshData(IntPtr headers, IntPtr nodes, IntPtr edges, IntPtr vertices);
[DllImport(LIBNAME)]
public static extern void SetDistanceFieldData(IntPtr headers, IntPtr nodes);
[DllImport(LIBNAME)]
public static extern void SetHeightFieldData(IntPtr headers, IntPtr samples);
[DllImport(LIBNAME)]
public static extern IntPtr CreateSolver(int capacity);
[DllImport(LIBNAME)]
public static extern void DestroySolver(IntPtr solver);
[DllImport(LIBNAME)]
public static extern void SetCapacity(IntPtr solver, int capacity);
[DllImport(LIBNAME)]
public static extern void InitializeFrame(IntPtr solver, ref Vector4 translation, ref Vector4 scale, ref Quaternion rotation);
[DllImport(LIBNAME)]
public static extern void UpdateFrame(IntPtr solver, ref Vector4 translation, ref Vector4 scale, ref Quaternion rotation, float dt);
[DllImport(LIBNAME)]
public static extern void ApplyFrame(IntPtr solver, float linearVelocityScale, float angularVelocityScale, float linearInertiaScale, float angularInertiaScale, float dt);
[DllImport(LIBNAME)]
public static extern void RecalculateInertiaTensors(IntPtr solver);
[DllImport(LIBNAME)]
public static extern void ResetForces(IntPtr solver);
[DllImport(LIBNAME)]
public static extern void SetRigidbodyLinearDeltas(IntPtr solver, IntPtr linearDeltas);
[DllImport(LIBNAME)]
public static extern void SetRigidbodyAngularDeltas(IntPtr solver, IntPtr angularDeltas);
[DllImport(LIBNAME)]
public static extern void GetBounds(IntPtr solver, ref Vector3 min, ref Vector3 max);
[DllImport(LIBNAME)]
public static extern int GetParticleGridSize(IntPtr solver);
[DllImport(LIBNAME)]
public static extern void GetParticleGrid(IntPtr solver, GridCell[] cells);
[DllImport(LIBNAME)]
public static extern int SpatialQuery(IntPtr solver, IntPtr shapes, IntPtr transforms, int count);
[DllImport(LIBNAME)]
public static extern void GetQueryResults(IntPtr solver, IntPtr results, int num);
[DllImport(LIBNAME)]
public static extern void SetSolverParameters(IntPtr solver, ref SolverParameters parameters);
[DllImport(LIBNAME)]
public static extern void GetSolverParameters(IntPtr solver, ref SolverParameters parameters);
[DllImport(LIBNAME)]
public static extern int SetActiveParticles(IntPtr solver, int[] active, int num);
[DllImport(LIBNAME)]
public static extern IntPtr CollisionDetection(IntPtr solver, float delta_time);
[DllImport(LIBNAME)]
public static extern IntPtr Step(IntPtr solver, float step_time, float substep_time, int substeps);
[DllImport(LIBNAME)]
public static extern void ApplyPositionInterpolation(IntPtr solver, IntPtr draw_positions, IntPtr draw_orientations, float delta_seconds, float unsimulated_time);
[DllImport(LIBNAME)]
public static extern void UpdateSkeletalAnimation(IntPtr solver);
[DllImport(LIBNAME)]
public static extern int GetConstraintCount(IntPtr solver, int type);
[DllImport(LIBNAME)]
public static extern void SetRenderableParticlePositions(IntPtr solver, IntPtr positions);
[DllImport(LIBNAME)]
public static extern void SetParticlePhases(IntPtr solver, IntPtr phases);
[DllImport(LIBNAME)]
public static extern void SetParticleFilters(IntPtr solver, IntPtr filters);
[DllImport(LIBNAME)]
public static extern void SetParticleCollisionMaterials(IntPtr solver, IntPtr materialIndices);
[DllImport(LIBNAME)]
public static extern void SetParticlePositions(IntPtr solver, IntPtr positions);
[DllImport(LIBNAME)]
public static extern void SetParticlePreviousPositions(IntPtr solver, IntPtr prevPositions);
[DllImport(LIBNAME)]
public static extern void SetParticleOrientations(IntPtr solver, IntPtr orientations);
[DllImport(LIBNAME)]
public static extern void SetParticlePreviousOrientations(IntPtr solver, IntPtr prevOrientations);
[DllImport(LIBNAME)]
public static extern void SetRenderableParticleOrientations(IntPtr solver, IntPtr orientations);
[DllImport(LIBNAME)]
public static extern void SetParticleInverseMasses(IntPtr solver, IntPtr invMasses);
[DllImport(LIBNAME)]
public static extern void SetParticleInverseRotationalMasses(IntPtr solver, IntPtr invRotMasses);
[DllImport(LIBNAME)]
public static extern void SetParticlePrincipalRadii(IntPtr solver, IntPtr principalRadii);
[DllImport(LIBNAME)]
public static extern void SetParticleVelocities(IntPtr solver, IntPtr velocities);
[DllImport(LIBNAME)]
public static extern void SetParticleAngularVelocities(IntPtr solver, IntPtr angularVelocities);
[DllImport(LIBNAME)]
public static extern void SetParticleExternalForces(IntPtr solver, IntPtr forces);
[DllImport(LIBNAME)]
public static extern void SetParticleExternalTorques(IntPtr solver, IntPtr torques);
[DllImport(LIBNAME)]
public static extern void SetParticleWinds(IntPtr solver, IntPtr winds);
[DllImport(LIBNAME)]
public static extern void SetParticlePositionDeltas(IntPtr solver, IntPtr deltas);
[DllImport(LIBNAME)]
public static extern void SetParticleOrientationDeltas(IntPtr solver, IntPtr deltas);
[DllImport(LIBNAME)]
public static extern void SetParticlePositionConstraintCounts(IntPtr solver, IntPtr counts);
[DllImport(LIBNAME)]
public static extern void SetParticleOrientationConstraintCounts(IntPtr solver, IntPtr counts);
[DllImport(LIBNAME)]
public static extern void SetParticleNormals(IntPtr solver, IntPtr normals);
[DllImport(LIBNAME)]
public static extern void SetParticleInverseInertiaTensors(IntPtr solver, IntPtr tensors);
[DllImport(LIBNAME)]
public static extern void SetParticleSmoothingRadii(IntPtr solver, IntPtr radii);
[DllImport(LIBNAME)]
public static extern void SetParticleBuoyancy(IntPtr solver, IntPtr buoyancy);
[DllImport(LIBNAME)]
public static extern void SetParticleRestDensities(IntPtr solver, IntPtr rest_densities);
[DllImport(LIBNAME)]
public static extern void SetParticleViscosities(IntPtr solver, IntPtr viscosities);
[DllImport(LIBNAME)]
public static extern void SetParticleSurfaceTension(IntPtr solver, IntPtr surface_tension);
[DllImport(LIBNAME)]
public static extern void SetParticleVorticityConfinement(IntPtr solver, IntPtr vort_confinement);
[DllImport(LIBNAME)]
public static extern void SetParticleAtmosphericDragPressure(IntPtr solver, IntPtr atmospheric_drag, IntPtr atmospheric_pressure);
[DllImport(LIBNAME)]
public static extern void SetParticleDiffusion(IntPtr solver, IntPtr diffusion);
[DllImport(LIBNAME)]
public static extern void SetParticleVorticities(IntPtr solver, IntPtr vorticities);
[DllImport(LIBNAME)]
public static extern void SetParticleFluidData(IntPtr solver, IntPtr fluidData);
[DllImport(LIBNAME)]
public static extern void SetParticleUserData(IntPtr solver, IntPtr userData);
[DllImport(LIBNAME)]
public static extern void SetParticleAnisotropies(IntPtr solver, IntPtr anisotropies);
[DllImport(LIBNAME)]
public static extern void SetSimplices(IntPtr solver, int[] indices, int pointCount, int edgeCount, int triangleCount);
[DllImport(LIBNAME)]
public static extern int GetDeformableTriangleCount(IntPtr solver);
[DllImport(LIBNAME)]
public static extern void SetDeformableTriangles(IntPtr solver, int[] indices, int num, int destOffset);
[DllImport(LIBNAME)]
public static extern int RemoveDeformableTriangles(IntPtr solver, int num, int sourceOffset);
[DllImport(LIBNAME)]
public static extern void SetConstraintGroupParameters(IntPtr solver, int type, ref ConstraintParameters parameters);
[DllImport(LIBNAME)]
public static extern void GetConstraintGroupParameters(IntPtr solver, int type, ref ConstraintParameters parameters);
[DllImport(LIBNAME)]
public static extern void SetRestPositions(IntPtr solver, IntPtr restPositions);
[DllImport(LIBNAME)]
public static extern void SetRestOrientations(IntPtr solver, IntPtr restOrientations);
[DllImport(LIBNAME)]
public static extern IntPtr CreateBatch(int type);
[DllImport(LIBNAME)]
public static extern void DestroyBatch(IntPtr batch);
[DllImport(LIBNAME)]
public static extern IntPtr AddBatch(IntPtr solver, IntPtr batch);
[DllImport(LIBNAME)]
public static extern void RemoveBatch(IntPtr solver, IntPtr batch);
[DllImport(LIBNAME)]
public static extern bool EnableBatch(IntPtr batch, [MarshalAs(UnmanagedType.I1)]bool enabled);
[DllImport(LIBNAME)]
public static extern int GetBatchConstraintForces(IntPtr batch, float[] forces, int num, int destOffset);
[DllImport(LIBNAME)]
public static extern void SetBatchConstraintCount(IntPtr batch, int num);
[DllImport(LIBNAME)]
public static extern int GetBatchConstraintCount(IntPtr batch);
[DllImport(LIBNAME)]
public static extern void SetDistanceConstraints(IntPtr batch, IntPtr indices,
IntPtr restLengths,
IntPtr stiffnesses,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetBendingConstraints(IntPtr batch, IntPtr indices,
IntPtr restBends,
IntPtr bendingStiffnesses,
IntPtr plasticity,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetSkinConstraints(IntPtr batch,
IntPtr indices,
IntPtr points,
IntPtr normals,
IntPtr radiiBackstops,
IntPtr stiffnesses,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetAerodynamicConstraints(IntPtr batch,
IntPtr particleIndices,
IntPtr aerodynamicCoeffs,
int num);
[DllImport(LIBNAME)]
public static extern void SetVolumeConstraints(IntPtr batch,
IntPtr triangleIndices,
IntPtr firstTriangle,
IntPtr numTriangles,
IntPtr restVolumes,
IntPtr pressureStiffnesses,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetShapeMatchingConstraints(IntPtr batch,
IntPtr shapeIndices,
IntPtr firstIndex,
IntPtr numIndices,
IntPtr explicitGroup,
IntPtr materialParameters,
IntPtr restComs,
IntPtr coms,
IntPtr orientations,
IntPtr linearTransforms,
IntPtr plasticDeformations,
int num);
[DllImport(LIBNAME)]
public static extern void CalculateRestShapeMatching(IntPtr solver, IntPtr batch);
[DllImport(LIBNAME)]
public static extern void SetStretchShearConstraints(IntPtr batch,
IntPtr particleIndices,
IntPtr orientationIndices,
IntPtr restLengths,
IntPtr restOrientations,
IntPtr stiffnesses,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetBendTwistConstraints(IntPtr batch,
IntPtr orientationIndices,
IntPtr restDarboux,
IntPtr stiffnesses,
IntPtr plasticity,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetTetherConstraints(IntPtr batch,
IntPtr indices,
IntPtr maxLenghtsScales,
IntPtr stiffnesses,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetPinConstraints(IntPtr batch,
IntPtr indices,
IntPtr pinOffsets,
IntPtr restDarboux,
IntPtr colliders,
IntPtr stiffnesses,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetStitchConstraints(IntPtr batch,
IntPtr indices,
IntPtr stiffnesses,
IntPtr lambdas,
int num);
[DllImport(LIBNAME)]
public static extern void SetChainConstraints(IntPtr batch,
IntPtr indices,
IntPtr lengths,
IntPtr firstIndex,
IntPtr numIndex,
int num);
[DllImport(LIBNAME)]
public static extern void GetCollisionContacts(IntPtr solver, Contact[] contacts, int n);
[DllImport(LIBNAME)]
public static extern void GetParticleCollisionContacts(IntPtr solver, Contact[] contacts, int n);
[DllImport(LIBNAME)]
public static extern int InterpolateDiffuseParticles(IntPtr solver, IntPtr properties, IntPtr diffusePositions, IntPtr diffuseProperties, IntPtr neighbourCount, int n);
[DllImport(LIBNAME)]
public static extern int MakePhase(int group, ObiUtils.ParticleFlags flags);
[DllImport(LIBNAME)]
public static extern int GetGroupFromPhase(int phase);
[DllImport(LIBNAME)]
public static extern int GetFlagsFromPhase(int phase);
[DllImport(LIBNAME)]
public static extern float BendingConstraintRest(float[] constraintCoordinates);
[DllImport(LIBNAME)]
public static extern void CompleteAll();
[DllImport(LIBNAME)]
public static extern void Complete(IntPtr task);
[DllImport(LIBNAME)]
public static extern IntPtr CreateEmpty();
[DllImport(LIBNAME)]
public static extern void Schedule(IntPtr task);
[DllImport(LIBNAME)]
public static extern void AddChild(IntPtr task, IntPtr child);
[DllImport(LIBNAME)]
public static extern int GetMaxSystemConcurrency();
[DllImport(LIBNAME)]
public static extern void ClearProfiler();
[DllImport(LIBNAME)]
public static extern void EnableProfiler([MarshalAs(UnmanagedType.I1)]bool cooked);
[DllImport(LIBNAME)]
public static extern void BeginSample(string name, byte type);
[DllImport(LIBNAME)]
public static extern void EndSample();
[DllImport(LIBNAME)]
public static extern int GetProfilingInfoCount();
[DllImport(LIBNAME)]
public static extern void GetProfilingInfo([Out] ProfileInfo[] info, int num);
#endif
}