add round layout example.

This commit is contained in:
hecomi
2016-11-08 22:09:55 +09:00
parent d423e0d1db
commit 941bb2da91
13 changed files with 220 additions and 41 deletions
@@ -4,11 +4,17 @@ using System.Collections.Generic;
public class MultipleMonitorCreator : MonoBehaviour
{
[SerializeField] GameObject monitorPrefab;
[SerializeField] float scale = 1f;
[SerializeField] float margin = 1f;
private List<GameObject> monitors_ = new List<GameObject>();
private float totalWidth_ = 0f;
public class MonitorInfo
{
public GameObject gameObject { get; set; }
public Quaternion originalRotation { get; set; }
public uDesktopDuplication.Texture uddTexture { get; set; }
public Vector3 meshBounds;
}
private List<MonitorInfo> monitors_ = new List<MonitorInfo>();
public List<MonitorInfo> monitors { get { return monitors_; } }
void Start()
{
@@ -26,25 +32,16 @@ public class MultipleMonitorCreator : MonoBehaviour
}
void Create()
{
CreateMonitors();
LayoutMonitors();
}
void CreateMonitors()
{
// Sort monitors in coordinate order
var monitors = uDesktopDuplication.Manager.monitors;
monitors.Sort((a, b) => a.left - b.left);
// Create monitors
var n = monitors.Count;
totalWidth_ = 0f;
for (int i = 0 ; i < n; ++i) {
for (int i = 0 ; i < uDesktopDuplication.Manager.monitorCount; ++i) {
// Create monitor obeject
var go = Instantiate(monitorPrefab);
go.name = "Monitor " + i;
monitors_.Add(go);
// Assign monitor
var texture = go.GetComponent<uDesktopDuplication.Texture>();
@@ -52,37 +49,28 @@ public class MultipleMonitorCreator : MonoBehaviour
var monitor = texture.monitor;
// Set width / height
go.transform.localScale = new Vector3(monitor.widthMeter, go.transform.localScale.y, monitor.heightMeter) * scale;
go.transform.localScale = new Vector3(monitor.widthMeter, go.transform.localScale.y, monitor.heightMeter);
// Set parent as this object
go.transform.SetParent(transform);
// Calc actual size considering mesh size
var scaleX = go.GetComponent<MeshFilter>().sharedMesh.bounds.extents.x * 2f;
totalWidth_ += monitor.widthMeter * scale * scaleX;
}
}
var bounds = go.GetComponent<MeshFilter>().sharedMesh.bounds.extents * 2f;
void LayoutMonitors()
{
// Set positions with margin
totalWidth_ += margin * (monitors_.Count - 1);
var x = -totalWidth_ / 2;
foreach (var go in monitors_) {
var monitor = go.GetComponent<uDesktopDuplication.Texture>().monitor;
var halfScaleX = go.GetComponent<MeshFilter>().sharedMesh.bounds.extents.x;
var width = monitor.widthMeter * scale;
var halfWidth = width * halfScaleX;
x += halfWidth;
go.transform.localPosition = new Vector3(x, 0f, 0f);
x += halfWidth + margin;
// Save
var info = new MonitorInfo();
info.gameObject = go;
info.originalRotation = go.transform.rotation;
info.uddTexture = texture;
info.meshBounds = bounds;
monitors_.Add(info);
}
}
void Clear()
{
foreach (var go in monitors_) {
Destroy(go);
foreach (var info in monitors_) {
Destroy(info.gameObject);
}
monitors_.Clear();
}
@@ -0,0 +1,52 @@
using UnityEngine;
[RequireComponent(typeof(MultipleMonitorCreator))]
public class MultipleMonitorLayouter : MonoBehaviour
{
protected MultipleMonitorCreator creator_;
[SerializeField] bool updateEveryFrame = true;
[SerializeField] protected float margin = 0.1f;
void Start()
{
creator_ = GetComponent<MultipleMonitorCreator>();
Layout();
}
protected virtual void Update()
{
if (updateEveryFrame) {
Layout();
}
}
void LateUpdate()
{
margin = Mathf.Max(margin, 0f);
}
protected virtual void Layout()
{
var monitors = creator_.monitors;
var n = monitors.Count;
var totalWidth = 0f;
foreach (var info in monitors) {
var width = info.uddTexture.monitor.widthMeter * info.meshBounds.x;
totalWidth += width;
}
totalWidth += margin * (n - 1);
var x = -totalWidth / 2;
foreach (var info in creator_.monitors) {
var monitor = info.uddTexture.monitor;
x += (monitor.widthMeter * info.meshBounds.x) / 2;
info.gameObject.transform.localPosition = new Vector3(x, 0f, 0f);
info.gameObject.transform.localRotation = info.originalRotation;
x += (monitor.widthMeter * info.meshBounds.x) / 2 + margin;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0db1dcac2dedc724194c423ee75b3bf4
timeCreated: 1478608632
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,60 @@
using UnityEngine;
public class MultipleMonitorRoundLayouter : MultipleMonitorLayouter
{
[SerializeField] float radius = 10f;
void OnDisable()
{
foreach (var info in creator_.monitors) {
info.uddTexture.bend = uDesktopDuplication.Texture.Bend.Off;
}
}
protected override void Layout()
{
var monitors = creator_.monitors;
var n = monitors.Count;
var totalWidth = 0f;
foreach (var info in monitors) {
var width = info.uddTexture.monitor.widthMeter * info.meshBounds.x;
totalWidth += width;
}
totalWidth += margin * (n - 1);
radius = Mathf.Max(radius, (totalWidth + margin) / (2 * Mathf.PI));
var totalAngle = totalWidth / radius;
float angle = -totalAngle / 2;
foreach (var info in monitors) {
var uddTex = info.uddTexture;
var width = uddTex.monitor.widthMeter * info.meshBounds.x;
angle += (width / radius) * 0.5f;
uddTex.transform.localPosition = radius * new Vector3(Mathf.Sin(angle), 0f, Mathf.Cos(angle) - 1f);
uddTex.transform.localRotation = Quaternion.AngleAxis(angle * Mathf.Rad2Deg, Vector3.up) * info.originalRotation;
angle += (width * 0.5f + margin) / radius;
uddTex.bend = uDesktopDuplication.Texture.Bend.Y;
uddTex.radius = radius;
uddTex.width = uddTex.monitor.widthMeter;
}
}
protected override void Update()
{
base.Update();
var scale = transform.localScale.x;
var center = transform.position - Vector3.forward * radius * scale;
for (int i = 0; i < 100; ++i) {
var a0 = 2 * Mathf.PI * i / 100;
var a1 = 2 * Mathf.PI * (i + 1) / 100;
var p0 = center + radius * scale * new Vector3(Mathf.Cos(a0), 0f, Mathf.Sin(a0));
var p1 = center + radius * scale * new Vector3(Mathf.Cos(a1), 0f, Mathf.Sin(a1));
Debug.DrawLine(p0, p1, Color.red);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a31b05fdfa301f14e88365e64622b43a
timeCreated: 1478524060
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -33,6 +33,56 @@ public class Texture : MonoBehaviour
public Vector2 clipPos = Vector2.zero;
public Vector2 clipScale = new Vector2(0.2f, 0.2f);
public enum Bend
{
Off = 0,
Y = 1,
Z = 2,
}
public Bend bend
{
get
{
return (Bend)material.GetInt("_Bend");
}
set
{
switch (value) {
case Bend.Off:
material.SetInt("_Bend", 0);
material.DisableKeyword("_BEND_OFF");
material.DisableKeyword("_BEND_Y");
material.DisableKeyword("_BEND_Z");
break;
case Bend.Y:
material.SetInt("_Bend", 1);
material.DisableKeyword("_BEND_OFF");
material.EnableKeyword("_BEND_Y");
material.DisableKeyword("_BEND_Z");
break;
case Bend.Z:
material.SetInt("_Bend", 2);
material.DisableKeyword("_BEND_OFF");
material.DisableKeyword("_BEND_Y");
material.EnableKeyword("_BEND_Z");
break;
}
}
}
public float radius
{
get { return material.GetFloat("_Radius"); }
set { material.SetFloat("_Radius", value); }
}
public float width
{
get { return material.GetFloat("_Width"); }
set { material.SetFloat("_Width", value); }
}
public Material material
{
get;
@@ -5,8 +5,8 @@ Properties
{
_Color ("Color", Color) = (1, 1, 1, 1)
_MainTex ("Texture", 2D) = "white" {}
[Toggle(USE_BEND)] _UseBend("UseBend", Float) = 0
[PowerSlider(10.0)]_Radius ("Radius", Range(10, 100)) = 30
[KeywordEnum(Off, Y, Z)] _Bend("Bending", Int) = 0
[PowerSlider(10.0)]_Radius ("Radius", Range(1, 100)) = 30
[KeywordEnum(Off, Front, Back)] _Cull("Culling", Int) = 2
}
@@ -21,15 +21,20 @@ CGINCLUDE
#include "./uDD_Common.cginc"
fixed _Radius;
half _Radius;
half _Width;
v2f vert(appdata v)
{
v2f o;
#ifdef USE_BEND
half a = v.vertex.x / _Radius;
v.vertex.x = _Radius * sin(a);
#if defined(_BEND_Z) || defined(_BEND_Y)
half a = _Width * v.vertex.x / _Radius;
v.vertex.x = _Radius * sin(a) / _Width;
#ifdef _BEND_Y
v.vertex.y += _Radius * (1 - cos(a));
#elif _BEND_Z
v.vertex.z += _Radius * (1 - cos(a));
#endif
#endif
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
@@ -51,8 +56,8 @@ Pass
#pragma multi_compile ___ INVERT_X
#pragma multi_compile ___ INVERT_Y
#pragma multi_compile ___ ROTATE90 ROTATE180 ROTATE270
#pragma multi_compile ___ USE_BEND
#pragma multi_compile ___ USE_CLIP
#pragma multi_compile _BEND_OFF _BEND_Y _BEND_Z
ENDCG
}