180 lines
5.7 KiB
C#
180 lines
5.7 KiB
C#
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
* All rights reserved.
|
|
*
|
|
* Licensed under the Oculus SDK License Agreement (the "License");
|
|
* you may not use the Oculus SDK except in compliance with the License,
|
|
* which is provided at the time of installation or download, or which
|
|
* otherwise accompanies this software in either electronic or hard copy form.
|
|
*
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* https://developer.oculus.com/licenses/oculussdk/
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, the Oculus SDK
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
using Unity.Collections;
|
|
using Unity.Jobs;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
public class OVRMesh : MonoBehaviour
|
|
{
|
|
public interface IOVRMeshDataProvider
|
|
{
|
|
MeshType GetMeshType();
|
|
}
|
|
|
|
public enum MeshType
|
|
{
|
|
None = OVRPlugin.MeshType.None,
|
|
HandLeft = OVRPlugin.MeshType.HandLeft,
|
|
HandRight = OVRPlugin.MeshType.HandRight,
|
|
}
|
|
|
|
[SerializeField]
|
|
private IOVRMeshDataProvider _dataProvider;
|
|
|
|
[SerializeField]
|
|
private MeshType _meshType = MeshType.None;
|
|
|
|
private Mesh _mesh;
|
|
|
|
public bool IsInitialized { get; private set; }
|
|
|
|
public Mesh Mesh
|
|
{
|
|
get => _mesh;
|
|
}
|
|
|
|
internal void SetMeshType(MeshType type)
|
|
{
|
|
_meshType = type;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (_dataProvider == null)
|
|
{
|
|
_dataProvider = GetComponent<IOVRMeshDataProvider>();
|
|
}
|
|
|
|
if (_dataProvider != null)
|
|
{
|
|
_meshType = _dataProvider.GetMeshType();
|
|
}
|
|
|
|
if (ShouldInitialize())
|
|
{
|
|
Initialize(_meshType);
|
|
}
|
|
}
|
|
|
|
private bool ShouldInitialize()
|
|
{
|
|
if (IsInitialized)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (_meshType == MeshType.None)
|
|
{
|
|
return false;
|
|
}
|
|
else if (_meshType == MeshType.HandLeft || _meshType == MeshType.HandRight)
|
|
{
|
|
#if UNITY_EDITOR
|
|
return OVRInput.IsControllerConnected(OVRInput.Controller.Hands);
|
|
#else
|
|
return true;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private void Initialize(MeshType meshType)
|
|
{
|
|
_mesh = new Mesh();
|
|
if (OVRPlugin.GetMesh((OVRPlugin.MeshType)_meshType, out var ovrpMesh))
|
|
{
|
|
TransformOvrpMesh(ovrpMesh, _mesh);
|
|
IsInitialized = true;
|
|
}
|
|
}
|
|
|
|
private void TransformOvrpMesh(OVRPlugin.Mesh ovrpMesh, Mesh mesh)
|
|
{
|
|
int numVertices = (int)ovrpMesh.NumVertices;
|
|
int numIndices = (int)ovrpMesh.NumIndices;
|
|
|
|
using (var verticesNativeArray =
|
|
new OVRMeshJobs.NativeArrayHelper<OVRPlugin.Vector3f>(ovrpMesh.VertexPositions, numVertices))
|
|
using (var normalsNativeArray =
|
|
new OVRMeshJobs.NativeArrayHelper<OVRPlugin.Vector3f>(ovrpMesh.VertexNormals, numVertices))
|
|
using (var uvNativeArray =
|
|
new OVRMeshJobs.NativeArrayHelper<OVRPlugin.Vector2f>(ovrpMesh.VertexUV0, numVertices))
|
|
using (var weightsNativeArray =
|
|
new OVRMeshJobs.NativeArrayHelper<OVRPlugin.Vector4f>(ovrpMesh.BlendWeights, numVertices))
|
|
using (var indicesNativeArray =
|
|
new OVRMeshJobs.NativeArrayHelper<OVRPlugin.Vector4s>(ovrpMesh.BlendIndices, numVertices))
|
|
using (var trianglesNativeArray = new OVRMeshJobs.NativeArrayHelper<short>(ovrpMesh.Indices, numIndices))
|
|
using (var vertices = new NativeArray<Vector3>(numVertices, Allocator.TempJob))
|
|
using (var normals = new NativeArray<Vector3>(numVertices, Allocator.TempJob))
|
|
using (var uv = new NativeArray<Vector2>(numVertices, Allocator.TempJob))
|
|
using (var boneWeights = new NativeArray<BoneWeight>(numVertices, Allocator.TempJob))
|
|
using (var triangles = new NativeArray<uint>(numIndices, Allocator.TempJob))
|
|
{
|
|
var job = new OVRMeshJobs.TransformToUnitySpaceJob
|
|
{
|
|
Vertices = vertices,
|
|
Normals = normals,
|
|
UV = uv,
|
|
BoneWeights = boneWeights,
|
|
MeshVerticesPosition = verticesNativeArray.UnityNativeArray,
|
|
MeshNormals = normalsNativeArray.UnityNativeArray,
|
|
MeshUV = uvNativeArray.UnityNativeArray,
|
|
MeshBoneWeights = weightsNativeArray.UnityNativeArray,
|
|
MeshBoneIndices = indicesNativeArray.UnityNativeArray
|
|
};
|
|
|
|
var jobTransformTriangle = new OVRMeshJobs.TransformTrianglesJob
|
|
{
|
|
Triangles = triangles,
|
|
MeshIndices = trianglesNativeArray.UnityNativeArray,
|
|
NumIndices = numIndices
|
|
};
|
|
|
|
var handle = job.Schedule(numVertices, 20);
|
|
var handleTriangleJob = jobTransformTriangle.Schedule(numIndices, 60);
|
|
JobHandle.CombineDependencies(handle, handleTriangleJob).Complete();
|
|
|
|
mesh.SetVertices(job.Vertices);
|
|
mesh.SetNormals(job.Normals);
|
|
mesh.SetUVs(0, job.UV);
|
|
mesh.boneWeights = job.BoneWeights.ToArray();
|
|
|
|
mesh.SetIndexBufferParams(numIndices, IndexFormat.UInt32);
|
|
mesh.SetIndexBufferData(jobTransformTriangle.Triangles, 0, 0, numIndices);
|
|
mesh.SetSubMesh(0, new SubMeshDescriptor(0, numIndices));
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
private void Update()
|
|
{
|
|
if (ShouldInitialize())
|
|
{
|
|
Initialize(_meshType);
|
|
}
|
|
}
|
|
#endif
|
|
}
|