去掉obi,使用自写绳索
This commit is contained in:
@@ -1,98 +0,0 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public struct BurstBoxQuery : BurstLocalOptimization.IDistanceFunction
|
||||
{
|
||||
public BurstQueryShape shape;
|
||||
public BurstAffineTransform colliderToSolver;
|
||||
|
||||
public void Evaluate(float4 point, float4 radii, quaternion orientation, ref BurstLocalOptimization.SurfacePoint projectedPoint)
|
||||
{
|
||||
float4 center = shape.center * colliderToSolver.scale;
|
||||
float4 size = shape.size * colliderToSolver.scale * 0.5f;
|
||||
|
||||
// clamp the point to the surface of the box:
|
||||
point = colliderToSolver.InverseTransformPointUnscaled(point) - center;
|
||||
|
||||
/*if (shape.is2D != 0)
|
||||
point[2] = 0;*/
|
||||
|
||||
// get minimum distance for each axis:
|
||||
float4 distances = size - math.abs(point);
|
||||
|
||||
if (distances.x >= 0 && distances.y >= 0 && distances.z >= 0)
|
||||
{
|
||||
// find minimum distance in all three axes and the axis index:
|
||||
float min = float.MaxValue;
|
||||
int axis = 0;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (distances[i] < min)
|
||||
{
|
||||
min = distances[i];
|
||||
axis = i;
|
||||
}
|
||||
}
|
||||
|
||||
projectedPoint.normal = float4.zero;
|
||||
projectedPoint.point = point;
|
||||
|
||||
projectedPoint.normal[axis] = point[axis] > 0 ? 1 : -1;
|
||||
projectedPoint.point[axis] = size[axis] * projectedPoint.normal[axis];
|
||||
}
|
||||
else
|
||||
{
|
||||
projectedPoint.point = math.clamp(point, -size, size);
|
||||
projectedPoint.normal = math.normalizesafe(point - projectedPoint.point);
|
||||
}
|
||||
|
||||
projectedPoint.point = colliderToSolver.TransformPointUnscaled(projectedPoint.point + center + projectedPoint.normal * shape.contactOffset);
|
||||
projectedPoint.normal = colliderToSolver.TransformDirection(projectedPoint.normal);
|
||||
}
|
||||
|
||||
public void Query(int shapeIndex,
|
||||
NativeArray<float4> positions,
|
||||
NativeArray<quaternion> orientations,
|
||||
NativeArray<float4> radii,
|
||||
NativeArray<int> simplices,
|
||||
int simplexIndex,
|
||||
int simplexStart,
|
||||
int simplexSize,
|
||||
|
||||
NativeQueue<BurstQueryResult>.ParallelWriter results,
|
||||
int optimizationIterations,
|
||||
float optimizationTolerance)
|
||||
{
|
||||
var co = new BurstQueryResult { simplexIndex = simplexIndex, queryIndex = shapeIndex };
|
||||
float4 simplexBary = BurstMath.BarycenterForSimplexOfSize(simplexSize);
|
||||
|
||||
var colliderPoint = BurstLocalOptimization.Optimize(ref this, positions, orientations, radii, simplices, simplexStart, simplexSize,
|
||||
ref simplexBary, out float4 convexPoint, optimizationIterations, optimizationTolerance);
|
||||
|
||||
float4 simplexPrevPosition = float4.zero;
|
||||
float simplexRadius = 0;
|
||||
|
||||
for (int j = 0; j < simplexSize; ++j)
|
||||
{
|
||||
int particleIndex = simplices[simplexStart + j];
|
||||
simplexPrevPosition += positions[particleIndex] * simplexBary[j];
|
||||
simplexRadius += BurstMath.EllipsoidRadius(colliderPoint.normal, orientations[particleIndex], radii[particleIndex].xyz) * simplexBary[j];
|
||||
}
|
||||
|
||||
co.queryPoint = colliderPoint.point;
|
||||
co.normal = colliderPoint.normal;
|
||||
co.simplexBary = simplexBary;
|
||||
co.distance = math.dot(simplexPrevPosition - colliderPoint.point, colliderPoint.normal) - simplexRadius;
|
||||
|
||||
if (co.distance <= shape.maxDistance)
|
||||
results.Enqueue(co);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6b3a07d6f9da432ea6e8e0dd3eea022
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,92 +0,0 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public struct BurstRay : BurstLocalOptimization.IDistanceFunction
|
||||
{
|
||||
public BurstQueryShape shape;
|
||||
public BurstAffineTransform colliderToSolver;
|
||||
|
||||
public void Evaluate(float4 point, float4 radii, quaternion orientation, ref BurstLocalOptimization.SurfacePoint projectedPoint)
|
||||
{
|
||||
float4x4 simplexToSolver = float4x4.TRS(point.xyz, orientation, radii.xyz);
|
||||
float4x4 solverToSimplex = math.inverse(simplexToSolver);
|
||||
float4x4 colliderToSimplex = math.mul(solverToSimplex, float4x4.TRS(colliderToSolver.translation.xyz, colliderToSolver.rotation, colliderToSolver.scale.xyz));
|
||||
|
||||
// express ray in simplex space (ellipsoid == scaled sphere)
|
||||
float4 rayOrigin = math.mul(colliderToSimplex, new float4(shape.center.xyz,1));
|
||||
float4 rayDirection = math.normalizesafe(math.mul(colliderToSimplex, new float4(shape.size.xyz,0)));
|
||||
|
||||
float rayDistance = ObiUtils.RaySphereIntersection(rayOrigin.xyz, rayDirection.xyz, float3.zero, 1);
|
||||
|
||||
if (rayDistance < 0)
|
||||
{
|
||||
point = colliderToSolver.InverseTransformPointUnscaled(point);
|
||||
|
||||
float4 centerLine = BurstMath.NearestPointOnEdge(shape.center * colliderToSolver.scale, (shape.center + shape.size) * colliderToSolver.scale, point, out float mu);
|
||||
float4 centerToPoint = point - centerLine;
|
||||
float distanceToCenter = math.length(centerToPoint);
|
||||
|
||||
float4 normal = centerToPoint / (distanceToCenter + BurstMath.epsilon);
|
||||
|
||||
projectedPoint.point = colliderToSolver.TransformPointUnscaled(centerLine + normal * shape.contactOffset);
|
||||
projectedPoint.normal = colliderToSolver.TransformDirection(normal);
|
||||
}
|
||||
else
|
||||
{
|
||||
float4 rayPoint = math.mul(simplexToSolver, new float4((rayOrigin + rayDirection * rayDistance).xyz,1));
|
||||
float4 normal = math.normalizesafe(new float4((point - rayPoint).xyz,0));
|
||||
|
||||
projectedPoint.point = rayPoint + normal * shape.contactOffset;
|
||||
projectedPoint.normal = normal;
|
||||
}
|
||||
}
|
||||
|
||||
public void Query(int shapeIndex,
|
||||
NativeArray<float4> positions,
|
||||
NativeArray<quaternion> orientations,
|
||||
NativeArray<float4> radii,
|
||||
NativeArray<int> simplices,
|
||||
int simplexIndex,
|
||||
int simplexStart,
|
||||
int simplexSize,
|
||||
|
||||
NativeQueue<BurstQueryResult>.ParallelWriter results,
|
||||
int optimizationIterations,
|
||||
float optimizationTolerance)
|
||||
{
|
||||
var co = new BurstQueryResult { simplexIndex = simplexIndex, queryIndex = shapeIndex };
|
||||
float4 simplexBary = BurstMath.BarycenterForSimplexOfSize(simplexSize);
|
||||
|
||||
var colliderPoint = BurstLocalOptimization.Optimize(ref this, positions, orientations, radii, simplices, simplexStart, simplexSize,
|
||||
ref simplexBary, out float4 convexPoint, optimizationIterations, optimizationTolerance);
|
||||
|
||||
float4 simplexPrevPosition = float4.zero;
|
||||
float simplexRadius = 0;
|
||||
|
||||
for (int j = 0; j < simplexSize; ++j)
|
||||
{
|
||||
int particleIndex = simplices[simplexStart + j];
|
||||
simplexPrevPosition += positions[particleIndex] * simplexBary[j];
|
||||
simplexRadius += BurstMath.EllipsoidRadius(colliderPoint.normal, orientations[particleIndex], radii[particleIndex].xyz) * simplexBary[j];
|
||||
}
|
||||
|
||||
co.queryPoint = colliderPoint.point;
|
||||
co.normal = colliderPoint.normal;
|
||||
co.simplexBary = simplexBary;
|
||||
co.distance = math.dot(simplexPrevPosition - colliderPoint.point, colliderPoint.normal) - simplexRadius;
|
||||
|
||||
if (co.distance <= shape.maxDistance)
|
||||
{
|
||||
float4 pointOnRay = colliderPoint.point + colliderPoint.normal * co.distance;
|
||||
co.distanceAlongRay = math.dot(pointOnRay.xyz - shape.center.xyz, math.normalizesafe(shape.size.xyz));
|
||||
results.Enqueue(co);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57b77d0143f8a4af18df103368d328f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,69 +0,0 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
public struct BurstSphereQuery : BurstLocalOptimization.IDistanceFunction
|
||||
{
|
||||
public BurstQueryShape shape;
|
||||
public BurstAffineTransform colliderToSolver;
|
||||
|
||||
public void Evaluate(float4 point, float4 radii, quaternion orientation, ref BurstLocalOptimization.SurfacePoint projectedPoint)
|
||||
{
|
||||
float4 center = shape.center * colliderToSolver.scale;
|
||||
point = colliderToSolver.InverseTransformPointUnscaled(point) - center;
|
||||
|
||||
/*if (shape.is2D != 0)
|
||||
point[2] = 0;*/
|
||||
|
||||
float radius = shape.size.x * math.cmax(colliderToSolver.scale.xyz);
|
||||
float distanceToCenter = math.length(point);
|
||||
|
||||
float4 normal = point / (distanceToCenter + BurstMath.epsilon);
|
||||
|
||||
projectedPoint.point = colliderToSolver.TransformPointUnscaled(center + normal * (radius + shape.contactOffset));
|
||||
projectedPoint.normal = colliderToSolver.TransformDirection(normal);
|
||||
}
|
||||
|
||||
public void Query(int shapeIndex,
|
||||
NativeArray<float4> positions,
|
||||
NativeArray<quaternion> orientations,
|
||||
NativeArray<float4> radii,
|
||||
NativeArray<int> simplices,
|
||||
int simplexIndex,
|
||||
int simplexStart,
|
||||
int simplexSize,
|
||||
|
||||
NativeQueue<BurstQueryResult>.ParallelWriter results,
|
||||
int optimizationIterations,
|
||||
float optimizationTolerance)
|
||||
{
|
||||
var co = new BurstQueryResult { simplexIndex = simplexIndex, queryIndex = shapeIndex };
|
||||
float4 simplexBary = BurstMath.BarycenterForSimplexOfSize(simplexSize);
|
||||
|
||||
var colliderPoint = BurstLocalOptimization.Optimize(ref this, positions, orientations, radii, simplices, simplexStart, simplexSize,
|
||||
ref simplexBary, out float4 convexPoint, optimizationIterations, optimizationTolerance);
|
||||
|
||||
float4 simplexPrevPosition = float4.zero;
|
||||
float simplexRadius = 0;
|
||||
|
||||
for (int j = 0; j < simplexSize; ++j)
|
||||
{
|
||||
int particleIndex = simplices[simplexStart + j];
|
||||
simplexPrevPosition += positions[particleIndex] * simplexBary[j];
|
||||
simplexRadius += BurstMath.EllipsoidRadius(colliderPoint.normal, orientations[particleIndex], radii[particleIndex].xyz) * simplexBary[j];
|
||||
}
|
||||
|
||||
co.queryPoint = colliderPoint.point;
|
||||
co.normal = colliderPoint.normal;
|
||||
co.simplexBary = simplexBary;
|
||||
co.distance = math.dot(simplexPrevPosition - colliderPoint.point, colliderPoint.normal) - simplexRadius;
|
||||
|
||||
if (co.distance <= shape.maxDistance)
|
||||
results.Enqueue(co);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3c36e77eab954f2e9b12e7fd5c63a6f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,129 +0,0 @@
|
||||
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
|
||||
using Unity.Jobs;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Burst;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
|
||||
[BurstCompile]
|
||||
unsafe struct SpatialQueryJob : IJobParallelFor
|
||||
{
|
||||
//collider grid:
|
||||
[ReadOnly] public NativeMultilevelGrid<int> grid;
|
||||
|
||||
// particle arrays:
|
||||
[ReadOnly] public NativeArray<float4> positions;
|
||||
[ReadOnly] public NativeArray<quaternion> orientations;
|
||||
[ReadOnly] public NativeArray<float4> radii;
|
||||
[ReadOnly] public NativeArray<int> filters;
|
||||
|
||||
// simplex arrays:
|
||||
[ReadOnly] public NativeArray<int> simplices;
|
||||
[ReadOnly] public SimplexCounts simplexCounts;
|
||||
|
||||
// query arrays:
|
||||
[ReadOnly] public NativeArray<BurstQueryShape> shapes;
|
||||
[ReadOnly] public NativeArray<BurstAffineTransform> transforms;
|
||||
|
||||
// output contacts queue:
|
||||
[WriteOnly]
|
||||
[NativeDisableParallelForRestriction]
|
||||
public NativeQueue<BurstQueryResult>.ParallelWriter results;
|
||||
|
||||
// auxiliar data:
|
||||
[ReadOnly] public BurstAffineTransform worldToSolver;
|
||||
[ReadOnly] public Oni.SolverParameters parameters;
|
||||
|
||||
// execute for each query shape:
|
||||
public void Execute(int i)
|
||||
{
|
||||
var shapeToSolver = worldToSolver * transforms[i];
|
||||
|
||||
// calculate solver-space aabb of query shape:
|
||||
BurstAabb queryBoundsSS = CalculateShapeAABB(shapes[i]).Transformed(shapeToSolver);
|
||||
|
||||
var shapeCategory = shapes[i].filter & ObiUtils.FilterCategoryBitmask;
|
||||
var shapeMask = (shapes[i].filter & ObiUtils.FilterMaskBitmask) >> 16;
|
||||
|
||||
bool is2D = parameters.mode == Oni.SolverParameters.Mode.Mode2D;
|
||||
|
||||
// iterate over all occupied cells:
|
||||
for (int c = 0; c < grid.usedCells.Length; ++c)
|
||||
{
|
||||
var cell = grid.usedCells[c];
|
||||
|
||||
// calculate thickened grid bounds:
|
||||
float size = NativeMultilevelGrid<int>.CellSizeOfLevel(cell.Coords.w);
|
||||
float4 cellPos = (float4)cell.Coords * size;
|
||||
BurstAabb cellBounds = new BurstAabb(cellPos - new float4(size), cellPos + new float4(2 * size));
|
||||
|
||||
// if cell and query bounds intersect:
|
||||
if (cellBounds.IntersectsAabb(in queryBoundsSS, is2D))
|
||||
{
|
||||
// iterate over cell contents:
|
||||
for (int k = 0; k < cell.Length; ++k)
|
||||
{
|
||||
int simplexStart = simplexCounts.GetSimplexStartAndSize(cell[k], out int simplexSize);
|
||||
|
||||
// check if any simplex particle and the query shape should collide:
|
||||
bool shouldCollide = false;
|
||||
for (int j = 0; j < simplexSize; ++j)
|
||||
{
|
||||
var simplexCategory = filters[simplices[simplexStart + j]] & ObiUtils.FilterCategoryBitmask;
|
||||
var simplexMask = (filters[simplices[simplexStart + j]] & ObiUtils.FilterMaskBitmask) >> 16;
|
||||
shouldCollide |= (simplexCategory & shapeMask) != 0 && (simplexMask & shapeCategory) != 0;
|
||||
}
|
||||
|
||||
if (shouldCollide)
|
||||
Query(shapes[i], shapeToSolver, i, cell[k], simplexStart, simplexSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BurstAabb CalculateShapeAABB(in BurstQueryShape shape)
|
||||
{
|
||||
float offset = shape.contactOffset + shape.maxDistance;
|
||||
switch (shape.type)
|
||||
{
|
||||
case QueryShape.QueryType.Sphere:
|
||||
return new BurstAabb(shape.center, shape.center, shape.size.x + offset);
|
||||
case QueryShape.QueryType.Box:
|
||||
return new BurstAabb(shape.center - shape.size*0.5f - offset, shape.center + shape.size * 0.5f + offset);
|
||||
case QueryShape.QueryType.Ray:
|
||||
return new BurstAabb(shape.center, shape.center + shape.size, offset);
|
||||
}
|
||||
return new BurstAabb();
|
||||
}
|
||||
|
||||
private void Query(in BurstQueryShape shape,
|
||||
in BurstAffineTransform shapeToSolver,
|
||||
int shapeIndex,
|
||||
int simplexIndex,
|
||||
int simplexStart,
|
||||
int simplexSize)
|
||||
{
|
||||
switch (shape.type)
|
||||
{
|
||||
case QueryShape.QueryType.Sphere:
|
||||
BurstSphereQuery sphereShape = new BurstSphereQuery { colliderToSolver = shapeToSolver, shape = shape};
|
||||
sphereShape.Query(shapeIndex, positions, orientations, radii, simplices,
|
||||
simplexIndex, simplexStart, simplexSize, results, parameters.surfaceCollisionIterations, parameters.surfaceCollisionTolerance);
|
||||
break;
|
||||
case QueryShape.QueryType.Box:
|
||||
BurstBoxQuery boxShape = new BurstBoxQuery { colliderToSolver = shapeToSolver, shape = shape};
|
||||
boxShape.Query(shapeIndex, positions, orientations, radii, simplices,
|
||||
simplexIndex, simplexStart, simplexSize, results, parameters.surfaceCollisionIterations, parameters.surfaceCollisionTolerance);
|
||||
break;
|
||||
case QueryShape.QueryType.Ray:
|
||||
BurstRay rayShape = new BurstRay { colliderToSolver = shapeToSolver, shape = shape };
|
||||
rayShape.Query(shapeIndex, positions, orientations, radii, simplices,
|
||||
simplexIndex, simplexStart, simplexSize, results, parameters.surfaceCollisionIterations, parameters.surfaceCollisionTolerance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f8bb8e6f2de74ab3b2ab294100629a4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user