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 }