添加插件
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user