You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
272 lines
6.1 KiB
272 lines
6.1 KiB
using UnityEngine; |
|
using System.Collections; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Copyright 2015-2016 RenderHeads Ltd. All rights reserverd. |
|
//----------------------------------------------------------------------------- |
|
|
|
namespace RenderHeads.Media.AVProVideo |
|
{ |
|
/// <summary> |
|
/// Builds a cube mesh for displaying a 360 degree "Cubemap 3x2 facebook layout" texture in VR |
|
/// </summary> |
|
[RequireComponent(typeof(MeshRenderer))] |
|
[RequireComponent(typeof(MeshFilter))] |
|
//[ExecuteInEditMode] |
|
[AddComponentMenu("AVPro Video/Cubemap Cube (VR)")] |
|
public class CubemapCube : MonoBehaviour |
|
{ |
|
private Mesh _mesh; |
|
private MeshRenderer _renderer; |
|
|
|
[SerializeField] |
|
private Material _material; |
|
|
|
[SerializeField] |
|
private MediaPlayer _mediaPlayer; |
|
|
|
// This value comes from the facebook transform ffmpeg filter and is used to prevent seams appearing along the edges due to bilinear filtering |
|
[SerializeField] |
|
private float expansion_coeff = 1.01f; |
|
|
|
public MediaPlayer Player |
|
{ |
|
set { _mediaPlayer = value; } |
|
get { return _mediaPlayer; } |
|
} |
|
|
|
void Start() |
|
{ |
|
if (_mesh == null) |
|
{ |
|
_mesh = new Mesh(); |
|
_mesh.MarkDynamic(); |
|
MeshFilter filter = this.GetComponent<MeshFilter>(); |
|
if (filter != null) |
|
{ |
|
filter.mesh = _mesh; |
|
} |
|
_renderer = this.GetComponent<MeshRenderer>(); |
|
if (_renderer != null) |
|
{ |
|
_renderer.material = _material; |
|
} |
|
BuildMesh(); |
|
} |
|
} |
|
|
|
void OnDestroy() |
|
{ |
|
if (_mesh != null) |
|
{ |
|
MeshFilter filter = this.GetComponent<MeshFilter>(); |
|
if (filter != null) |
|
{ |
|
filter.mesh = null; |
|
} |
|
|
|
#if UNITY_EDITOR |
|
Mesh.DestroyImmediate(_mesh); |
|
#else |
|
Mesh.Destroy(_mesh); |
|
#endif |
|
_mesh = null; |
|
} |
|
|
|
if (_renderer != null) |
|
{ |
|
_renderer.material = null; |
|
_renderer = null; |
|
} |
|
} |
|
|
|
void Update() |
|
{ |
|
if (Application.isPlaying) |
|
{ |
|
Texture texture = null; |
|
if (_mediaPlayer != null && _mediaPlayer.Control != null) |
|
{ |
|
if (_mediaPlayer.TextureProducer != null) |
|
{ |
|
texture = _mediaPlayer.TextureProducer.GetTexture(); |
|
} |
|
} |
|
|
|
UpdateMaterial(texture); |
|
if (texture != null) |
|
{ |
|
UpdateMeshUV(texture.width, texture.height, _mediaPlayer.TextureProducer.RequiresVerticalFlip()); |
|
} |
|
} |
|
} |
|
|
|
private void UpdateMaterial(Texture texture) |
|
{ |
|
_renderer.material.mainTexture = texture; |
|
} |
|
|
|
private void BuildMesh() |
|
{ |
|
Vector3 offset = new Vector3(-0.5f, -0.5f, -0.5f); |
|
Vector3[] v = new Vector3[] |
|
{ |
|
// Left |
|
new Vector3(0f,-1f,0f) - offset, |
|
new Vector3(0f,0f,0f) - offset, |
|
new Vector3(0f,0f,-1f) - offset, |
|
new Vector3(0f,-1f,-1f) - offset, |
|
// Front |
|
new Vector3(0f,0f,0f) - offset, |
|
new Vector3(-1f,0f,0f) - offset, |
|
new Vector3(-1f,0f,-1f) - offset, |
|
new Vector3(0f,0f,-1f) - offset, |
|
// Right |
|
new Vector3(-1f,0f,0f) - offset, |
|
new Vector3(-1f,-1f,0f) - offset, |
|
new Vector3(-1f,-1f,-1f) - offset, |
|
new Vector3(-1f,0f,-1f) - offset, |
|
// Back |
|
new Vector3(-1f,-1f,0f) - offset, |
|
new Vector3(0f,-1f,0f) - offset, |
|
new Vector3(0f,-1f,-1f) - offset, |
|
new Vector3(-1f,-1f,-1f) - offset, |
|
// Bottom |
|
new Vector3(0f,-1f,-1f) - offset, |
|
new Vector3(0f,0f,-1f) - offset, |
|
new Vector3(-1f,0f,-1f) - offset, |
|
new Vector3(-1f,-1f,-1f) - offset, |
|
// Top |
|
new Vector3(-1f,-1f,0f) - offset, |
|
new Vector3(-1f,0f,0f) - offset, |
|
new Vector3(0f,0f,0f) - offset, |
|
new Vector3(0f,-1f,0f) - offset, |
|
}; |
|
|
|
Matrix4x4 rot = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(-90f, Vector3.right), Vector3.one); |
|
for (int i = 0; i < v.Length; i++) |
|
{ |
|
v[i] = rot.MultiplyPoint(v[i]); |
|
} |
|
|
|
_mesh.vertices = v; |
|
|
|
_mesh.triangles = new int[] |
|
{ |
|
0,1,2, |
|
0,2,3, |
|
4,5,6, |
|
4,6,7, |
|
8,9,10, |
|
8,10,11, |
|
12,13,14, |
|
12,14,15, |
|
16,17,18, |
|
16,18,19, |
|
20,21,22, |
|
20,22,23, |
|
}; |
|
|
|
_mesh.normals = new Vector3[] |
|
{ |
|
// Left |
|
new Vector3(-1f,0f,0f), |
|
new Vector3(-1f,0f,0f), |
|
new Vector3(-1f,0f,0f), |
|
new Vector3(-1f,0f,0f), |
|
// Front |
|
new Vector3(0f,-1f,0f), |
|
new Vector3(0f,-1f,0f), |
|
new Vector3(0f,-1f,0f), |
|
new Vector3(0f,-1f,0f), |
|
// Right |
|
new Vector3(1f,0f,0f), |
|
new Vector3(1f,0f,0f), |
|
new Vector3(1f,0f,0f), |
|
new Vector3(1f,0f,0f), |
|
// Back |
|
new Vector3(0f,1f,0f), |
|
new Vector3(0f,1f,0f), |
|
new Vector3(0f,1f,0f), |
|
new Vector3(0f,1f,0f), |
|
// Bottom |
|
new Vector3(0f,0f,1f), |
|
new Vector3(0f,0f,1f), |
|
new Vector3(0f,0f,1f), |
|
new Vector3(0f,0f,1f), |
|
// Top |
|
new Vector3(0f,0f,-1f), |
|
new Vector3(0f,0f,-1f), |
|
new Vector3(0f,0f,-1f), |
|
new Vector3(0f,0f,-1f) |
|
}; |
|
|
|
UpdateMeshUV(512, 512, false); |
|
} |
|
|
|
private void UpdateMeshUV(int textureWidth, int textureHeight, bool flipY) |
|
{ |
|
float texWidth = textureWidth; |
|
float texHeight = textureHeight; |
|
|
|
float blockWidth = texWidth / 3f; |
|
float pixelOffset = Mathf.Floor(((expansion_coeff * blockWidth) - blockWidth) / 2f); |
|
|
|
float wO = pixelOffset / texWidth; |
|
float hO = pixelOffset / texHeight; |
|
|
|
const float third = 1f / 3f; |
|
const float half = 1f / 2f; |
|
|
|
Vector2[] uv = new Vector2[] |
|
{ |
|
//left |
|
new Vector2(third+wO,1-hO), |
|
new Vector2((third*2)-wO, 1-hO), |
|
new Vector2((third*2)-wO, half+hO), |
|
new Vector2(third+wO, half+hO), |
|
|
|
//front |
|
new Vector2(third+wO, half-hO), |
|
new Vector2((third*2)-wO, half-hO), |
|
new Vector2((third*2)-wO, 0f+hO), |
|
new Vector2(third+wO, 0f+hO), |
|
|
|
//right |
|
new Vector2(0+wO, 1f-hO), |
|
new Vector2(third-wO, 1f-hO), |
|
new Vector2(third-wO, half+hO), |
|
new Vector2(0+wO, half+hO), |
|
|
|
//back |
|
new Vector2((third*2)+wO, half-hO), |
|
new Vector2(1-wO, half-hO), |
|
new Vector2(1-wO, 0+hO), |
|
new Vector2((third*2)+wO, 0+hO), |
|
|
|
//bottom |
|
new Vector2(0+wO, 0+hO), |
|
new Vector2(0+wO, half-hO), |
|
new Vector2(third-wO, half-hO), |
|
new Vector2(third-wO, 0+hO), |
|
|
|
//top |
|
new Vector2(1-wO, 1-hO), |
|
new Vector2(1-wO, half+hO), |
|
new Vector2((third*2)+wO, half+hO), |
|
new Vector2((third*2)+wO, 1-hO) |
|
}; |
|
|
|
if (flipY) |
|
{ |
|
for (int i = 0; i < uv.Length; i++) |
|
{ |
|
uv[i].y = 1f - uv[i].y; |
|
} |
|
} |
|
|
|
_mesh.uv = uv; |
|
_mesh.UploadMeshData(false); |
|
} |
|
} |
|
}
|
|
|