在我的應用程式中,用戶可以將物件放入場景中。每個物件都有一個背景網格,由程式計算和添加。因此放置的物件存盤為元組串列:
public List<Tuple<GameObject, GameObject>> PlacedObjects;
用戶還會得到一個“清除”按鈕來洗掉物件,如下所示:
foreach (var placedObject in PlacedObjects)
{
Destroy(placedObject.Item1);
Destroy(placedObject.Item2);
}
PlacedObjects.Clear();
由于某種原因,Item1被洗掉,但Item2在場景中仍然可見。我猜,一定有一些泄漏或參考可以防止資料被破壞?
無論如何要獲得全貌,這里是資料的生成方式。首先,用戶可以放置一個專案(從下拉選擇中復制),這將按如下方式完成:
public void OnPlaceHereButtonPressed()
{
var clone = Instantiate(currentlySelectedObject);
clone.GetComponentInChildren<MeshFilter>().mesh = Instantiate(currentlySelectedObject.GetComponentInChildren<MeshFilter>().mesh);
// Clone the material for each item
Material cloneMat = new Material(currentlySelectedObject.GetComponentInChildren<Renderer>().material);
if (currentlySelectedObject.tag.Equals(paramSphere)) // Spheres get random colors after placing
cloneMat.SetColor("_BaseColor", Random.ColorHSV());
clone.GetComponentInChildren<Renderer>().material = cloneMat;
PlacedObjects.Add(new Tuple<GameObject, GameObject>(clone, null));
SendVirtualObjectsToServer(clone);
SetCameraBackgroundShader(true);
}
Item2有點復雜,因為它來自服務器的結果資料。大部分只是將傳入的資料流轉換為網格資料:
// this is done for each of the placed objects after getting the result
if (hasReconstrucedData)
{
var reconstructed = new GameObject("Reconstructed Mesh " i.ToString(), typeof(MeshFilter), typeof(MeshRenderer));
reconstructed.transform.position = new Vector3(0, 0, 0);
reconstructed.transform.localScale = new Vector3(1, -1, 1);
reconstructed.isStatic = true;
Mesh mesh = new Mesh();
// vertices
int vertexBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
mesh.vertices = nativeBuffer.GetSubArray(bufferOffset, vertexBufferSize).Reinterpret<Vector3>(vertexBufferSize / 12).ToArray();
bufferOffset = vertexBufferSize;
// normals
int vertexNormalsBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
mesh.normals = nativeBuffer.GetSubArray(bufferOffset, vertexNormalsBufferSize).Reinterpret<Vector3>(vertexNormalsBufferSize / 12).ToArray();
bufferOffset = vertexNormalsBufferSize;
// colors
int vertexColorsBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
mesh.colors = nativeBuffer.GetSubArray(bufferOffset, vertexColorsBufferSize).Reinterpret<Color>(vertexNormalsBufferSize / 16).ToArray();
bufferOffset = vertexColorsBufferSize;
// triangles
int trianglesBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
mesh.triangles = nativeBuffer.GetSubArray(bufferOffset, trianglesBufferSize).Reinterpret<int>(trianglesBufferSize / 4).ToArray();
bufferOffset = trianglesBufferSize;
// sh probes
int reconstructedProbeBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
// set material and probe texture for reconstructed mesh
Material reconstructedMat = new Material(Shader.Find("Custom/Differential"));
rows = (int)Math.Ceiling((float)reconstructedProbeBufferSize / (float)cols);
recbuffer = new NativeArray<float>(cols * rows, Allocator.TempJob);
// only needed to fill up the complete texture
recbuffer.CopyFrom(nativeBuffer.GetSubArray(bufferOffset, reconstructedProbeBufferSize).Reinterpret<float>(reconstructedProbeBufferSize / 4));
bufferOffset = reconstructedProbeBufferSize;
Texture2D shEnvTexture = new Texture2D(cols, rows, TextureFormat.RFloat, false);
shEnvTexture.LoadRawTextureData(recbuffer);
shEnvTexture.filterMode = FilterMode.Point;
shEnvTexture.wrapMode = TextureWrapMode.Clamp;
shEnvTexture.Apply(updateMipmaps: false);
reconstructedMat.SetTexture("_SHTexture", shEnvTexture);
float[] objectPos = new float[3]
{
PlacedObjects[i].Item1.transform.position.x,
PlacedObjects[i].Item1.transform.position.y,
PlacedObjects[i].Item1.transform.position.z
};
reconstructedMat.SetFloatArray("_ObjectPosition", objectPos);
reconstructedMat.SetFloat("_ObjectScale",
(PlacedObjects[i].Item1.transform.localScale * differentialShaderScaleFactor).magnitude);
reconstructed.GetComponentInChildren<Renderer>().material = reconstructedMat;
reconstructed.GetComponent<MeshFilter>().mesh = mesh;
PlacedObjects[i] = Tuple.Create(PlacedObjects[i].Item1, reconstructed);
}
這些都是在串列中添加或洗掉資料的地方。為什么該Destroy()功能不適用于第二項?
uj5u.com熱心網友回復:
終于找到了這個問題,這個問題隱藏的很好。問題不在于 destroy 函式不起作用,而是Item2每次服務器發送新結果時都會創建一個新物件而不清理現有物件。
將相應的代碼更改為以下內容后:
if (hasReconstrucedData)
{
if(PlacedObjects[i].Item2 == null)
PlacedObjects[i] = Tuple.Create(PlacedObjects[i].Item1, new GameObject("Reconstructed Mesh " i.ToString(), typeof(MeshFilter), typeof(MeshRenderer)));
PlacedObjects[i].Item2.transform.position = new Vector3(0, 0, 0);
PlacedObjects[i].Item2.transform.localScale = new Vector3(1, -1, 1);
PlacedObjects[i].Item2.isStatic = true;
Mesh mesh = new Mesh();
// vertices
int vertexBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
mesh.vertices = nativeBuffer.GetSubArray(bufferOffset, vertexBufferSize).Reinterpret<Vector3>(vertexBufferSize / 12).ToArray();
bufferOffset = vertexBufferSize;
// normals
int vertexNormalsBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
mesh.normals = nativeBuffer.GetSubArray(bufferOffset, vertexNormalsBufferSize).Reinterpret<Vector3>(vertexNormalsBufferSize / 12).ToArray();
bufferOffset = vertexNormalsBufferSize;
// colors
int vertexColorsBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
mesh.colors = nativeBuffer.GetSubArray(bufferOffset, vertexColorsBufferSize).Reinterpret<Color>(vertexNormalsBufferSize / 16).ToArray();
bufferOffset = vertexColorsBufferSize;
// triangles
int trianglesBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
mesh.triangles = nativeBuffer.GetSubArray(bufferOffset, trianglesBufferSize).Reinterpret<int>(trianglesBufferSize / 4).ToArray();
bufferOffset = trianglesBufferSize;
// sh probes
int reconstructedProbeBufferSize = BitConverter.ToInt32(data, bufferOffset);
bufferOffset = sizeof(int);
// set material and probe texture for reconstructed mesh
Material reconstructedMat = new Material(Shader.Find("Custom/Differential"));
rows = (int)Math.Ceiling((float)reconstructedProbeBufferSize / (float)cols);
recbuffer = new NativeArray<float>(cols * rows, Allocator.TempJob);
// only needed to fill up the complete texture
recbuffer.CopyFrom(nativeBuffer.GetSubArray(bufferOffset, reconstructedProbeBufferSize).Reinterpret<float>(reconstructedProbeBufferSize / 4));
bufferOffset = reconstructedProbeBufferSize;
Texture2D shEnvTexture = new Texture2D(cols, rows, TextureFormat.RFloat, false);
shEnvTexture.LoadRawTextureData(recbuffer);
shEnvTexture.filterMode = FilterMode.Point;
shEnvTexture.wrapMode = TextureWrapMode.Clamp;
shEnvTexture.Apply(updateMipmaps: false);
reconstructedMat.SetTexture("_SHTexture", shEnvTexture);
reconstructedMat.SetFloatArray("_SHEnvironmentProbe", lightProbeValues);
float[] objectPos = new float[3]
{
PlacedObjects[i].Item1.transform.position.x,
PlacedObjects[i].Item1.transform.position.y,
PlacedObjects[i].Item1.transform.position.z
};
reconstructedMat.SetFloatArray("_ObjectPosition", objectPos);
reconstructedMat.SetFloat("_ObjectScale",
(PlacedObjects[i].Item1.transform.localScale * differentialShaderScaleFactor).magnitude);
PlacedObjects[i].Item2.GetComponentInChildren<Renderer>().material = reconstructedMat;
PlacedObjects[i].Item2.GetComponent<MeshFilter>().mesh = mesh;
}
我猜,在正常情況下,人們會很容易看到多個物體,因為我猜會發生 z-fighting。然而,這里這些物件用于 AR 系統的差分渲染(即將虛擬物件的陰影渲染到現實世界的風景上),因此它們大部分是透明的,為了除錯,我只是在著色器中將輸出顏色更改為紅色。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/403256.html
標籤:
上一篇:預制不是原始的直接副本
