add raycast api.

This commit is contained in:
hecomi
2016-12-15 02:30:04 +09:00
parent 295b41f57b
commit d519dba120
5 changed files with 123 additions and 0 deletions
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f68bd0626da87264cb4daca57d3c1594
timeCreated: 1481736541
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,22 @@
using UnityEngine;
using System.Collections;
public class RaycastTest : MonoBehaviour
{
public Transform from;
public Transform to;
void Update()
{
if (!from || !to) return;
Debug.DrawLine(from.position, to.position, Color.red);
foreach (var uddTexture in GameObject.FindObjectsOfType<uDesktopDuplication.Texture>()) {
var result = uddTexture.RayCast(from.position, to.position - from.position);
if (result.hit) {
Debug.DrawLine(result.position, result.position + result.normal, Color.yellow);
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 810a4ad59c7d8d34e9b6014e8191fffe
timeCreated: 1481722966
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -308,6 +308,87 @@ public class Texture : MonoBehaviour
// To world position
return transform.position + (transform.rotation * localPos);
}
public struct RayCastResult
{
public bool hit;
public Vector3 position;
public Vector3 normal;
}
static readonly RayCastResult raycastFailedResult = new RayCastResult {
hit = false,
position = Vector3.zero,
normal = Vector3.forward
};
// This function can be used only for vertical (= MeshForwardDirection.Z) plane.
public RayCastResult RayCast(Vector3 from, Vector3 dir)
{
var r = radius;
var center = transform.position - transform.forward * r;
var rot = transform.rotation;//Quaternion.FromToRotation(Vector3.forward, (transform.position - center).normalized);
var trs = Matrix4x4.TRS(center, rot, Vector3.one);
var invTrs = trs.inverse;
Vector3 localFrom = invTrs.MultiplyPoint3x4(from);
Vector3 localDir = invTrs.MultiplyVector(dir).normalized;
var a = localDir.z / localDir.x;
var b = localFrom.z - a * localFrom.x;
var aa = a * a;
var bb = b * b;
var ab = a * b;
var rr = r * r;
var s = aa * rr - bb + rr;
if (s < 0f) {
return raycastFailedResult;
}
s = Mathf.Sqrt(s);
var t = aa + 1;
var lx0 = (-s - ab) / t;
var lz0 = (b - a * s) / t;
var to0 = new Vector3(lx0, 0f, lz0);
var lx1 = (s - ab) / t;
var lz1 = (a * s + b) / t;
var to1 = new Vector3(lx1, 0f, lz1);
var to = (Vector3.Dot(localDir, to0) > 0f) ? to0 : to1;
var toAngle = Mathf.Abs(Mathf.Atan2(to.x, to.z));
var halfWidthAngle = (worldWidth / radius) * 0.5f;
if (toAngle > halfWidthAngle) {
return raycastFailedResult;
}
var v = to - localFrom;
var l = Mathf.Sqrt(Mathf.Pow(v.x, 2f) + Mathf.Pow(v.z, 2f));
var ly = localFrom.y + l * localDir.y / Mathf.Sqrt(Mathf.Pow(localDir.x, 2f) + Mathf.Pow(localDir.z, 2f));
var halfHeight = worldHeight * 0.5f;
if (Mathf.Abs(ly) > halfHeight) {
return raycastFailedResult;
}
to.y = ly;
var hitPos = trs.MultiplyPoint(to);
if ((hitPos - from).magnitude > dir.magnitude) {
return raycastFailedResult;
}
return new RayCastResult {
hit = true,
position = trs.MultiplyPoint(to),
normal = trs.MultiplyVector(-to).normalized
};
}
}
}