Skip to content

Commit

Permalink
Reverted PinnedList changes from dev branch.
Browse files Browse the repository at this point in the history
found an issue where meshes with changing topology have indices referencing out of bounds vertices.
  • Loading branch information
Thomasch-unity3d committed Dec 7, 2017
1 parent 1d5d966 commit 9929eab
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 371 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Reflection;
using UnityEngine;
#if UNITY_EDITOR
Expand All @@ -17,6 +18,11 @@ public class AlembicExporter : MonoBehaviour
{
#region impl

public static IntPtr GetArrayPtr(Array v)
{
return Marshal.UnsafeAddrOfPinnedArrayElement(v, 0);
}

public static void CaptureTransform(
AbcAPI.aeObject abc, Transform trans,
bool inherits, bool invertForward, bool scale)
Expand Down Expand Up @@ -60,44 +66,34 @@ public static void CaptureCamera(AbcAPI.aeObject abc, Camera cam, AlembicCameraP

public class MeshBuffer
{
public PinnedList<int> indices = new PinnedList<int>();
public PinnedList<Vector3> vertices = new PinnedList<Vector3>();
public PinnedList<Vector3> normals = new PinnedList<Vector3>();
public PinnedList<Vector2> uvs = new PinnedList<Vector2>();

public void Clear()
{
indices.Clear();
vertices.Clear();
normals.Clear();
uvs.Clear();
}
public int[] indices;
public Vector3[] vertices;
public Vector3[] normals;
public Vector2[] uvs;
}

public static void CaptureMesh(AbcAPI.aeObject abc, Mesh mesh, Cloth cloth, MeshBuffer dst_buf)
{
dst_buf.Clear();
dst_buf.indices.LockList(ls => mesh.GetTriangles(ls, 0));
dst_buf.uvs.LockList(ls => mesh.GetUVs(0, ls));

dst_buf.indices = mesh.triangles;
dst_buf.uvs = mesh.uv;
if (cloth == null)
{
dst_buf.vertices.LockList(ls => mesh.GetVertices(ls));
dst_buf.normals.LockList(ls => mesh.GetNormals(ls));
dst_buf.vertices = mesh.vertices;
dst_buf.normals = mesh.normals;
}
else
{
dst_buf.vertices.Assign(cloth.vertices);
dst_buf.normals.Assign(cloth.normals);
dst_buf.vertices = cloth.vertices;
dst_buf.normals = cloth.normals;
}

var data = new AbcAPI.aePolyMeshData();
data.indices = dst_buf.indices;
data.positions = dst_buf.vertices;
data.normals = dst_buf.normals;
data.uvs = dst_buf.uvs;
data.positionCount = dst_buf.vertices.Count;
data.indexCount = dst_buf.indices.Count;
data.indices = GetArrayPtr(dst_buf.indices);
data.positions = GetArrayPtr(dst_buf.vertices);
if(dst_buf.normals != null) { data.normals = GetArrayPtr(dst_buf.normals); }
if(dst_buf.uvs != null) { data.uvs = GetArrayPtr(dst_buf.uvs); }
data.positionCount = dst_buf.vertices.Length;
data.indexCount = dst_buf.indices.Length;

AbcAPI.aePolyMeshWriteSample(abc, ref data);
}
Expand Down Expand Up @@ -258,8 +254,8 @@ public class ParticleCapturer : ComponentCapturer
AbcAPI.aeProperty m_prop_rotatrions;

ParticleSystem.Particle[] m_buf_particles;
PinnedList<Vector3> m_buf_positions = new PinnedList<Vector3>();
PinnedList<Vector4> m_buf_rotations = new PinnedList<Vector4>();
Vector3[] m_buf_positions;
Vector4[] m_buf_rotations;

public ParticleCapturer(ComponentCapturer parent, ParticleSystem target)
: base(parent)
Expand All @@ -284,14 +280,14 @@ public override void Capture()
if (m_buf_particles == null)
{
m_buf_particles = new ParticleSystem.Particle[count_max];
m_buf_positions.Resize(count_max);
m_buf_rotations.Resize(count_max);
m_buf_positions = new Vector3[count_max];
m_buf_rotations = new Vector4[count_max];
}
else if (m_buf_particles.Length != count_max)
{
Array.Resize(ref m_buf_particles, count_max);
m_buf_positions.Resize(count_max);
m_buf_rotations.Resize(count_max);
Array.Resize(ref m_buf_positions, count_max);
Array.Resize(ref m_buf_rotations, count_max);
}

// copy particle positions & rotations to buffer
Expand All @@ -302,16 +298,16 @@ public override void Capture()
}
for (int i = 0; i < count; ++i)
{
var a = m_buf_particles[i].axisOfRotation;
m_buf_rotations[i].Set(a.x, a.y, a.z, m_buf_particles[i].rotation);
m_buf_rotations[i] = m_buf_particles[i].axisOfRotation;
m_buf_rotations[i].w = m_buf_particles[i].rotation;
}

// write!
var data = new AbcAPI.aePointsData();
data.positions = m_buf_positions;
data.positions = GetArrayPtr(m_buf_positions);
data.count = count;
AbcAPI.aePointsWriteSample(m_abc, ref data);
AbcAPI.aePropertyWriteArraySample(m_prop_rotatrions, m_buf_rotations, count);
AbcAPI.aePropertyWriteArraySample(m_prop_rotatrions, GetArrayPtr(m_buf_rotations), count);
}
}

Expand Down Expand Up @@ -854,4 +850,4 @@ void OnDisable()
EndCapture();
}
}
}
}
120 changes: 72 additions & 48 deletions AlembicImporter/Assets/UTJ/Alembic/Scripts/Importer/AlembicMesh.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Rendering;

Expand All @@ -9,13 +10,13 @@ public class AlembicMesh : AlembicElement
{
public class Split
{
public PinnedList<Vector3> positionCache = new PinnedList<Vector3>();
public PinnedList<Vector3> normalCache = new PinnedList<Vector3>();
public PinnedList<Vector3> velocitiesCache = new PinnedList<Vector3>();
public PinnedList<Vector2> velocitiesXYCache = new PinnedList<Vector2>();
public PinnedList<Vector2> velocitiesZCache = new PinnedList<Vector2>();
public PinnedList<Vector2> uvCache = new PinnedList<Vector2>();
public PinnedList<Vector4> tangentCache = new PinnedList<Vector4>();
public Vector3[] positionCache;
public Vector3[] normalCache;
public Vector3[] velocitiesCache;
public Vector2[] velocitiesXYCache;
public Vector2[] velocitiesZCache;
public Vector2[] uvCache;
public Vector4[] tangentCache;
public Mesh mesh;
public GameObject host;

Expand All @@ -29,7 +30,7 @@ public class Split

public class Submesh
{
public PinnedList<int> indexCache = new PinnedList<int>();
public int[] indexCache;
public int facesetIndex;
public int splitIndex;
public int index;
Expand All @@ -44,9 +45,14 @@ public class Submesh
public List<Split> splits = new List<Split>();

public AbcAPI.aiMeshSummary summary;
AbcAPI.aiMeshSampleSummary m_SampleSummary;
public AbcAPI.aiMeshSampleSummary sampleSummary;
bool m_FreshSetup = false;

public static IntPtr GetArrayPtr(Array a)
{
return Marshal.UnsafeAddrOfPinnedArrayElement(a, 0);
}

void UpdateSplits(int numSplits)
{
Split split = null;
Expand All @@ -59,8 +65,17 @@ void UpdateSplits(int numSplits)
{
split = new Split
{
positionCache = new Vector3[0],
normalCache = new Vector3[0],
uvCache = new Vector2[0],
tangentCache = new Vector4[0],
mesh = null,
host = null,
clear = true,
submeshCount = 0,
active = true,
center = Vector3.zero,
size = Vector3.zero
};

splits.Add(split);
Expand All @@ -77,9 +92,17 @@ void UpdateSplits(int numSplits)
{
split = new Split
{
positionCache = new Vector3[0],
normalCache = new Vector3[0],
uvCache = new Vector2[0],
tangentCache = new Vector4[0],
mesh = null,
host = AlembicTreeNode.linkedGameObj,
clear = true,
submeshCount = 0,
active = true,
center = Vector3.zero,
size = Vector3.zero
};

splits.Add(split);
Expand Down Expand Up @@ -148,13 +171,13 @@ public override void AbcSampleUpdated(AbcAPI.aiSample sample, bool topologyChang
m_FreshSetup = false;
}

AbcAPI.aiPolyMeshGetSampleSummary(sample, ref m_SampleSummary, topologyChanged);
AbcAPI.aiPolyMeshGetSampleSummary(sample, ref sampleSummary, topologyChanged);

AbcAPI.aiPolyMeshData vertexData = default(AbcAPI.aiPolyMeshData);

UpdateSplits(m_SampleSummary.splitCount);
UpdateSplits(sampleSummary.splitCount);

for (int s = 0; s < m_SampleSummary.splitCount; ++s)
for (int s=0; s<sampleSummary.splitCount; ++s)
{
Split split = splits[s];

Expand All @@ -163,51 +186,51 @@ public override void AbcSampleUpdated(AbcAPI.aiSample sample, bool topologyChang

int vertexCount = AbcAPI.aiPolyMeshGetVertexBufferLength(sample, s);

split.positionCache.ResizeDiscard(vertexCount);
vertexData.positions = split.positionCache;
Array.Resize(ref split.positionCache, vertexCount);
vertexData.positions = GetArrayPtr(split.positionCache);

if (m_SampleSummary.hasVelocities)
if (sampleSummary.hasVelocities)
{
split.velocitiesCache.ResizeDiscard(vertexCount);
vertexData.velocities = split.velocitiesCache;

split.velocitiesXYCache.ResizeDiscard(vertexCount);
vertexData.interpolatedVelocitiesXY = split.velocitiesXYCache;

split.velocitiesZCache.ResizeDiscard(vertexCount);
vertexData.interpolatedVelocitiesZ = split.velocitiesZCache;
Array.Resize(ref split.velocitiesCache, vertexCount);
vertexData.velocities = GetArrayPtr(split.velocitiesCache);

Array.Resize(ref split.velocitiesXYCache, vertexCount);
vertexData.interpolatedVelocitiesXY = GetArrayPtr(split.velocitiesXYCache);
Array.Resize(ref split.velocitiesZCache, vertexCount);
vertexData.interpolatedVelocitiesZ = GetArrayPtr(split.velocitiesZCache);
}

if (m_SampleSummary.hasNormals)
if (sampleSummary.hasNormals)
{
split.normalCache.ResizeDiscard(vertexCount);
vertexData.normals = split.normalCache;
Array.Resize(ref split.normalCache, vertexCount);
vertexData.normals = GetArrayPtr(split.normalCache);
}
else
{
split.normalCache.ResizeDiscard(0);
Array.Resize(ref split.normalCache, 0);
vertexData.normals = IntPtr.Zero;
}

if (m_SampleSummary.hasUVs)
if (sampleSummary.hasUVs)
{
split.uvCache.ResizeDiscard(vertexCount);
vertexData.uvs = split.uvCache;
Array.Resize(ref split.uvCache, vertexCount);
vertexData.uvs = GetArrayPtr(split.uvCache);
}
else
{
split.uvCache.ResizeDiscard(0);
Array.Resize(ref split.uvCache, 0);
vertexData.uvs = IntPtr.Zero;
}

if (m_SampleSummary.hasTangents)
if (sampleSummary.hasTangents)
{
split.tangentCache.ResizeDiscard(vertexCount);
vertexData.tangents = split.tangentCache;
Array.Resize(ref split.tangentCache, vertexCount);
vertexData.tangents = GetArrayPtr(split.tangentCache);
}
else
{
split.tangentCache.ResizeDiscard(0);
Array.Resize(ref split.tangentCache, 0);
vertexData.tangents = IntPtr.Zero;
}

Expand Down Expand Up @@ -235,7 +258,7 @@ public override void AbcSampleUpdated(AbcAPI.aiSample sample, bool topologyChang
submeshes.RemoveRange(numSubmeshes, submeshes.Count - numSubmeshes);
}

for (int s=0; s<m_SampleSummary.splitCount; ++s)
for (int s=0; s<sampleSummary.splitCount; ++s)
{
splits[s].submeshCount = AbcAPI.aiPolyMeshGetSplitSubmeshCount(sample, s);
}
Expand All @@ -258,6 +281,7 @@ public override void AbcSampleUpdated(AbcAPI.aiSample sample, bool topologyChang
{
submesh = new Submesh
{
indexCache = new int[0],
facesetIndex = -1,
splitIndex = -1,
index = -1,
Expand All @@ -272,8 +296,9 @@ public override void AbcSampleUpdated(AbcAPI.aiSample sample, bool topologyChang
submesh.index = submeshSummary.splitSubmeshIndex;
submesh.update = true;

submesh.indexCache.ResizeDiscard(3 * submeshSummary.triangleCount);
submeshData.indices = submesh.indexCache;
Array.Resize(ref submesh.indexCache, 3 * submeshSummary.triangleCount);

submeshData.indices = GetArrayPtr(submesh.indexCache);

AbcAPI.aiPolyMeshFillSubmeshIndices(sample, ref submeshSummary, ref submeshData);
}
Expand Down Expand Up @@ -301,7 +326,7 @@ public override void AbcUpdate()
return;
}

bool useSubObjects = (summary.topologyVariance == AbcAPI.aiTopologyVariance.Heterogeneous || m_SampleSummary.splitCount > 1);
bool useSubObjects = (summary.topologyVariance == AbcAPI.aiTopologyVariance.Heterogeneous || sampleSummary.splitCount > 1);

for (int s=0; s<splits.Count; ++s)
{
Expand Down Expand Up @@ -349,13 +374,12 @@ public override void AbcUpdate()
split.mesh.Clear();
}

split.mesh.SetVertices(split.positionCache);
if (split.normalCache.Count > 0) split.mesh.SetNormals(split.normalCache);
if (split.tangentCache.Count > 0) split.mesh.SetTangents(split.tangentCache);
if (split.uvCache.Count > 0) split.mesh.SetUVs(0, split.uvCache);
if (split.velocitiesXYCache.Count > 0) split.mesh.SetUVs(2, split.velocitiesXYCache);
if (split.velocitiesZCache.Count > 0) split.mesh.SetUVs(3, split.velocitiesZCache);

split.mesh.vertices = split.positionCache;
split.mesh.normals = split.normalCache;
split.mesh.tangents = split.tangentCache;
split.mesh.uv3 = split.velocitiesXYCache;
split.mesh.uv4 = split.velocitiesZCache;
split.mesh.uv = split.uvCache;
// update the bounds
split.mesh.bounds = new Bounds(split.center, split.size);

Expand Down Expand Up @@ -416,9 +440,9 @@ public override void AbcUpdate()
}
}

if (!m_SampleSummary.hasNormals && !m_SampleSummary.hasTangents)
if (!sampleSummary.hasNormals && !sampleSummary.hasTangents)
{
for (int s=0; s<m_SampleSummary.splitCount; ++s)
for (int s=0; s<sampleSummary.splitCount; ++s)
{
splits[s].mesh.RecalculateNormals();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ public void AbcLoad(bool createMissingNodes=false)
m_Context = AbcAPI.aiCreateContext(alembicTreeRoot.linkedGameObj.GetInstanceID());
m_Loaded = AbcAPI.aiLoad(m_Context,m_StreamDesc.pathToAbc);



if (m_Loaded)
{
var settings = m_StreamDesc.settings;
Expand Down

0 comments on commit 9929eab

Please sign in to comment.