| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- using UnityEngine;
- public class LogicField
- {
- public Vector3 Position { get; private set;}
- public Vector3 Forward { get; private set;}
- public Vector3 Up { get; private set;}
- public Vector3 Right { get; private set;}
- public Vector3 Size {get; private set;}
- Vector3 mLocalMin;
- Vector3 mLocalMax;
- Matrix4x4 mLocalToWorld;
- Matrix4x4 mWorldToLocal;
- public LogicField(Vector3 pos, Vector3 size, Vector3 forward)
- {
- Position = pos;
- Size = size;
- Forward = forward.SetY (0).normalized;
- Up = Vector3.up;
- Right = Vector3.Cross (Up, Forward);
- mLocalMin = -0.5f * Size;
- mLocalMax = 0.5f * Size;
- mLocalToWorld.SetColumn (0, Right);
- mLocalToWorld.SetColumn (1, Up);
- mLocalToWorld.SetColumn (2, Forward);
- mLocalToWorld.SetColumn (3, new Vector4(Position.x, Position.y, Position.z, 1));
- mWorldToLocal = mLocalToWorld.inverse;
- }
-
- public bool IsInField(Vector3 pos)
- {
- Vector3 v = InverseTransformPoint(pos);
- return v.IsInRange (mLocalMin, mLocalMax);
- }
- public Vector3 FixMove(Vector3 from, Vector3 to)
- {
- Vector3 vfrom = InverseTransformPoint (from);
- if (!vfrom.IsInRange (mLocalMin, mLocalMax))
- return to;
-
- Vector3 vto = InverseTransformPoint(to);
- if (vto.IsInRange(mLocalMin, mLocalMax))
- return to;
-
- return TransformPoint(LocalCrossPosition(vfrom, vto));
- }
- public Vector3 ProjectGround(Vector3 pos)
- {
- return TransformPoint (InverseTransformPoint (pos).SetY (mLocalMin.y));
- }
-
- public Vector3 Closest(Vector3 pos)
- {
- Vector3 v = InverseTransformPoint(pos);
- v = Vector3.Min(v, mLocalMax);
- v = Vector3.Max(v, mLocalMin);
- return TransformPoint(v);
- }
- public float PositionHeight(Vector3 pos)
- {
- return InverseTransformPoint(pos).y - mLocalMin.y;
- }
- public Vector3 TransformPoint(Vector3 v)
- {
- return mLocalToWorld.MultiplyPoint(v);
- }
- public Vector3 InverseTransformPoint(Vector3 v)
- {
- return mWorldToLocal.MultiplyPoint(v);
- }
- public Vector3 TransformDirection(Vector3 d)
- {
- return mLocalToWorld.MultiplyVector(d);
- }
- public Vector3 InverseTransformDirection(Vector3 d)
- {
- return mWorldToLocal.MultiplyVector(d);
- }
- Vector3 LocalCrossPosition(Vector3 localInside, Vector3 localOutside)
- {
- float tx = 1f, ty = 1f, tz = 1f;
- const float diff = 1e-3f;
- if (localOutside.x < mLocalMin.x - diff)
- tx = (mLocalMin.x - localInside.x) / (localOutside.x - localInside.x);
- else if (localOutside.x > mLocalMax.x + diff)
- tx = (mLocalMax.x - localInside.x) / (localOutside.x - localInside.x);
- if (localOutside.y < mLocalMin.y - diff)
- ty = (mLocalMin.y - localInside.y) / (localOutside.y - localInside.y);
- else if (localOutside.y > mLocalMax.y + diff)
- ty = (mLocalMax.y - localInside.y) / (localOutside.y - localInside.y);
- if (localOutside.z < mLocalMin.z - diff)
- tz = (mLocalMin.z - localInside.z) / (localOutside.z - localInside.z);
- else if (localOutside.z > mLocalMax.z + diff)
- tz = (mLocalMax.z - localInside.z) / (localOutside.z - localInside.z);
- float t = Mathf.Min(tx, ty, tz);
- if (t >= 1 - 1e-3f)
- return localOutside.ClampPosition(mLocalMin, mLocalMax);
- else
- return Vector3.Lerp(localInside, localOutside, t);
- }
- }
|