去掉obi,使用自写绳索
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a4cb8b10f8b049c2ae0a97c50c9b33c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e19ecda6559144921868e71085db8408
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: feb78fd6bed7a49979dee4205d74deaa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad311e324f23a480d867e8e9b7f89cfe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fab1fee6e450d4e28a7a2770af3c94d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -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); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
Reference in New Issue
Block a user