Tanoda
Plane.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using UnityEngine;
10using Leap.Unity.Query;
11using System.Collections.Generic;
12using Leap.Unity.Infix;
13
14namespace Leap.Unity.Geometry {
15
16 [System.Serializable]
17 public struct Plane {
18
19 public Vector3 center;
21 public Transform transform;
22
23 private Vector3? _cachedCenter;
24 private Direction3? _cachedNormal;
25 private Matrix4x4? _cachedMatrix;
26 private Matrix4x4? _cachedTransformMatrix;
34 public Matrix4x4 matrix {
35 get {
36 if (!checkIsCacheValid()) { rebuildCache(); }
37 return _cachedMatrix.Value;
38 }
39 }
40 private Pose? _cachedPose;
44 public Pose pose {
45 get {
46 if (!checkIsCacheValid()) { rebuildCache(); }
47 return _cachedPose.Value;
48 }
49 }
50
51 private bool checkIsCacheValid() {
52 return _cachedPose.HasValue &&
53 _cachedCenter.HasValue &&
54 _cachedNormal.HasValue &&
55 center == _cachedCenter.Value &&
56 Direction3.PointsInSameDirection(normal, _cachedNormal.Value) &&
57 ((transform == null && !_cachedTransformMatrix.HasValue) ||
58 (_cachedTransformMatrix.HasValue &&
59 _cachedTransformMatrix.Value == transform.localToWorldMatrix));
60 }
61 private void rebuildCache() {
62 _cachedMatrix = Matrix4x4.TRS(
63 center,
64 Quaternion.LookRotation(normal),
65 Vector3.one);
66 _cachedPose = new Pose(center, Quaternion.LookRotation(normal));
67
68 _cachedCenter = center;
69 _cachedNormal = normal;
70
71 if (transform == null) {
72 _cachedTransformMatrix = null;
73 }
74 else {
75 _cachedMatrix = transform.localToWorldMatrix * _cachedMatrix;
76 _cachedPose = transform.localToWorldMatrix.GetPose() * _cachedPose;
77 _cachedTransformMatrix = transform.localToWorldMatrix;
78 }
79
80 }
81
82 public Plane(Vector3 center, Direction3 normal) {
83 _cachedCenter = null;
84 _cachedNormal = null;
85 _cachedMatrix = null;
86 _cachedPose = null;
87 _cachedTransformMatrix = null;
88 this.center = center;
89 this.normal = normal;
90 this.transform = null;
91 }
92 public Plane(Vector3 center, Direction3 normal, Transform transform) {
93 _cachedCenter = null;
94 _cachedNormal = null;
95 _cachedMatrix = null;
96 _cachedPose = null;
97 _cachedTransformMatrix = null;
98 this.center = center;
99 this.normal = normal;
100 this.transform = transform;
101 }
102
103 private static List<Collider> s_backingUnityBodyCollidersCache;
104 private static List<Collider> s_unityBodyCollidersCache {
105 get {
106 if (s_backingUnityBodyCollidersCache == null) {
107 s_backingUnityBodyCollidersCache = new List<Collider>();
108 }
109 return s_backingUnityBodyCollidersCache;
110 }
111 }
112 public bool CollidesWith(UnityEngine.Rigidbody unityBody,
113 bool includeBehindPlane = false) {
114 s_unityBodyCollidersCache.Clear();
115 Leap.Unity.Utils.FindOwnedChildComponents<Collider, Rigidbody>(
116 unityBody,
117 s_unityBodyCollidersCache,
118 includeInactiveObjects: false
119 );
120 foreach (var collider in s_unityBodyCollidersCache) {
121 if (this.CollidesWith(collider, includeBehindPlane)) {
122 return true;
123 }
124 }
125 return false;
126 }
127
131 public bool CollidesWith(UnityEngine.Collider unityCollider,
132 bool includeBehindPlane = false) {
133 var planePose = this.pose;
134 var planePoseInverse = this.pose.inverse;
135
136 var colliderCenter = getUnityColliderWorldCenter(unityCollider);
137 var colliderCenter_plane =
138 (planePoseInverse * colliderCenter).position;
139 var colliderCenterOnPlane_plane = colliderCenter_plane.WithZ(0f);
140 var colliderCenterOnPlane =
141 (planePose * colliderCenterOnPlane_plane).position;
142
143 var closestPoint = unityCollider.ClosestPoint(colliderCenterOnPlane);
144 var closestPoint_plane = (planePoseInverse * closestPoint).position;
145
146 // Concave shapes will break here; projection from their center is not
147 // valid. To support concavity, you'd want to project to the plane from
148 // the planeward-most point on the concave collider.
149 var planeToClosestPoint_plane =
150 closestPoint_plane - colliderCenterOnPlane_plane;
151
152 if (includeBehindPlane) {
153 // Plane faces forward on Z.
154 return planeToClosestPoint_plane.z <= 0f;
155 }
156 else {
157 return planeToClosestPoint_plane.z == 0f;
158 }
159 }
160
161 private Vector3 getUnityColliderWorldCenter(
162 UnityEngine.Collider unityCollider) {
163 SphereCollider sphere = unityCollider as SphereCollider;
164 if (sphere != null) {
165 return unityCollider.transform.localToWorldMatrix.MultiplyPoint3x4(
166 sphere.center
167 );
168 }
169
170 CapsuleCollider capsule = unityCollider as CapsuleCollider;
171 if (capsule != null) {
172 Vector3 a, b;
173 capsule.GetCapsulePoints(out a, out b);
174 return unityCollider.transform.localToWorldMatrix.MultiplyPoint3x4(
175 (a + b) / 2f
176 );
177 }
178
179 BoxCollider box = unityCollider as BoxCollider;
180 if (box != null) {
181 return unityCollider.transform.localToWorldMatrix.MultiplyPoint3x4(
182 box.center
183 );
184 }
185
186 MeshCollider mesh = unityCollider as MeshCollider;
187 if (mesh != null) {
188 // Warning: Only valid for convex meshes.
189 return unityCollider.transform.localToWorldMatrix.MultiplyPoint3x4(
190 mesh.bounds.center
191 );
192 }
193
194 throw new System.Exception("(Plane Collision) Collider type not supported: " +
195 unityCollider.GetType().ToString());
196 }
197 }
198
199}
A struct very similar to Vector3, but that prevents itself from ever being converted to Vector3....
Definition: Direction3.cs:24
static bool PointsInSameDirection(Direction3 A, Direction3 B)
Returns whether two Direction3s point in the same direction without normalizing either of the underly...
Definition: Direction3.cs:75
Direction3 normal
Definition: Plane.cs:20
Pose pose
The local to world pose for this plane. See Plane.matrix.
Definition: Plane.cs:44
Matrix4x4 matrix
The local to world matrix for this plane. The plane is always locally an XY plane,...
Definition: Plane.cs:34
bool CollidesWith(UnityEngine.Rigidbody unityBody, bool includeBehindPlane=false)
Definition: Plane.cs:112
Plane(Vector3 center, Direction3 normal, Transform transform)
Definition: Plane.cs:92
Transform transform
Definition: Plane.cs:21
bool CollidesWith(UnityEngine.Collider unityCollider, bool includeBehindPlane=false)
Only guaranteed to be correct for convex colliders.
Definition: Plane.cs:131
Plane(Vector3 center, Direction3 normal)
Definition: Plane.cs:82
A position and rotation. You can multiply two poses; this acts like Matrix4x4 multiplication,...
Definition: Pose.cs:21
Pose inverse
Definition: Pose.cs:37