去掉obi,使用自写绳索

This commit is contained in:
2026-02-23 20:51:03 +08:00
parent cb636f862d
commit 91e2309eeb
2011 changed files with 2593 additions and 190578 deletions

View File

@@ -1,216 +0,0 @@
using System.Runtime.InteropServices;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using Unity.Profiling;
namespace Obi
{
[StructLayout(LayoutKind.Sequential)]
public struct ChainRendererData
{
public int modifierOffset;
public float twistAnchor;
public float twist;
public uint usesOrientedParticles;
public Vector4 scale;
public ChainRendererData(int modifierOffset, float twistAnchor, float twist, Vector3 scale, bool usesOrientedParticles)
{
this.modifierOffset = modifierOffset;
this.twistAnchor = twistAnchor;
this.twist = twist;
this.usesOrientedParticles = (uint)(usesOrientedParticles ? 1 : 0);
this.scale = scale;
}
}
public abstract class ObiChainRopeRenderSystem : RenderSystem<ObiRopeChainRenderer>
{
public Oni.RenderingSystemType typeEnum { get => Oni.RenderingSystemType.ChainRope; }
public RendererSet<ObiRopeChainRenderer> renderers { get; } = new RendererSet<ObiRopeChainRenderer>();
// specify vertex count and layout
protected VertexAttributeDescriptor[] layout =
{
new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.Color, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2),
};
static protected ProfilerMarker m_SetupRenderMarker = new ProfilerMarker("SetupChainRopeRendering");
static protected ProfilerMarker m_RenderMarker = new ProfilerMarker("ChainRopeRendering");
protected ObiSolver m_Solver;
protected List<InstancedRenderBatch> batchList = new List<InstancedRenderBatch>();
protected ObiNativeList<ChainRendererData> rendererData;
protected ObiNativeList<ChunkData> chunkData;
protected ObiNativeList<ObiRopeChainRenderer.LinkModifier> modifiers;
protected ObiNativeList<Vector2Int> elements;
protected ObiNativeList<Matrix4x4> instanceTransforms;
protected ObiNativeList<Matrix4x4> invInstanceTransforms;
protected ObiNativeList<Vector4> instanceColors;
public ObiChainRopeRenderSystem(ObiSolver solver)
{
m_Solver = solver;
}
public virtual void Dispose()
{
CleanupBatches();
DestroyLists();
}
private void DestroyLists()
{
if (instanceTransforms != null)
instanceTransforms.Dispose();
if (invInstanceTransforms != null)
invInstanceTransforms.Dispose();
if (instanceColors != null)
instanceColors.Dispose();
if (elements != null)
elements.Dispose();
if (chunkData != null)
chunkData.Dispose();
if (rendererData != null)
rendererData.Dispose();
if (modifiers != null)
modifiers.Dispose();
}
private void CreateListsIfNecessary()
{
DestroyLists();
instanceTransforms = new ObiNativeList<Matrix4x4>();
invInstanceTransforms = new ObiNativeList<Matrix4x4>();
instanceColors = new ObiNativeList<Vector4>();
elements = new ObiNativeList<Vector2Int>();
chunkData = new ObiNativeList<ChunkData>();
rendererData = new ObiNativeList<ChainRendererData>();
modifiers = new ObiNativeList<ObiRopeChainRenderer.LinkModifier>();
}
private void CleanupBatches()
{
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Dispose();
batchList.Clear();
}
private void GenerateBatches()
{
instanceTransforms.Clear();
invInstanceTransforms.Clear();
instanceColors.Clear();
elements.Clear();
rendererData.Clear();
chunkData.Clear();
modifiers.Clear();
// generate batches:
for (int i = 0; i < renderers.Count; ++i)
{
var renderer = renderers[i];
if (renderer.linkMesh != null && renderer.linkMaterial != null)
{
renderer.renderParameters.layer = renderer.gameObject.layer;
batchList.Add(new InstancedRenderBatch(i, renderer.linkMesh, renderer.linkMaterial, renderer.renderParameters));
}
}
// sort batches:
batchList.Sort();
// append elements:
for (int i = 0; i < batchList.Count; ++i)
{
var renderer = renderers[batchList[i].firstRenderer];
var rope = renderer.actor as ObiRopeBase;
modifiers.AddRange(renderer.linkModifiers);
rendererData.Add(new ChainRendererData(modifiers.count, renderer.twistAnchor, renderer.linkTwist, renderer.linkScale, rope.usesOrientedParticles));
batchList[i].firstInstance = elements.count;
batchList[i].instanceCount = rope.elements.Count;
// iterate trough elements, finding discontinuities as we go:
for (int e = 0; e < rope.elements.Count; ++e)
{
elements.Add(new Vector2Int(rope.elements[e].particle1, rope.elements[e].particle2));
// At discontinuities, start a new chunk.
if (e < rope.elements.Count - 1 && rope.elements[e].particle2 != rope.elements[e + 1].particle1)
{
chunkData.Add(new ChunkData(rendererData.count - 1, elements.count));
}
}
chunkData.Add(new ChunkData(rendererData.count - 1, elements.count));
}
instanceTransforms.ResizeUninitialized(elements.count);
invInstanceTransforms.ResizeUninitialized(elements.count);
instanceColors.ResizeUninitialized(elements.count);
}
protected virtual void CloseBatches()
{
// Initialize each batch:
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Initialize();
}
public virtual void Setup()
{
using (m_SetupRenderMarker.Auto())
{
CreateListsIfNecessary();
CleanupBatches();
GenerateBatches();
ObiUtils.MergeBatches(batchList);
CloseBatches();
}
}
public abstract void Render();
public void Step()
{
}
public void BakeMesh(ObiRopeChainRenderer renderer, ref Mesh mesh, bool transformToActorLocalSpace = false)
{
int index = renderers.IndexOf(renderer);
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
if (index >= batch.firstRenderer && index < batch.firstRenderer + batch.rendererCount)
{
batch.BakeMesh(renderers, renderer, chunkData, instanceTransforms,
renderer.actor.actorSolverToLocalMatrix, ref mesh, transformToActorLocalSpace);
return;
}
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9a4cb8b10f8b049c2ae0a97c50c9b33c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,279 +0,0 @@
using System.Runtime.InteropServices;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using Unity.Profiling;
namespace Obi
{
[StructLayout(LayoutKind.Sequential)]
public struct BurstExtrudedMeshData
{
public int sectionVertexCount;
public float thicknessScale;
public float uvAnchor;
public uint normalizeV;
public Vector2 uvScale;
public BurstExtrudedMeshData(ObiRopeExtrudedRenderer renderer)
{
sectionVertexCount = renderer.section.vertices.Count;
uvAnchor = renderer.uvAnchor;
thicknessScale = renderer.thicknessScale;
uvScale = renderer.uvScale;
normalizeV = (uint)(renderer.normalizeV ? 1 : 0);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct ProceduralRopeVertex
{
public Vector3 pos;
public Vector3 normal;
public Vector4 tangent;
public Vector4 color;
public Vector2 uv;
}
public abstract class ObiExtrudedRopeRenderSystem : RenderSystem<ObiRopeExtrudedRenderer>
{
public Oni.RenderingSystemType typeEnum { get => Oni.RenderingSystemType.ExtrudedRope; }
public RendererSet<ObiRopeExtrudedRenderer> renderers { get; } = new RendererSet<ObiRopeExtrudedRenderer>();
protected List<ObiRopeExtrudedRenderer> sortedRenderers = new List<ObiRopeExtrudedRenderer>(); /**< temp list used to store renderers sorted by batch.*/
// specify vertex count and layout
protected VertexAttributeDescriptor[] layout =
{
new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.Color, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2),
};
static protected ProfilerMarker m_SetupRenderMarker = new ProfilerMarker("SetupExtrudedRopeRendering");
static protected ProfilerMarker m_RenderMarker = new ProfilerMarker("ExtrudedRopeRendering");
protected ObiSolver m_Solver;
protected SubMeshDescriptor subMeshDescriptor = new SubMeshDescriptor(0, 0);
protected List<ProceduralRenderBatch<ProceduralRopeVertex>> batchList = new List<ProceduralRenderBatch<ProceduralRopeVertex>>();
protected ObiNativeList<BurstExtrudedMeshData> rendererData; /**< for each renderer, data about smoother.*/
protected ObiNativeList<int> pathSmootherIndices; /**< renderer indices, sorted by batch */
protected Dictionary<ObiRopeSection, int> sectionToIndex = new Dictionary<ObiRopeSection, int>();
protected ObiNativeVector2List sectionData;
protected ObiNativeList<int> sectionOffsets; /**< for each section, offset of its first entry in the sectionData array.*/
protected ObiNativeList<int> sectionIndices; /**< for each renderer, index of the section used.*/
protected ObiNativeList<int> vertexOffsets; /**< for each renderer, vertex offset in its batch mesh data.*/
protected ObiNativeList<int> triangleOffsets; /**< for each renderer, triangle offset in its batch mesh data.*/
protected ObiNativeList<int> vertexCounts; /**< for each renderer, vertex count.*/
protected ObiNativeList<int> triangleCounts; /**< for each renderer, triangle count.*/
protected ObiPathSmootherRenderSystem pathSmootherSystem;
public ObiExtrudedRopeRenderSystem(ObiSolver solver)
{
m_Solver = solver;
rendererData = new ObiNativeList<BurstExtrudedMeshData>();
pathSmootherIndices = new ObiNativeList<int>();
sectionData = new ObiNativeVector2List();
sectionOffsets = new ObiNativeList<int>();
sectionIndices = new ObiNativeList<int>();
vertexOffsets = new ObiNativeList<int>();
triangleOffsets = new ObiNativeList<int>();
vertexCounts = new ObiNativeList<int>();
triangleCounts = new ObiNativeList<int>();
}
public void Dispose()
{
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Dispose();
batchList.Clear();
if (rendererData != null)
rendererData.Dispose();
if (pathSmootherIndices != null)
pathSmootherIndices.Dispose();
if (sectionData != null)
sectionData.Dispose();
if (sectionOffsets != null)
sectionOffsets.Dispose();
if (sectionIndices != null)
sectionIndices.Dispose();
if (vertexOffsets != null)
vertexOffsets.Dispose();
if (triangleOffsets != null)
triangleOffsets.Dispose();
if (vertexCounts != null)
vertexCounts.Dispose();
if (triangleCounts != null)
triangleCounts.Dispose();
}
private void Clear()
{
rendererData.Clear();
pathSmootherIndices.Clear();
sectionData.Clear();
sectionToIndex.Clear();
sectionOffsets.Clear();
sectionIndices.Clear();
vertexOffsets.Clear();
triangleOffsets.Clear();
vertexCounts.Clear();
triangleCounts.Clear();
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Dispose();
batchList.Clear();
}
private void CreateBatches()
{
// generate batches:
sortedRenderers.Clear();
for (int i = 0; i < renderers.Count; ++i)
{
if (renderers[i].section != null && renderers[i].TryGetComponent(out ObiPathSmoother smoother) && smoother.enabled)
{
renderers[i].renderParameters.layer = renderers[i].gameObject.layer;
batchList.Add(new ProceduralRenderBatch<ProceduralRopeVertex>(i, renderers[i].material, renderers[i].renderParameters));
sortedRenderers.Add(renderers[i]);
}
}
vertexOffsets.ResizeUninitialized(sortedRenderers.Count);
triangleOffsets.ResizeUninitialized(sortedRenderers.Count);
// sort batches:
batchList.Sort();
// reorder renderers based on sorted batches:
sortedRenderers.Clear();
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
sortedRenderers.Add(renderers[batch.firstRenderer]);
batch.firstRenderer = i;
int pathIndex = sortedRenderers[i].GetComponent<ObiPathSmoother>().indexInSystem;
pathSmootherIndices.Add(pathIndex);
// get or create extruded section:
if (!sectionToIndex.TryGetValue(sortedRenderers[i].section, out int sectionIndex))
{
sectionIndex = sectionOffsets.count;
sectionToIndex[sortedRenderers[i].section] = sectionIndex;
sectionOffsets.Add(sectionData.count);
sectionData.AddRange(sortedRenderers[i].section.vertices);
}
sectionIndices.Add(sectionIndex);
// calculate vertex and triangle counts for each renderer:
int chunkStart = pathSmootherSystem.chunkOffsets[pathIndex];
int chunkAmount = pathSmootherSystem.chunkOffsets[pathIndex + 1] - chunkStart;
for (int k = chunkStart; k < chunkStart + chunkAmount; ++k)
{
int frameCount = pathSmootherSystem.smoothFrameCounts[k];
batch.vertexCount += frameCount * sortedRenderers[i].section.vertices.Count;
batch.triangleCount += (frameCount - 1) * (sortedRenderers[i].section.vertices.Count - 1) * 2;
}
vertexCounts.Add(batch.vertexCount);
triangleCounts.Add(batch.triangleCount);
rendererData.Add(new BurstExtrudedMeshData(sortedRenderers[i]));
}
// add last entry to section offsets:
sectionOffsets.Add(sectionData.count);
}
private void CalculateMeshOffsets()
{
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
int vtxCount = 0;
int triCount = 0;
// Calculate vertex and triangle offsets for each renderer in the batch:
for (int j = 0; j < batch.rendererCount; ++j)
{
int r = batch.firstRenderer + j;
vertexOffsets[r] = vtxCount;
triangleOffsets[r] = triCount;
vtxCount += vertexCounts[r];
triCount += triangleCounts[r];
}
}
}
public virtual void Setup()
{
pathSmootherSystem = m_Solver.GetRenderSystem<ObiPathSmoother>() as ObiPathSmootherRenderSystem;
if (pathSmootherSystem == null)
return;
using (m_SetupRenderMarker.Auto())
{
Clear();
CreateBatches();
ObiUtils.MergeBatches(batchList);
CalculateMeshOffsets();
}
}
public abstract void Render();
public void Step()
{
}
public void BakeMesh(ObiRopeExtrudedRenderer renderer, ref Mesh mesh, bool transformToActorLocalSpace = false)
{
int index = sortedRenderers.IndexOf(renderer);
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
if (index >= batch.firstRenderer && index < batch.firstRenderer + batch.rendererCount)
{
batch.BakeMesh(vertexOffsets[index], vertexCounts[index], triangleOffsets[index], triangleCounts[index],
renderer.actor.actorSolverToLocalMatrix, ref mesh, transformToActorLocalSpace);
return;
}
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e19ecda6559144921868e71085db8408
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,230 +0,0 @@
using System.Runtime.InteropServices;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using Unity.Profiling;
namespace Obi
{
[StructLayout(LayoutKind.Sequential)]
public struct BurstLineMeshData
{
public Vector2 uvScale;
public float thicknessScale;
public float uvAnchor;
public uint normalizeV;
public BurstLineMeshData(ObiRopeLineRenderer renderer)
{
uvAnchor = renderer.uvAnchor;
thicknessScale = renderer.thicknessScale;
uvScale = renderer.uvScale;
normalizeV = (uint)(renderer.normalizeV ? 1 : 0);
}
}
public abstract class ObiLineRopeRenderSystem : RenderSystem<ObiRopeLineRenderer>
{
public Oni.RenderingSystemType typeEnum { get => Oni.RenderingSystemType.LineRope; }
public RendererSet<ObiRopeLineRenderer> renderers { get; } = new RendererSet<ObiRopeLineRenderer>();
protected List<ObiRopeLineRenderer> sortedRenderers = new List<ObiRopeLineRenderer>();
// specify vertex count and layout
protected VertexAttributeDescriptor[] layout =
{
new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.Color, VertexAttributeFormat.Float32, 4),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2),
};
static protected ProfilerMarker m_SetupRenderMarker = new ProfilerMarker("SetupExtrudedRopeRendering");
static protected ProfilerMarker m_RenderMarker = new ProfilerMarker("ExtrudedRopeRendering");
protected ObiSolver m_Solver;
protected SubMeshDescriptor subMeshDescriptor = new SubMeshDescriptor(0, 0);
protected List<ProceduralRenderBatch<ProceduralRopeVertex>> batchList = new List<ProceduralRenderBatch<ProceduralRopeVertex>>();
protected ObiNativeList<int> pathSmootherIndices;
protected ObiNativeList<BurstLineMeshData> rendererData; /**< for each renderer, data about smoother.*/
protected ObiNativeList<int> vertexOffsets; /**< for each renderer, vertex offset in its batch mesh data.*/
protected ObiNativeList<int> triangleOffsets; /**< for each renderer, triangle offset in its batch mesh data.*/
protected ObiNativeList<int> vertexCounts; /**< for each renderer, vertex count.*/
protected ObiNativeList<int> triangleCounts; /**< for each renderer, triangle count.*/
protected ObiPathSmootherRenderSystem pathSmootherSystem;
#if (UNITY_2019_1_OR_NEWER)
System.Action<ScriptableRenderContext, Camera> renderCallback;
#endif
public ObiLineRopeRenderSystem(ObiSolver solver)
{
#if (UNITY_2019_1_OR_NEWER)
renderCallback = new System.Action<ScriptableRenderContext, Camera>((cntxt, cam) => { RenderFromCamera(cam); });
RenderPipelineManager.beginCameraRendering += renderCallback;
#endif
Camera.onPreCull += RenderFromCamera;
m_Solver = solver;
pathSmootherIndices = new ObiNativeList<int>();
rendererData = new ObiNativeList<BurstLineMeshData>();
vertexOffsets = new ObiNativeList<int>();
triangleOffsets = new ObiNativeList<int>();
vertexCounts = new ObiNativeList<int>();
triangleCounts = new ObiNativeList<int>();
}
public void Dispose()
{
#if (UNITY_2019_1_OR_NEWER)
RenderPipelineManager.beginCameraRendering -= renderCallback;
#endif
Camera.onPreCull -= RenderFromCamera;
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Dispose();
batchList.Clear();
if (pathSmootherIndices != null)
pathSmootherIndices.Dispose();
if (rendererData != null)
rendererData.Dispose();
if (vertexOffsets != null)
vertexOffsets.Dispose();
if (triangleOffsets != null)
triangleOffsets.Dispose();
if (vertexCounts != null)
vertexCounts.Dispose();
if (triangleCounts != null)
triangleCounts.Dispose();
}
private void Clear()
{
pathSmootherIndices.Clear();
rendererData.Clear();
vertexOffsets.Clear();
vertexCounts.Clear();
triangleCounts.Clear();
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Dispose();
batchList.Clear();
}
private void CreateBatches()
{
// generate batches:
sortedRenderers.Clear();
for (int i = 0; i < renderers.Count; ++i)
{
if (renderers[i].TryGetComponent(out ObiPathSmoother smoother) && smoother.enabled)
{
renderers[i].renderParams.layer = renderers[i].gameObject.layer;
batchList.Add(new ProceduralRenderBatch<ProceduralRopeVertex>(i, renderers[i].material, renderers[i].renderParams));
sortedRenderers.Add(renderers[i]);
}
}
vertexOffsets.ResizeUninitialized(sortedRenderers.Count);
triangleOffsets.ResizeUninitialized(sortedRenderers.Count);
// sort batches:
batchList.Sort();
// reorder renderers based on sorted batches:
sortedRenderers.Clear();
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
sortedRenderers.Add(renderers[batch.firstRenderer]);
batch.firstRenderer = i;
int pathIndex = sortedRenderers[i].GetComponent<ObiPathSmoother>().indexInSystem;
pathSmootherIndices.Add(pathIndex);
// calculate vertex and triangle counts for each renderer:
int chunkStart = pathSmootherSystem.chunkOffsets[pathIndex];
int chunkAmount = pathSmootherSystem.chunkOffsets[pathIndex + 1] - chunkStart;
for (int k = chunkStart; k < chunkStart + chunkAmount; ++k)
{
int frameCount = pathSmootherSystem.smoothFrameCounts[k];
batch.vertexCount += frameCount * 2; // in a triangle strip, there's 2 vertices per frame.
batch.triangleCount += (frameCount - 1) * 2; // and 2 triangles per frame (except for the last one)
}
vertexCounts.Add(batch.vertexCount);
triangleCounts.Add(batch.triangleCount);
rendererData.Add(new BurstLineMeshData(sortedRenderers[i]));
}
}
private void CalculateMeshOffsets()
{
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
int vtxCount = 0;
int triCount = 0;
// Calculate vertex and triangle offsets for each renderer in the batch:
for (int j = 0; j < batch.rendererCount; ++j)
{
int r = batch.firstRenderer + j;
vertexOffsets[r] = vtxCount;
triangleOffsets[r] = triCount;
vtxCount += vertexCounts[r];
triCount += triangleCounts[r];
}
}
}
public virtual void Setup()
{
pathSmootherSystem = m_Solver.GetRenderSystem<ObiPathSmoother>() as ObiPathSmootherRenderSystem;
if (pathSmootherSystem == null)
return;
using (m_SetupRenderMarker.Auto())
{
Clear();
CreateBatches();
ObiUtils.MergeBatches(batchList);
CalculateMeshOffsets();
}
}
public abstract void RenderFromCamera(Camera camera);
public abstract void Render();
public void Step()
{
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: feb78fd6bed7a49979dee4205d74deaa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,296 +0,0 @@
using System.Runtime.InteropServices;
using UnityEngine;
using Unity.Profiling;
using UnityEngine.Rendering;
using System.Collections.Generic;
using System;
namespace Obi
{
[StructLayout(LayoutKind.Sequential)]
public struct BurstMeshData
{
public uint axis;
public float volumeScaling;
public uint stretchWithRope;
public uint spanEntireLength;
public uint instances;
public float instanceSpacing;
public float offset;
public float meshSizeAlongAxis;
public Vector4 scale;
public BurstMeshData(ObiRopeMeshRenderer renderer)
{
axis = (uint)renderer.axis;
volumeScaling = renderer.volumeScaling;
stretchWithRope = (uint)(renderer.stretchWithRope ? 1 : 0);
spanEntireLength = (uint)(renderer.spanEntireLength ? 1 : 0);
instances = renderer.instances;
instanceSpacing = renderer.instanceSpacing;
offset = renderer.offset;
meshSizeAlongAxis = renderer.sourceMesh != null ? renderer.sourceMesh.bounds.size[(int)renderer.axis] : 0;
scale = renderer.scale;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct RopeMeshVertex
{
public Vector3 pos;
public Vector3 normal;
public Vector4 tangent;
public Vector4 color;
}
public abstract class ObiMeshRopeRenderSystem : RenderSystem<ObiRopeMeshRenderer>
{
public Oni.RenderingSystemType typeEnum { get => Oni.RenderingSystemType.MeshRope; }
public RendererSet<ObiRopeMeshRenderer> renderers { get; } = new RendererSet<ObiRopeMeshRenderer>();
protected List<ObiRopeMeshRenderer> sortedRenderers = new List<ObiRopeMeshRenderer>(); /**< temp list used to store renderers sorted by batch.*/
static protected ProfilerMarker m_SetupRenderMarker = new ProfilerMarker("SetupMeshRopeRendering");
static protected ProfilerMarker m_RenderMarker = new ProfilerMarker("MeshRopeRendering");
// specify vertex count and layout
protected VertexAttributeDescriptor[] layout =
{
new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3,0),
new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3,0),
new VertexAttributeDescriptor(VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4,0),
new VertexAttributeDescriptor(VertexAttribute.Color, VertexAttributeFormat.Float32, 4,0),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2,1),
new VertexAttributeDescriptor(VertexAttribute.TexCoord1, VertexAttributeFormat.Float32, 2,1),
new VertexAttributeDescriptor(VertexAttribute.TexCoord2, VertexAttributeFormat.Float32, 2,1),
new VertexAttributeDescriptor(VertexAttribute.TexCoord3, VertexAttributeFormat.Float32, 2,1),
};
protected ObiSolver m_Solver;
protected List<DynamicRenderBatch<ObiRopeMeshRenderer>> batchList = new List<DynamicRenderBatch<ObiRopeMeshRenderer>>();
protected MeshDataBatch meshData;
protected ObiNativeList<int> meshIndices; // for each renderer, its mesh index.
protected ObiNativeList<int> pathSmootherIndices; /**< for each renderer, index of its path smoother in the path smoother system.*/
protected ObiNativeList<BurstMeshData> rendererData;
protected ObiNativeList<int> sortedIndices; /**< axis-sorted vertex indices. */
protected ObiNativeList<int> sortedOffsets; /**< for each renderer, offset in the sortedIndices array.*/
protected ObiNativeList<int> vertexOffsets; /**< for each renderer, vertex offset in its batch mesh data.*/
protected ObiNativeList<int> vertexCounts; /**< for each renderer, vertex count.*/
protected ObiPathSmootherRenderSystem pathSmootherSystem;
public ObiMeshRopeRenderSystem(ObiSolver solver)
{
m_Solver = solver;
meshData = new MeshDataBatch();
meshIndices = new ObiNativeList<int>();
pathSmootherIndices = new ObiNativeList<int>();
rendererData = new ObiNativeList<BurstMeshData>();
sortedIndices = new ObiNativeList<int>();
sortedOffsets = new ObiNativeList<int>();
vertexOffsets = new ObiNativeList<int>();
vertexCounts = new ObiNativeList<int>();
}
public void Dispose()
{
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Dispose();
batchList.Clear();
meshData.Dispose();
if (pathSmootherIndices != null)
pathSmootherIndices.Dispose();
if (meshIndices != null)
meshIndices.Dispose();
if (sortedIndices != null)
sortedIndices.Dispose();
if (sortedOffsets != null)
sortedOffsets.Dispose();
if (vertexOffsets != null)
vertexOffsets.Dispose();
if (vertexCounts != null)
vertexCounts.Dispose();
if (rendererData != null)
rendererData.Dispose();
}
private void Clear()
{
meshData.Clear();
meshIndices.Clear();
pathSmootherIndices.Clear();
rendererData.Clear();
vertexOffsets.Clear();
vertexCounts.Clear();
sortedIndices.Clear();
sortedOffsets.Clear();
for (int i = 0; i < batchList.Count; ++i)
batchList[i].Dispose();
batchList.Clear();
meshData.InitializeStaticData();
meshData.InitializeTempData();
}
private void CreateBatches()
{
// generate batches:
sortedRenderers.Clear();
for (int i = 0; i < renderers.Count; ++i)
{
if (renderers[i].sourceMesh != null && renderers[i].TryGetComponent(out ObiPathSmoother smoother) && smoother.enabled)
{
int vertexCount = renderers[i].vertexCount * (int)renderers[i].meshInstances;
renderers[i].renderParameters.layer = renderers[i].gameObject.layer;
batchList.Add(new DynamicRenderBatch<ObiRopeMeshRenderer>(i, vertexCount, renderers[i].materials, renderers[i].renderParameters));
sortedRenderers.Add(renderers[i]);
}
}
vertexOffsets.ResizeUninitialized(sortedRenderers.Count);
// sort batches:
batchList.Sort();
// reorder renderers based on sorted batches:
sortedRenderers.Clear();
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
// store amount of vertices in this batch, prior to merging:
vertexCounts.Add(batch.vertexCount);
// write renderers in the order dictated by the sorted batch:
sortedRenderers.Add(renderers[batch.firstRenderer]);
batch.firstRenderer = i;
pathSmootherIndices.Add(sortedRenderers[i].GetComponent<ObiPathSmoother>().indexInSystem);
rendererData.Add(new BurstMeshData(sortedRenderers[i]));
}
}
protected virtual void PopulateBatches()
{
List<Vector3> verts = new List<Vector3>();
// store per-mesh data
for (int i = 0; i < sortedRenderers.Count; ++i)
{
// sort vertices along curve axis:
sortedRenderers[i].GetVertices(verts);
float[] keys = new float[sortedRenderers[i].vertexCount];
var orderedVertices = new int[sortedRenderers[i].vertexCount];
for (int j = 0; j < keys.Length; ++j)
{
keys[j] = verts[j][(int)sortedRenderers[i].axis];
orderedVertices[j] = j;
}
Array.Sort(keys, orderedVertices);
sortedOffsets.Add(sortedIndices.count);
sortedIndices.AddRange(orderedVertices);
// add mesh index
meshIndices.Add(meshData.AddMesh(sortedRenderers[i]));
}
}
private void CalculateMeshOffsets()
{
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
int vtxCount = 0;
// Calculate vertex and triangle offsets for each renderer in the batch:
for (int j = 0; j < batch.rendererCount; ++j)
{
int r = batch.firstRenderer + j;
vertexOffsets[r] = vtxCount;
vtxCount += vertexCounts[r];
}
}
}
protected virtual void CloseBatches()
{
meshData.DisposeOfStaticData();
meshData.DisposeOfTempData();
}
public void Setup()
{
pathSmootherSystem = m_Solver.GetRenderSystem<ObiPathSmoother>() as ObiPathSmootherRenderSystem;
if (pathSmootherSystem == null)
return;
using (m_SetupRenderMarker.Auto())
{
Clear();
CreateBatches();
PopulateBatches();
ObiUtils.MergeBatches(batchList);
CalculateMeshOffsets();
CloseBatches();
}
}
public void Step()
{
}
public virtual void Render()
{
}
public void BakeMesh(ObiRopeMeshRenderer renderer, ref Mesh mesh, bool transformToActorLocalSpace = false)
{
int index = sortedRenderers.IndexOf(renderer);
for (int i = 0; i < batchList.Count; ++i)
{
var batch = batchList[i];
if (index >= batch.firstRenderer && index < batch.firstRenderer + batch.rendererCount)
{
batch.BakeMesh(sortedRenderers, renderer, ref mesh, transformToActorLocalSpace);
return;
}
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ad311e324f23a480d867e8e9b7f89cfe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,325 +0,0 @@
using System.Runtime.InteropServices;
using UnityEngine;
using Unity.Profiling;
namespace Obi
{
[StructLayout(LayoutKind.Sequential)]
public struct BurstPathSmootherData
{
public uint smoothing;
public float decimation;
public float twist;
public float restLength;
public float smoothLength;
public uint usesOrientedParticles;
public BurstPathSmootherData(ObiRopeBase rope, ObiPathSmoother smoother)
{
smoothing = smoother.smoothing;
decimation = smoother.decimation;
twist = smoother.twist;
usesOrientedParticles = (uint)(rope.usesOrientedParticles ? 1 : 0);
restLength = rope.restLength;
smoothLength = 0;
}
}
public abstract class ObiPathSmootherRenderSystem : RenderSystem<ObiPathSmoother>
{
public Oni.RenderingSystemType typeEnum { get => Oni.RenderingSystemType.AllSmoothedRopes; }
public RendererSet<ObiPathSmoother> renderers { get; } = new RendererSet<ObiPathSmoother>();
static protected ProfilerMarker m_SetupRenderMarker = new ProfilerMarker("SetupSmoothPathRendering");
static protected ProfilerMarker m_RenderMarker = new ProfilerMarker("SmoothPathRendering");
protected ObiSolver m_Solver;
public ObiNativeList<int> particleIndices;
public ObiNativeList<int> chunkOffsets; /**< for each actor, index of the first chunk */
public ObiNativeList<BurstPathSmootherData> pathData; /**< for each chunk, smoother params/data.*/
public ObiNativeList<ObiPathFrame> rawFrames;
public ObiNativeList<int> rawFrameOffsets; /**< index of the first frame for each chunk.*/
public ObiNativeList<int> decimatedFrameCounts; /**< amount of frames in each chunk, after decimation.*/
public ObiNativeList<ObiPathFrame> smoothFrames;
public ObiNativeList<int> smoothFrameOffsets; /**< index of the first frame for each chunk.*/
public ObiNativeList<int> smoothFrameCounts; /**< amount of smooth frames for each chunk.*/
// path smoothing must be done before all other rope render systems, which are on a higher tier.
public uint tier
{
get { return 0; }
}
public ObiPathSmootherRenderSystem(ObiSolver solver)
{
m_Solver = solver;
pathData = new ObiNativeList<BurstPathSmootherData>();
particleIndices = new ObiNativeList<int>();
chunkOffsets = new ObiNativeList<int>();
rawFrames = new ObiNativeList<ObiPathFrame>();
rawFrameOffsets = new ObiNativeList<int>();
decimatedFrameCounts = new ObiNativeList<int>();
smoothFrames = new ObiNativeList<ObiPathFrame>();
smoothFrameOffsets = new ObiNativeList<int>();
smoothFrameCounts = new ObiNativeList<int>();
}
public void Dispose()
{
if (particleIndices != null)
particleIndices.Dispose();
if (chunkOffsets != null)
chunkOffsets.Dispose();
if (pathData != null)
pathData.Dispose();
if (rawFrames != null)
rawFrames.Dispose();
if (rawFrameOffsets != null)
rawFrameOffsets.Dispose();
if (decimatedFrameCounts != null)
decimatedFrameCounts.Dispose();
if (smoothFrames != null)
smoothFrames.Dispose();
if (smoothFrameOffsets != null)
smoothFrameOffsets.Dispose();
if (smoothFrameCounts != null)
smoothFrameCounts.Dispose();
}
private void Clear()
{
pathData.Clear();
particleIndices.Clear();
chunkOffsets.Clear();
rawFrames.Clear();
rawFrameOffsets.Clear();
decimatedFrameCounts.Clear();
smoothFrames.Clear();
smoothFrameOffsets.Clear();
smoothFrameCounts.Clear();
}
private int GetChaikinCount(int initialPoints, uint recursionLevel)
{
if (recursionLevel <= 0 || initialPoints < 3)
return initialPoints;
// calculate amount of new points generated by each inner control point:
int pCount = (int)Mathf.Pow(2, recursionLevel);
return (initialPoints - 2) * pCount + 2;
}
public virtual void Setup()
{
using (m_SetupRenderMarker.Auto())
{
Clear();
int actorCount = 0;
int chunkCount = 0;
int rawFrameCount = 0;
for (int i = 0; i < renderers.Count; ++i)
{
var renderer = renderers[i];
var rope = renderer.actor as ObiRopeBase;
var data = new BurstPathSmootherData(rope, renderer);
chunkOffsets.Add(chunkCount);
// iterate trough elements, finding discontinuities as we go:
for (int e = 0; e < rope.elements.Count; ++e)
{
rawFrameCount++;
particleIndices.Add(rope.elements[e].particle1);
// At discontinuities, start a new chunk.
if (e < rope.elements.Count - 1 && rope.elements[e].particle2 != rope.elements[e + 1].particle1)
{
rawFrameOffsets.Add(++rawFrameCount);
particleIndices.Add(rope.elements[e].particle2);
pathData.Add(data);
chunkCount++;
}
}
chunkCount++;
rawFrameOffsets.Add(++rawFrameCount);
particleIndices.Add(rope.elements[rope.elements.Count - 1].particle2);
pathData.Add(data);
// store the index in this system, so that other render systems
// in higher tiers can easily access smooth path data:
renderer.indexInSystem = actorCount++;
}
// Add last entry (total amount of chunks):
chunkOffsets.Add(chunkCount);
// resize storage:
rawFrames.ResizeUninitialized(rawFrameCount);
decimatedFrameCounts.ResizeUninitialized(rawFrameOffsets.count);
smoothFrameOffsets.ResizeUninitialized(rawFrameOffsets.count);
smoothFrameCounts.ResizeUninitialized(rawFrameOffsets.count);
// calculate smooth chunk counts:
int smoothFrameCount = 0;
for (int i = 0; i < rawFrameOffsets.count; ++i)
{
int frameCount = rawFrameOffsets[i] - (i > 0 ? rawFrameOffsets[i - 1] : 0);
int smoothCount = GetChaikinCount(frameCount, pathData[i].smoothing);
smoothFrameOffsets[i] = smoothFrameCount;
smoothFrameCounts[i] = smoothCount;
smoothFrameCount += smoothCount;
}
smoothFrames.ResizeUninitialized(smoothFrameCount);
}
}
public int GetChunkCount(int rendererIndex)
{
rendererIndex = Mathf.Clamp(rendererIndex, 0, renderers.Count);
if (rendererIndex >= chunkOffsets.count)
return 0;
return chunkOffsets[rendererIndex + 1] - chunkOffsets[rendererIndex];
}
public int GetSmoothFrameCount(int rendererIndex)
{
rendererIndex = Mathf.Clamp(rendererIndex, 0, renderers.Count);
int frameCount = 0;
if (rendererIndex >= chunkOffsets.count)
return frameCount;
for (int i = chunkOffsets[rendererIndex]; i < chunkOffsets[rendererIndex + 1]; ++i)
frameCount += smoothFrameCounts[i];
return frameCount;
}
public int GetSmoothFrameCount(int rendererIndex, int chunkIndex)
{
rendererIndex = Mathf.Clamp(rendererIndex, 0, renderers.Count);
if (rendererIndex >= chunkOffsets.count)
return 0;
int chunkCount = chunkOffsets[rendererIndex + 1] - chunkOffsets[rendererIndex];
int chunk = chunkOffsets[rendererIndex] + Mathf.Clamp(chunkIndex, 0, chunkCount);
return smoothFrameCounts[chunk];
}
public float GetSmoothLength(int rendererIndex)
{
rendererIndex = Mathf.Clamp(rendererIndex, 0, renderers.Count);
float smoothLength = 0;
if (rendererIndex >= chunkOffsets.count)
return smoothLength;
for (int i = chunkOffsets[rendererIndex]; i < chunkOffsets[rendererIndex + 1]; ++i)
smoothLength += pathData[i].smoothLength;
return smoothLength;
}
public ObiPathFrame GetFrameAt(int rendererIndex, int chunkIndex, int frameIndex)
{
rendererIndex = Mathf.Clamp(rendererIndex, 0, renderers.Count);
if (rendererIndex >= chunkOffsets.count)
return ObiPathFrame.Identity;
int chunkCount = chunkOffsets[rendererIndex + 1] - chunkOffsets[rendererIndex];
int chunk = chunkOffsets[rendererIndex] + Mathf.Clamp(chunkIndex, 0, chunkCount);
return smoothFrames[smoothFrameOffsets[chunk] + Mathf.Clamp(frameIndex, 0, smoothFrameCounts[chunk])];
}
public ObiPathFrame GetFrameAt(int rendererIndex, float mu)
{
rendererIndex = Mathf.Clamp(rendererIndex, 0, renderers.Count);
if (rendererIndex >= chunkOffsets.count)
return ObiPathFrame.Identity;
float length = 0;
for (int i = chunkOffsets[rendererIndex]; i < chunkOffsets[rendererIndex + 1]; ++i)
length += pathData[i].smoothLength;
length *= mu;
// iterate trough all chunks:
float lerp = 0;
int frame = 0;
for (int i = chunkOffsets[rendererIndex]; i < chunkOffsets[rendererIndex + 1]; ++i)
{
int firstFrame = smoothFrameOffsets[i];
int frameCount = smoothFrameCounts[i];
// iterate trough all frames in this chunk, accumulating distance:
for (int j = firstFrame + 1; j < firstFrame + frameCount; ++j)
{
float frameDistance = Vector3.Distance(smoothFrames[j - 1].position,
smoothFrames[j].position);
lerp = length / frameDistance;
length -= frameDistance;
frame = j;
if (length <= 0)
return (1 - lerp) * smoothFrames[j - 1] + lerp * smoothFrames[j];
}
}
// if no chunks/no frames, return default frame.
return (1 - lerp) * smoothFrames[frame - 1] + lerp * smoothFrames[frame];
}
public void Step()
{
}
public virtual void Render()
{
// Update rest lengths, in case they've changed due to cursors:
for (int i = 0; i < renderers.Count; ++i)
{
var rope = renderers[i].actor as ObiRopeBase;
for (int j = chunkOffsets[i]; j < chunkOffsets[i + 1]; ++j)
{
var data = pathData[j];
data.restLength = rope.restLength;
pathData[j] = data;
}
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fab1fee6e450d4e28a7a2770af3c94d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,79 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Unity.Profiling;
namespace Obi
{
[AddComponentMenu("Physics/Obi/Obi Rope Chain Renderer", 885)]
[ExecuteInEditMode]
public class ObiRopeChainRenderer : MonoBehaviour, ObiActorRenderer<ObiRopeChainRenderer>
{
[Serializable]
public struct LinkModifier
{
public Vector3 translation;
public Vector3 scale;
public Vector3 rotation;
public void Clear()
{
translation = Vector3.zero;
scale = Vector3.one;
rotation = Vector3.zero;
}
}
public Mesh linkMesh;
public Material linkMaterial;
public Vector3 linkScale = Vector3.one; /**< Scale of chain links.*/
[Range(0, 1)]
public float twistAnchor = 0; /**< Normalized position of twisting origin along rope.*/
public float linkTwist = 0; /**< Amount of twist applied to each section, in degrees.*/
public List<LinkModifier> linkModifiers = new List<LinkModifier>();
public RenderBatchParams renderParameters = new RenderBatchParams(true);
public ObiActor actor { get; private set; }
void Awake()
{
actor = GetComponent<ObiActor>();
}
public void OnEnable()
{
((ObiActorRenderer<ObiRopeChainRenderer>)this).EnableRenderer();
}
public void OnDisable()
{
((ObiActorRenderer<ObiRopeChainRenderer>)this).DisableRenderer();
}
public void OnValidate()
{
((ObiActorRenderer<ObiRopeChainRenderer>)this).SetRendererDirty(Oni.RenderingSystemType.ChainRope);
}
RenderSystem<ObiRopeChainRenderer> ObiRenderer<ObiRopeChainRenderer>.CreateRenderSystem(ObiSolver solver)
{
switch (solver.backendType)
{
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
case ObiSolver.BackendType.Burst: return new BurstChainRopeRenderSystem(solver);
#endif
case ObiSolver.BackendType.Compute:
default:
if (SystemInfo.supportsComputeShaders)
return new ComputeChainRopeRenderSystem(solver);
return null;
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 09ac962c0743c400aa230ebf871b6156
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 1289c40ad0e7c4fb3bd738f8a3f3e068, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,74 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using Unity.Profiling;
namespace Obi
{
[AddComponentMenu("Physics/Obi/Obi Rope Extruded Renderer", 883)]
[ExecuteInEditMode]
[RequireComponent(typeof(ObiPathSmoother))]
public class ObiRopeExtrudedRenderer : MonoBehaviour, ObiActorRenderer<ObiRopeExtrudedRenderer>
{
public ObiPathSmoother smoother { get; private set; } // Each renderer should have its own smoother. The renderer then has a method to get position and orientation at a point.
public Material material;
public RenderBatchParams renderParameters = new RenderBatchParams(true);
[Range(0, 1)]
public float uvAnchor = 0; /**< Normalized position of texture coordinate origin along rope.*/
public Vector2 uvScale = Vector2.one; /**< Scaling of uvs along rope.*/
public bool normalizeV = true;
public ObiRopeSection section = null; /**< Section asset to be extruded along the rope.*/
public float thicknessScale = 0.8f; /**< Scales section thickness.*/
public ObiActor actor { get; private set; }
public void Awake()
{
actor = GetComponent<ObiActor>();
}
public void OnEnable()
{
smoother = GetComponent<ObiPathSmoother>();
((ObiActorRenderer<ObiRopeExtrudedRenderer>)this).EnableRenderer();
}
public void OnDisable()
{
((ObiActorRenderer<ObiRopeExtrudedRenderer>)this).DisableRenderer();
}
public void OnValidate()
{
((ObiActorRenderer<ObiRopeExtrudedRenderer>)this).SetRendererDirty(Oni.RenderingSystemType.AllSmoothedRopes);
}
RenderSystem<ObiRopeExtrudedRenderer> ObiRenderer<ObiRopeExtrudedRenderer>.CreateRenderSystem(ObiSolver solver)
{
switch (solver.backendType)
{
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
case ObiSolver.BackendType.Burst: return new BurstExtrudedRopeRenderSystem(solver);
#endif
case ObiSolver.BackendType.Compute:
default:
if (SystemInfo.supportsComputeShaders)
return new ComputeExtrudedRopeRenderSystem(solver);
return null;
}
}
}
}

View File

@@ -1,13 +0,0 @@
fileFormatVersion: 2
guid: c4747da60837c44f9ba4b4a86879bcc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- extrudedMesh: {instanceID: 0}
- section: {fileID: 11400000, guid: a0bc36a59515f413e90e10895929c938, type: 2}
executionOrder: 0
icon: {fileID: 2800000, guid: a552ed0e1c0fd47c38eeff6d60b5b115, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,68 +0,0 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using Unity.Profiling;
namespace Obi
{
[AddComponentMenu("Physics/Obi/Obi Rope Line Renderer", 884)]
[ExecuteInEditMode]
[RequireComponent(typeof(ObiPathSmoother))]
public class ObiRopeLineRenderer : MonoBehaviour, ObiActorRenderer<ObiRopeLineRenderer>
{
public ObiActor actor { get; private set; }
public Material material;
public RenderBatchParams renderParams = new RenderBatchParams(true);
[Range(0, 1)]
public float uvAnchor = 0; /**< Normalized position of texture coordinate origin along rope.*/
public Vector2 uvScale = Vector2.one; /**< Scaling of uvs along rope.*/
public bool normalizeV = true;
public float thicknessScale = 0.8f; /**< Scales section thickness.*/
public void Awake()
{
actor = GetComponent<ObiActor>();
}
void OnEnable()
{
((ObiActorRenderer<ObiRopeLineRenderer>)this).EnableRenderer();
}
void OnDisable()
{
((ObiActorRenderer<ObiRopeLineRenderer>)this).DisableRenderer();
}
public void OnValidate()
{
((ObiActorRenderer<ObiRopeLineRenderer>)this).SetRendererDirty(Oni.RenderingSystemType.LineRope);
}
RenderSystem<ObiRopeLineRenderer> ObiRenderer<ObiRopeLineRenderer>.CreateRenderSystem(ObiSolver solver)
{
switch (solver.backendType)
{
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
case ObiSolver.BackendType.Burst: return new BurstLineRopeRenderSystem(solver);
#endif
case ObiSolver.BackendType.Compute:
default:
if (SystemInfo.supportsComputeShaders)
return new ComputeLineRopeRenderSystem(solver);
return null;
}
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 18f853588397d4a80a561203ed92fc8a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 905a18c273af443d6bc588b59ebd56f6, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,86 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace Obi
{
[AddComponentMenu("Physics/Obi/Obi Rope Mesh Renderer", 886)]
[ExecuteInEditMode]
[RequireComponent(typeof(ObiPathSmoother))]
public class ObiRopeMeshRenderer : MonoBehaviour, ObiActorRenderer<ObiRopeMeshRenderer>, IMeshDataProvider
{
public Renderer sourceRenderer { get; protected set; }
public ObiActor actor { get; private set; }
public uint meshInstances { get {return instances;} }
[field: SerializeField]
public Mesh sourceMesh { get; set; }
[field: SerializeField]
public Material[] materials { get; set; }
public virtual int vertexCount { get { return sourceMesh ? sourceMesh.vertexCount : 0; } }
public virtual int triangleCount { get { return sourceMesh ? sourceMesh.triangles.Length / 3 : 0; } }
public RenderBatchParams renderParameters = new RenderBatchParams(true);
public ObiPathFrame.Axis axis;
public float volumeScaling = 0;
public bool stretchWithRope = true;
public bool spanEntireLength = true;
public uint instances = 1;
public float instanceSpacing = 0;
public float offset = 0;
public Vector3 scale = Vector3.one;
public void Awake()
{
actor = GetComponent<ObiActor>();
sourceRenderer = GetComponent<MeshRenderer>();
}
public void OnEnable()
{
((ObiActorRenderer<ObiRopeMeshRenderer>)this).EnableRenderer();
}
public void OnDisable()
{
((ObiActorRenderer<ObiRopeMeshRenderer>)this).DisableRenderer();
}
public void OnValidate()
{
((ObiActorRenderer<ObiRopeMeshRenderer>)this).SetRendererDirty(Oni.RenderingSystemType.MeshRope);
}
RenderSystem<ObiRopeMeshRenderer> ObiRenderer<ObiRopeMeshRenderer>.CreateRenderSystem(ObiSolver solver)
{
switch (solver.backendType)
{
#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
case ObiSolver.BackendType.Burst: return new BurstMeshRopeRenderSystem(solver);
#endif
case ObiSolver.BackendType.Compute:
default:
if (SystemInfo.supportsComputeShaders)
return new ComputeMeshRopeRenderSystem(solver);
return null;
}
}
public virtual void GetVertices(List<Vector3> vertices) { sourceMesh.GetVertices(vertices); }
public virtual void GetNormals(List<Vector3> normals) { sourceMesh.GetNormals(normals); }
public virtual void GetTangents(List<Vector4> tangents) { sourceMesh.GetTangents(tangents); }
public virtual void GetColors(List<Color> colors) { sourceMesh.GetColors(colors); }
public virtual void GetUVs(int channel, List<Vector2> uvs) { sourceMesh.GetUVs(channel, uvs); }
public virtual void GetTriangles(List<int> triangles) { triangles.Clear(); triangles.AddRange(sourceMesh.triangles); }
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4ec7e70e3318044b69e11352b1f2136b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: c5afdc6c291b44a68be8bf66702358a5, type: 3}
userData:
assetBundleName:
assetBundleVariant: