Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/OvrAvatarAssetMesh.cs
2026-02-21 16:45:37 +08:00

229 lines
9.2 KiB
C#

using System;
using System.Runtime.InteropServices;
using Oculus.Avatar;
using UnityEngine;
public class OvrAvatarAssetMesh : OvrAvatarAsset
{
public Mesh mesh;
private ovrAvatarSkinnedMeshPose skinnedBindPose;
public string[] jointNames;
public OvrAvatarAssetMesh(ulong _assetId, IntPtr asset, ovrAvatarAssetType meshType)
{
assetID = _assetId;
mesh = new Mesh();
mesh.name = "Procedural Geometry for asset " + _assetId;
SetSkinnedBindPose(asset, meshType);
long vertexCount = 0L;
IntPtr vertexBuffer = IntPtr.Zero;
uint indexCount = 0u;
IntPtr indexBuffer = IntPtr.Zero;
GetVertexAndIndexData(asset, meshType, out vertexCount, out vertexBuffer, out indexCount, out indexBuffer);
Vector3[] array = new Vector3[vertexCount];
Vector3[] array2 = new Vector3[vertexCount];
Vector4[] array3 = new Vector4[vertexCount];
Vector2[] array4 = new Vector2[vertexCount];
Color[] array5 = new Color[vertexCount];
BoneWeight[] array6 = new BoneWeight[vertexCount];
long num = vertexBuffer.ToInt64();
switch (meshType)
{
case ovrAvatarAssetType.Mesh:
{
long num5 = Marshal.SizeOf(typeof(ovrAvatarMeshVertex));
for (long num6 = 0L; num6 < vertexCount; num6++)
{
long num7 = num5 * num6;
ovrAvatarMeshVertex ovrAvatarMeshVertex2 = (ovrAvatarMeshVertex)Marshal.PtrToStructure(new IntPtr(num + num7), typeof(ovrAvatarMeshVertex));
array[num6] = new Vector3(ovrAvatarMeshVertex2.x, ovrAvatarMeshVertex2.y, 0f - ovrAvatarMeshVertex2.z);
array2[num6] = new Vector3(ovrAvatarMeshVertex2.nx, ovrAvatarMeshVertex2.ny, 0f - ovrAvatarMeshVertex2.nz);
array3[num6] = new Vector4(ovrAvatarMeshVertex2.tx, ovrAvatarMeshVertex2.ty, 0f - ovrAvatarMeshVertex2.tz, ovrAvatarMeshVertex2.tw);
array4[num6] = new Vector2(ovrAvatarMeshVertex2.u, ovrAvatarMeshVertex2.v);
array5[num6] = new Color(0f, 0f, 0f, 1f);
array6[num6].boneIndex0 = ovrAvatarMeshVertex2.blendIndices[0];
array6[num6].boneIndex1 = ovrAvatarMeshVertex2.blendIndices[1];
array6[num6].boneIndex2 = ovrAvatarMeshVertex2.blendIndices[2];
array6[num6].boneIndex3 = ovrAvatarMeshVertex2.blendIndices[3];
array6[num6].weight0 = ovrAvatarMeshVertex2.blendWeights[0];
array6[num6].weight1 = ovrAvatarMeshVertex2.blendWeights[1];
array6[num6].weight2 = ovrAvatarMeshVertex2.blendWeights[2];
array6[num6].weight3 = ovrAvatarMeshVertex2.blendWeights[3];
}
break;
}
case ovrAvatarAssetType.CombinedMesh:
{
long num2 = Marshal.SizeOf(typeof(ovrAvatarMeshVertexV2));
for (long num3 = 0L; num3 < vertexCount; num3++)
{
long num4 = num2 * num3;
ovrAvatarMeshVertexV2 ovrAvatarMeshVertexV3 = (ovrAvatarMeshVertexV2)Marshal.PtrToStructure(new IntPtr(num + num4), typeof(ovrAvatarMeshVertexV2));
array[num3] = new Vector3(ovrAvatarMeshVertexV3.x, ovrAvatarMeshVertexV3.y, 0f - ovrAvatarMeshVertexV3.z);
array2[num3] = new Vector3(ovrAvatarMeshVertexV3.nx, ovrAvatarMeshVertexV3.ny, 0f - ovrAvatarMeshVertexV3.nz);
array3[num3] = new Vector4(ovrAvatarMeshVertexV3.tx, ovrAvatarMeshVertexV3.ty, 0f - ovrAvatarMeshVertexV3.tz, ovrAvatarMeshVertexV3.tw);
array4[num3] = new Vector2(ovrAvatarMeshVertexV3.u, ovrAvatarMeshVertexV3.v);
array5[num3] = new Color(ovrAvatarMeshVertexV3.r, ovrAvatarMeshVertexV3.g, ovrAvatarMeshVertexV3.b, ovrAvatarMeshVertexV3.a);
array6[num3].boneIndex0 = ovrAvatarMeshVertexV3.blendIndices[0];
array6[num3].boneIndex1 = ovrAvatarMeshVertexV3.blendIndices[1];
array6[num3].boneIndex2 = ovrAvatarMeshVertexV3.blendIndices[2];
array6[num3].boneIndex3 = ovrAvatarMeshVertexV3.blendIndices[3];
array6[num3].weight0 = ovrAvatarMeshVertexV3.blendWeights[0];
array6[num3].weight1 = ovrAvatarMeshVertexV3.blendWeights[1];
array6[num3].weight2 = ovrAvatarMeshVertexV3.blendWeights[2];
array6[num3].weight3 = ovrAvatarMeshVertexV3.blendWeights[3];
}
break;
}
default:
throw new Exception("Bad Mesh Asset Type");
}
mesh.vertices = array;
mesh.normals = array2;
mesh.uv = array4;
mesh.tangents = array3;
mesh.boneWeights = array6;
mesh.colors = array5;
LoadBlendShapes(asset, vertexCount);
LoadSubmeshes(asset, indexBuffer, indexCount);
uint jointCount = skinnedBindPose.jointCount;
jointNames = new string[jointCount];
for (uint num8 = 0u; num8 < jointCount; num8++)
{
jointNames[num8] = Marshal.PtrToStringAnsi(skinnedBindPose.jointNames[num8]);
}
}
private void LoadSubmeshes(IntPtr asset, IntPtr indexBufferPtr, ulong indexCount)
{
uint num = CAPI.ovrAvatarAsset_GetSubmeshCount(asset);
short[] array = new short[indexCount];
Marshal.Copy(indexBufferPtr, array, 0, (int)indexCount);
mesh.subMeshCount = (int)num;
uint num2 = 0u;
for (uint num3 = 0u; num3 < num; num3++)
{
uint num4 = CAPI.ovrAvatarAsset_GetSubmeshLastIndex(asset, num3);
uint num5 = num4 - num2;
int[] array2 = new int[num5];
int num6 = 0;
for (ulong num7 = num2; num7 < num4; num7 += 3)
{
array2[num6 + 2] = array[num7];
array2[num6 + 1] = array[num7 + 1];
array2[num6] = array[num7 + 2];
num6 += 3;
}
num2 += num5;
mesh.SetIndices(array2, MeshTopology.Triangles, (int)num3);
}
}
private void LoadBlendShapes(IntPtr asset, long vertexCount)
{
uint num = CAPI.ovrAvatarAsset_GetMeshBlendShapeCount(asset);
IntPtr intPtr = CAPI.ovrAvatarAsset_GetMeshBlendShapeVertices(asset);
if (!(intPtr != IntPtr.Zero))
{
return;
}
long num2 = 0L;
long num3 = Marshal.SizeOf(typeof(ovrAvatarBlendVertex));
long num4 = intPtr.ToInt64();
for (uint num5 = 0u; num5 < num; num5++)
{
Vector3[] array = new Vector3[vertexCount];
Vector3[] array2 = new Vector3[vertexCount];
Vector3[] array3 = new Vector3[vertexCount];
for (long num6 = 0L; num6 < vertexCount; num6++)
{
ovrAvatarBlendVertex ovrAvatarBlendVertex2 = (ovrAvatarBlendVertex)Marshal.PtrToStructure(new IntPtr(num4 + num2), typeof(ovrAvatarBlendVertex));
array[num6] = new Vector3(ovrAvatarBlendVertex2.x, ovrAvatarBlendVertex2.y, 0f - ovrAvatarBlendVertex2.z);
array2[num6] = new Vector3(ovrAvatarBlendVertex2.nx, ovrAvatarBlendVertex2.ny, 0f - ovrAvatarBlendVertex2.nz);
array3[num6] = new Vector4(ovrAvatarBlendVertex2.tx, ovrAvatarBlendVertex2.ty, 0f - ovrAvatarBlendVertex2.tz);
num2 += num3;
}
IntPtr ptr = CAPI.ovrAvatarAsset_GetMeshBlendShapeName(asset, num5);
string shapeName = Marshal.PtrToStringAnsi(ptr);
mesh.AddBlendShapeFrame(shapeName, 100f, array, array2, array3);
}
}
private void SetSkinnedBindPose(IntPtr asset, ovrAvatarAssetType meshType)
{
switch (meshType)
{
case ovrAvatarAssetType.Mesh:
skinnedBindPose = CAPI.ovrAvatarAsset_GetMeshData(asset).skinnedBindPose;
break;
case ovrAvatarAssetType.CombinedMesh:
skinnedBindPose = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).skinnedBindPose;
break;
}
}
private void GetVertexAndIndexData(IntPtr asset, ovrAvatarAssetType meshType, out long vertexCount, out IntPtr vertexBuffer, out uint indexCount, out IntPtr indexBuffer)
{
vertexCount = 0L;
vertexBuffer = IntPtr.Zero;
indexCount = 0u;
indexBuffer = IntPtr.Zero;
switch (meshType)
{
case ovrAvatarAssetType.Mesh:
vertexCount = CAPI.ovrAvatarAsset_GetMeshData(asset).vertexCount;
vertexBuffer = CAPI.ovrAvatarAsset_GetMeshData(asset).vertexBuffer;
indexCount = CAPI.ovrAvatarAsset_GetMeshData(asset).indexCount;
indexBuffer = CAPI.ovrAvatarAsset_GetMeshData(asset).indexBuffer;
break;
case ovrAvatarAssetType.CombinedMesh:
vertexCount = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).vertexCount;
vertexBuffer = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).vertexBuffer;
indexCount = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).indexCount;
indexBuffer = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).indexBuffer;
break;
}
}
public SkinnedMeshRenderer CreateSkinnedMeshRendererOnObject(GameObject target)
{
SkinnedMeshRenderer skinnedMeshRenderer = target.AddComponent<SkinnedMeshRenderer>();
skinnedMeshRenderer.sharedMesh = mesh;
mesh.name = "AvatarMesh_" + assetID;
uint jointCount = skinnedBindPose.jointCount;
GameObject[] array = new GameObject[jointCount];
Transform[] array2 = new Transform[jointCount];
Matrix4x4[] array3 = new Matrix4x4[jointCount];
for (uint num = 0u; num < jointCount; num++)
{
array[num] = new GameObject();
array2[num] = array[num].transform;
array[num].name = jointNames[num];
int num2 = skinnedBindPose.jointParents[num];
if (num2 == -1)
{
array[num].transform.parent = skinnedMeshRenderer.transform;
skinnedMeshRenderer.rootBone = array[num].transform;
}
else
{
array[num].transform.parent = array[num2].transform;
}
Vector3 position = skinnedBindPose.jointTransform[num].position;
position.z = 0f - position.z;
array[num].transform.localPosition = position;
Quaternion orientation = skinnedBindPose.jointTransform[num].orientation;
orientation.x = 0f - orientation.x;
orientation.y = 0f - orientation.y;
array[num].transform.localRotation = orientation;
array[num].transform.localScale = skinnedBindPose.jointTransform[num].scale;
array3[num] = array[num].transform.worldToLocalMatrix * skinnedMeshRenderer.transform.localToWorldMatrix;
}
skinnedMeshRenderer.bones = array2;
mesh.bindposes = array3;
return skinnedMeshRenderer;
}
}