public static void HyperbolaAsymptotes( NativeSlice <float3x2> segments, float a, float b, float xrange, float3 pos, quaternion rot ) { float Asymptote(float x) => (b / a) * x; float2 vertex = new float2 { y = a }; float xmin = vertex.x - xrange; float xmax = vertex.x + xrange; segments[0] = new float3x2 { c0 = pos + math.mul(rot, new float3 { x = xmin, y = Asymptote(xmin) }), c1 = pos + math.mul(rot, new float3 { x = xmax, y = Asymptote(xmax) }) }; segments[1] = new float3x2 { c0 = pos + math.mul(rot, new float3 { x = xmin, y = -Asymptote(xmin) }), c1 = pos + math.mul(rot, new float3 { x = xmax, y = -Asymptote(xmax) }) }; }
public static float3x2 sincos(this Vector3 f3) { var f = new float3x2(); math.sincos(f3, out f.c0, out f.c1); return(f); }
/// <inheritdoc/> <remarks> Will throw exception if length < 12. </remarks> public static void Parabola( NativeSlice <float3x2> segments, float a, float b, float xmin, float xmax, float3 pos, quaternion rot, int numSegments ) { const float c = 0; // float2 vertex = new float2{ x = -b / (2 * a) , y = ((4 * a * c) - (b * b)) / (4 * a) }; // float3 focus = new float3{ x = -b / (2 * a) , y = ((4 * a * c) - (b * b) + 1) / (4 * a) }; for (int index = 0; index < numSegments; index++) { float x0 = math.lerp(xmin, xmax, (float)index / (float)numSegments); float x1 = math.lerp(xmin, xmax, (float)(index + 1) / (float)numSegments); float3 v0 = math.mul(rot, new float3 { x = x0, y = a * x0 * x0 + b * x0 + c }); float3 v1 = math.mul(rot, new float3 { x = x1, y = a * x1 * x1 + b * x1 + c }); segments[index] = new float3x2 { c0 = pos + v0, c1 = pos + v1 }; } }
public static bool CapsuleIntersectsCapsule(float3 posa, float3 posb, float3 rota, float3 rotb, float lena, float lenb, float rada, float radb, out float distance) { float3x2 tipsA = GetCapsuleEndPoints(posa, rota, lena); float3x2 tipsB = GetCapsuleEndPoints(posb, rotb, lenb); float3x2 spheresA = GetCapsuleEndSpheres(tipsA.c0, tipsA.c1, rada); float3x2 spheresB = GetCapsuleEndSpheres(tipsB.c0, tipsB.c1, radb); float3 v0 = spheresB.c1 - spheresA.c1; float3 v1 = spheresB.c0 - spheresA.c1; float3 v2 = spheresB.c1 - spheresA.c0; float3 v3 = spheresA.c0 - spheresA.c0; float d0 = math.dot(v0, v0); float d1 = math.dot(v1, v1); float d2 = math.dot(v2, v2); float d3 = math.dot(v3, v3); float3 closestPointA = math.select(spheresA.c1, spheresA.c0, d2 < d0 || d2 < d1 || d3 < d0 || d3 < d1); float3 closestPointB = ClosestPointLineSegementPoint(spheresB.c1, spheresB.c0, closestPointA); closestPointA = ClosestPointLineSegementPoint(spheresA.c1, spheresA.c0, closestPointB); distance = math.distance(closestPointA, closestPointB); return(distance < rada + radb); }
private void CollisionCapsuleBox() { FixedList128 <float3> verticesOBB = ColPhysics.GetAABBVerticesOBB(posB, extentsB); verticesOBB = ColPhysics.GetRotatedVerticesOBB(verticesOBB, posB, rotB); FixedList128 <float3> normalAxesOBB = ColPhysics.GetAxisNormalsOBB(verticesOBB[0], verticesOBB[1], verticesOBB[3], verticesOBB[4]); FixedList128 <float> exte = new FixedList128 <float>(); exte.Add(extentsB.x); exte.Add(extentsB.y); exte.Add(extentsB.z); float3x2 capsuleTips = ColPhysics.GetCapsuleEndPoints(posA, rotA, extentsA.y * 2); float3x2 capsuleSpheres = ColPhysics.GetCapsuleEndSpheres(capsuleTips.c0, capsuleTips.c1, extentsA.x); if (ColPhysics.CapsuleIntersectsBox(capsuleSpheres, posB, extentsA.x, normalAxesOBB, exte, out float distance)) { isColliding = true; if (resolveCollisions) { ColPhysics.ResolveSphereBoxCollision(ref posA, extentsA.x, ref posB, distance); } } }
// TREE // private void createTree(int index, Entity prefab, BlobAssetReference <Collider> collider, float2x2 bounds) { float3x2 minMaxPositions = new float3x2 { c0 = new float3 { x = bounds.c0.x, y = 4, z = bounds.c0.y }, c1 = new float3 { x = bounds.c1.x, y = 0, z = bounds.c1.y } }; Entity newEntity = CommandBuffer.Instantiate(index, prefab); float3 position = getRandomPosition(minMaxPositions); CommandBuffer.SetComponent(index, newEntity, new Translation { Value = position }); CommandBuffer.SetComponent(index, newEntity, new PhysicsCollider { Value = collider }); float3 fruitSpawnPositionMin = position; float3 fruitSpawnPositionMax = position; fruitSpawnPositionMin.y = 8; fruitSpawnPositionMin.x -= 5; fruitSpawnPositionMax.x += 5; fruitSpawnPositionMin.z -= 5; fruitSpawnPositionMax.z += 5; fruitSpawnPositionMax.y = 10; CommandBuffer.AddComponent(index, newEntity, new ThingSpawner { PrefabCollider = prefabs.prefabColliderFruit, PrefabEntity = prefabs.prefabEntityFruit, SpawnPerCycle = 1, ThingToSpawn = ThingType.Fruit, ToSpawn = 0, MinMaxSpawnPositions = new float3x2 { c0 = fruitSpawnPositionMin, c1 = fruitSpawnPositionMax }, SpawnedFrom = newEntity }); float spawnFruitEvery = 300; CommandBuffer.AddComponent(index, newEntity, new Tree { ProducesEvery = spawnFruitEvery, SinceLastProduction = random.NextFloat(spawnFruitEvery) }); }
public void Execute(int index) { var points = new float3x4 { c0 = BezierData[index].B1.c0, c1 = BezierData[index].B1.c1, c2 = BezierData[index].B2.c0, c3 = BezierData[index].B2.c2 }; var extents = new float3x2 { c0 = { x = Min(points.c0.x, points.c1.x, points.c2.x, points.c3.x), y = Min(points.c0.y, points.c1.y, points.c2.y, points.c3.y), z = Min(points.c0.z, points.c1.z, points.c2.z, points.c3.z) }, c1 = { x = Max(points.c0.x, points.c1.x, points.c2.x, points.c3.x), y = Max(points.c0.y, points.c1.y, points.c2.y, points.c3.y), z = Max(points.c0.z, points.c1.z, points.c2.z, points.c3.z) } }; BoundsArray[index] = new float3x2 { c0 = math.lerp(extents.c1, extents.c0, 0.5f), c1 = extents.c1 - extents.c0 }; }
/// <inheritdoc/> <remarks> Will throw exception if length < numSegments. </remarks> public static void HyperbolaAtFoci( NativeSlice <float3x2> segments, float a, float b, float xrange, float3 pos, quaternion rot, int numSegments ) { float c = math.sqrt(a * a + b * b); float2 vertex = new float2 { y = a }; float3 focus = new float3 { x = 0, y = c }; float xmin = vertex.x - xrange; float xmax = vertex.x + xrange; int index = 0; for ( ; index < numSegments;) { float x0 = math.lerp(xmin, xmax, (float)index / (float)numSegments); float x1 = math.lerp(xmin, xmax, (float)(index + 1) / (float)numSegments); float3 v0 = math.mul(rot, (new float3 { x = x0, y = (b * math.sqrt(a * a + x0 * x0)) / a } -focus)); float3 v1 = math.mul(rot, (new float3 { x = x1, y = (b * math.sqrt(a * a + x1 * x1)) / a } -focus)); segments[index++] = new float3x2 { c0 = pos + v0, c1 = pos + v1 }; } }
/// <inheritdoc/> <remarks> Will throw exception if length < numSegments. </remarks> public static void Ellipse( NativeSlice <float3x2> segments, float rx, float ry, float3 pos, quaternion rot, int numSegments ) { float theta = (2f * math.PI) / (float)numSegments; int index = 0; for ( ; index < numSegments;) { float f0 = theta * (float)index; float f1 = theta * (float)(index + 1); float3 v0 = math.mul(rot, (new float3 { x = math.cos(f0) * rx, y = math.sin(f0) * ry })); float3 v1 = math.mul(rot, (new float3 { x = math.cos(f1) * rx, y = math.sin(f1) * ry })); segments[index++] = new float3x2 { c0 = pos + v0, c1 = pos + v1 }; } // float a = math.max(rx,ry); // float b = math.min(rx,ry); // float ecc = math.sqrt( 1f - (b*b)/(a*a) ); // float c = a * ecc; // float3 focus = rx>ry ? new float3{x=c} : new float3{y=c}; // foci( pos + math.mul(rot,focus) ); // foci( pos + math.mul(rot,-focus) ); }
// BUBBLE // private void createBubble(int index, Entity prefab, float2x2 bounds) { float3x2 minMaxPositions = new float3x2 { c0 = new float3(bounds.c0.x + 20, -10, bounds.c0.y + 20), c1 = new float3(bounds.c1.x - 20, -4, bounds.c1.y - 20) }; Entity newEntity = CommandBuffer.Instantiate(index, prefab); float3 position = getRandomPosition(minMaxPositions); CommandBuffer.SetComponent(index, newEntity, new Translation { Value = position }); CommandBuffer.AddComponent(index, newEntity, new ScaleChange { Axis = ScaleChangeAxis.Y, MinMax = new float2(22, 28), Shrinking = 0, Speed = random.NextFloat(1, 4), SpeedRatioWhenShrinking = random.NextFloat(.1f, .9f) }); CommandBuffer.SetComponent(index, newEntity, new NonUniformScale { Value = new float3(random.NextFloat(10, 50), random.NextFloat(22, 28), random.NextFloat(10, 50)) }); }
public void TestMatrix() { var a = new float3x2(1, 2, 1, 2, 2, 1); var b = new float2x3(2, 2, 1, 3, 1, 2); var c = math.mul(a, b); Debug.Log($"{c}"); }
public static bool CapsuleIntersectsBox(float3x2 capsuleSpheres, float3 obbPos, float capsuleRadius, FixedList128 <float3> boxNormals, FixedList128 <float> boxExtents, out float distance) { float3 closestPoint = ClosestPointLineSegementPoint(capsuleSpheres.c1, capsuleSpheres.c0, obbPos); bool intersects = SphereIntersectsBox(closestPoint, capsuleRadius, obbPos, boxNormals, boxExtents, out float dist); distance = dist; return(intersects); }
public static bool SphereIntersectsCapsule(float3 spherePos, float sphereRadius, float3 capsulePos, float3 capsuleRot, float capsuleLength, float capsuleRadius) { float3x2 capsuleTips = GetCapsuleEndPoints(capsulePos, capsuleRot, capsuleLength); float3x2 capsuleSpheres = GetCapsuleEndSpheres(capsuleTips.c0, capsuleTips.c1, capsuleRadius); float3 closestPoint = ClosestPointLineSegementPoint(capsuleSpheres.c1, capsuleSpheres.c0, spherePos); return(math.distancesq(spherePos, closestPoint) < sphereRadius + capsuleRadius); }
private static void CustomVisit(ref float3x2 f) { LogVisit(f); GUILayout.Label(name); EditorGUI.indentLevel++; f[0] = EditorGUILayout.Vector3Field("", (Vector3)f[0]); f[1] = EditorGUILayout.Vector3Field("", (Vector3)f[1]); EditorGUI.indentLevel--; }
float GetClosestDistanceFromTwoPositions(float3x2 from, float3 to) { float distance = GetDistance(from.c0, to); float otherEyeDistance = GetDistance(from.c1, to); if (otherEyeDistance < distance) { return(otherEyeDistance); } return(distance); }
float GetEyeDistance(float3x2 eyePositions, float3 to) { if (speciesEyeType == EyesScript.EyeTypes.Foward) { return(GetDistance(eyePositions.c0, to)); } else { return(GetClosestDistanceFromTwoPositions(eyePositions, to)); } }
private static float3x2 GetControlPoints([ReadOnly] ref float3[] knots, int index, float tension = 0.66f) { var result = new float3x2(new float3(), new float3()); var thisVector = knots[index]; float looseness = (1f - tension) / 2; var previousVector = knots[index - 1 < 0 ? knots.Length - 1 : index - 1]; var nextVector = knots[index + 1 >= knots.Length ? 0 : index + 1]; var heading = math.normalize(nextVector - previousVector); result.c0 = thisVector - heading * math.length(thisVector - previousVector) * looseness; result.c1 = thisVector + heading * math.length(nextVector - thisVector) * looseness; return(result); }
void Update() { _batch.Dependency.Complete(); var buffer = _batch.buffer; buffer.Length = 3; Vector3 position = transform.position; buffer[0] = new float3x2(position, position + transform.right); buffer[1] = new float3x2(position, position + transform.up); buffer[2] = new float3x2(position, position + transform.forward); }
/// <inheritdoc/> <remarks> Will throw exception if length < 12. </remarks> public static void ParabolaAtFoci( NativeSlice <float3x2> segments, float a, float b, float xrange, float3 pos, quaternion rot, int numSegments ) { const float c = 0; float2 vertex = new float2 { x = -b / (2 * a), y = ((4 * a * c) - (b * b)) / (4 * a) }; float3 focus = new float3 { x = -b / (2 * a), y = ((4 * a * c) - (b * b) + 1) / (4 * a) }; float directrix_y = c - ((b * b) + 1) * 4 * a; float xmin = vertex.x - xrange; float xmax = vertex.x + xrange; int index = 0; for ( ; index < numSegments - 1;) { float x0 = math.lerp(xmin, xmax, (float)index / (float)numSegments); float x1 = math.lerp(xmin, xmax, (float)(index + 1) / (float)numSegments); float3 v0 = math.mul(rot, (new float3 { x = x0, y = a * x0 * x0 + b * x0 + c } -focus)); float3 v1 = math.mul(rot, (new float3 { x = x1, y = a * x1 * x1 + b * x1 + c } -focus)); segments[index++] = new float3x2 { c0 = pos + v0, c1 = pos + v1 }; } segments[index++] = new float3x2 { c0 = math.mul(rot, new float3 { x = xmin, y = directrix_y } -focus) + new float3 { x = pos.z }, c1 = math.mul(rot, new float3 { x = xmax, y = directrix_y } -focus) + new float3 { x = pos.z } }; }
/// <inheritdoc/> <remarks> Will does nothing if array is too short. </remarks> public static void Line( NativeArray <float3x2> segments, ref int index, float3 start, float3 end ) { int bufferSizeRequired = index + 1; if (segments.Length < bufferSizeRequired) { return; } segments[index++] = new float3x2 { c0 = start, c1 = end }; }
/// <inheritdoc/> <remarks> Will throw exception if length < numDashes. </remarks> public static void DashedLine( NativeSlice <float3x2> segments, float3 start, float3 end, int numSegments ) { int index = 0; int max = math.max(numSegments * 2 - 1, 0); for (int i = 0; i < max; i += 2) { segments[index++] = new float3x2 { c0 = math.lerp(start, end, (float)(i) / (float)max), c1 = math.lerp(start, end, (float)(i + 1) / (float)max) }; } }
public AnimalData(AnimalScript animal) { age = animal.age; speciesIndex = animal.species.speciesIndex; specificSpeciesIndex = animal.species.specificSpeciesIndex; animalIndex = animal.specificOrganismIndex; position = animal.position; zone = animal.zone; animalEyePosition = GetAnimalEyePositions(animal, animal.GetEyes()); animalMouthPosition = GetMouthPosition(animal, animal.GetMouth()); animalFood = animal.food; animalSex = animal.GetReproductive().GetSex(); animalHasMate = AnimalHasMate(animal); animalReproductionReady = ReadyToReproduce(animal); stage = animal.stage; }
void IJobParallelFor.Execute(int index) { int i0 = Edges[index].x; int i1 = Edges[index].y; float4 p0 = math.mul(Transform, new float4(Vertices[i0], 1)); float4 p1 = math.mul(Transform, new float4(Vertices[i1], 1)); Segments[index] = new float3x2 { c0 = new float3 { x = p0.x, y = p0.y, z = p0.z }, c1 = new float3 { x = p1.x, y = p1.y, z = p1.z } }; }
public static float3x2 GetAnimalEyePositions(AnimalScript animal, EyesScript eyes) { if (eyes != null) { float3x2 eyePostions; if (eyes.GetEyeType() == EyesScript.EyeTypes.Foward) { eyePostions = new float3x2(eyes.eyes[0].position, eyes.eyes[0].position); } else { eyePostions = new float3x2(eyes.eyes[0].position, eyes.eyes[1].position); } return(eyePostions); } return(new float3x2(animal.position, animal.position)); }
public static bool CapsuleIntersectsCapsule(float3x2 spheresA, float3x2 spheresB, float rada, float radb) { float3 v0 = spheresB.c1 - spheresA.c1; float3 v1 = spheresB.c0 - spheresA.c1; float3 v2 = spheresB.c1 - spheresA.c0; float3 v3 = spheresA.c0 - spheresA.c0; float d0 = math.dot(v0, v0); float d1 = math.dot(v1, v1); float d2 = math.dot(v2, v2); float d3 = math.dot(v3, v3); float3 closestPointA = math.select(spheresA.c1, spheresA.c0, d2 < d0 || d2 < d1 || d3 < d0 || d3 < d1); float3 closestPointB = ClosestPointLineSegementPoint(spheresB.c1, spheresB.c0, closestPointA); closestPointA = ClosestPointLineSegementPoint(spheresA.c1, spheresA.c0, closestPointB); return(math.distancesq(closestPointA, closestPointB) < rada + radb); }
/// <remarks> Will throw exception if length < 1. </remarks> public static void ParabolaDirectrix( NativeSlice <float3x2> segments, float a, float b, float xmin, float xmax, float3 pos, quaternion rot ) { const float c = 0; float directrix_y = c - ((b * b) + 1) * 4 * a; segments[0] = new float3x2 { c0 = pos + math.mul(rot, new float3 { x = xmin, y = directrix_y }), c1 = pos + math.mul(rot, new float3 { x = xmax, y = directrix_y }) }; }
void IJobParallelFor.Execute(int index) { float t0 = (float)index / (float)NumSegments; float t1 = (float)(index + 1) / (float)NumSegments; float2 amp = math.sin(Frequency * new float2 { x = t0 * math.PI * 2f + Offset, y = t1 * math.PI * 2f + Offset }); float3 vec0 = math.transform(Transform, new float3 { x = t0, y = amp.x }); float3 vec1 = math.transform(Transform, new float3 { x = t1, y = amp.y }); Segments[index] = new float3x2 { c0 = vec0, c1 = vec1 }; }
void IJob.Execute() { float3 position = new float3 { x = LocalToWorld.c3.x, y = LocalToWorld.c3.y, z = LocalToWorld.c3.z }; float3x3 rotation = new float3x3(LocalToWorld); float3 right = math.mul(rotation, new float3 { x = 1 }); float3 up = math.mul(rotation, new float3 { y = 1 }); float3 forward = math.mul(rotation, new float3 { z = 1 }); Buffer[0] = new float3x2(position, position + right); Buffer[1] = new float3x2(position, position + up); Buffer[2] = new float3x2(position, position + forward); }
/// <inheritdoc/> <remarks> Will throw exception if length < numSegments. </remarks> public static void Hyperbola( NativeSlice <float3x2> segments, float a, float b, float xrange, float3 pos, quaternion rot, int numSegments ) { float c = math.sqrt(a * a + b * b); float2 vertex = new float2 { y = a }; float3 focus = new float3 { y = c }; float3 fmirror = new float3 { x = 1, y = -1f, z = 1 }; float xmin = vertex.x - xrange; float xmax = vertex.x + xrange; int index = 0; for (int i = 0; i < numSegments; i++) { float x0 = math.lerp(xmin, xmax, (float)i / (float)numSegments); float x1 = math.lerp(xmin, xmax, (float)(i + 1) / (float)numSegments); float3 p0 = new float3 { x = x0, y = (b * math.sqrt(a * a + x0 * x0)) / a }; float3 p1 = new float3 { x = x1, y = (b * math.sqrt(a * a + x1 * x1)) / a }; float3 v0 = math.mul(rot, p0); float3 v1 = math.mul(rot, p1); segments[index++] = new float3x2 { c0 = pos + v0, c1 = pos + v1 }; } }
/// <inheritdoc/> <remarks> Will throw exception if length < 4. </remarks> public static void Arrow( NativeSlice <float3x2> segments, float3 v1, float3 v2, float3 cameraPos ) { float3 arrowLen = math.normalize(v1 - v2) * math.distance(v1, v2) * 0.06f; float3 camAxis = math.normalize(v2 - cameraPos); float3 v3 = v2 + math.mul(quaternion.AxisAngle(camAxis, math.PI / 14f), arrowLen); float3 v4 = v2 + math.mul(quaternion.AxisAngle(camAxis, -math.PI / 14f), arrowLen); segments[0] = new float3x2 { c0 = v1, c1 = v2 }; segments[1] = new float3x2 { c0 = v2, c1 = v3 }; segments[2] = new float3x2 { c0 = v3, c1 = v4 }; segments[3] = new float3x2 { c0 = v4, c1 = v2 }; }