Initial commit
This commit is contained in:
@@ -0,0 +1,362 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
namespace Fragilem17.MirrorsAndPortals
|
||||
{
|
||||
public class PortalUtils
|
||||
{
|
||||
public enum DebugColors
|
||||
{
|
||||
Info,
|
||||
Warn,
|
||||
Error
|
||||
}
|
||||
|
||||
public static string Colorize(string text, DebugColors color, bool bold = false)
|
||||
{
|
||||
string c = "00BC0E";
|
||||
if (color == DebugColors.Error)
|
||||
{
|
||||
c = "BE0000";
|
||||
}
|
||||
else if (color == DebugColors.Warn)
|
||||
{
|
||||
c = "FFB900";
|
||||
}
|
||||
|
||||
return "<color=#" + c + ">" + (bold ? "<b>" : "") + text + (bold ? "</b>" : "") + "</color>";
|
||||
}
|
||||
|
||||
// taken from http://www.terathon.com/code/oblique.html
|
||||
public static void MakeProjectionMatrixOblique(ref Matrix4x4 matrix, Vector4 clipPlane)
|
||||
{
|
||||
Vector4 q = matrix.inverse * new Vector4(Mathf.Sign(clipPlane.x), Mathf.Sign(clipPlane.y), 1.0f, 1.0f);
|
||||
Vector4 c = clipPlane * (2.0F / (Vector4.Dot(clipPlane, q)));
|
||||
|
||||
// Replace the third row of the projection matrix
|
||||
matrix[2] = c.x - matrix[3];
|
||||
matrix[6] = c.y - matrix[7];
|
||||
matrix[10] = c.z - matrix[11];
|
||||
matrix[14] = c.w - matrix[15];
|
||||
|
||||
|
||||
/*
|
||||
Vector4 q;
|
||||
|
||||
// Calculate the clip-space corner point opposite the clipping plane
|
||||
// as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and
|
||||
// transform it into camera space by multiplying it
|
||||
// by the inverse of the projection matrix
|
||||
|
||||
q.x = (sgn(clipPlane.x) + matrix[8]) / matrix[0];
|
||||
q.y = (sgn(clipPlane.y) + matrix[9]) / matrix[5];
|
||||
q.z = -1.0F;
|
||||
q.w = (1.0F + matrix[10]) / matrix[14];
|
||||
|
||||
// Calculate the scaled plane vector
|
||||
Vector4 c = clipPlane * (2.0F / Vector4.Dot(clipPlane, q));
|
||||
|
||||
// Replace the third row of the projection matrix
|
||||
matrix[2] = c.x;
|
||||
matrix[6] = c.y;
|
||||
matrix[10] = c.z + 1.0F;
|
||||
matrix[14] = c.w;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public static Matrix4x4 OffAxisProjectionMatrix(float near, float far, Vector3 pa, Vector3 pb, Vector3 pc, Vector3 pe)
|
||||
{
|
||||
Vector3 va; // from pe to pa
|
||||
Vector3 vb; // from pe to pb
|
||||
Vector3 vc; // from pe to pc
|
||||
Vector3 vr; // right axis of screen
|
||||
Vector3 vu; // up axis of screen
|
||||
Vector3 vn; // normal vector of screen
|
||||
|
||||
float l; // distance to left screen edge
|
||||
float r; // distance to right screen edge
|
||||
float b; // distance to bottom screen edge
|
||||
float t; // distance to top screen edge
|
||||
float d; // distance from eye to screen
|
||||
|
||||
vr = pb - pa;
|
||||
vu = pc - pa;
|
||||
va = pa - pe;
|
||||
vb = pb - pe;
|
||||
vc = pc - pe;
|
||||
|
||||
// are we looking at the backface of the plane object?
|
||||
if (Vector3.Dot(-Vector3.Cross(va, vc), vb) < 0.0)
|
||||
{
|
||||
// mirror points along the z axis (most users
|
||||
// probably expect the x axis to stay fixed)
|
||||
vu = -vu;
|
||||
pa = pc;
|
||||
pb = pa + vr;
|
||||
pc = pa + vu;
|
||||
va = pa - pe;
|
||||
vb = pb - pe;
|
||||
vc = pc - pe;
|
||||
}
|
||||
|
||||
vr.Normalize();
|
||||
vu.Normalize();
|
||||
vn = -Vector3.Cross(vr, vu);
|
||||
// we need the minus sign because Unity
|
||||
// uses a left-handed coordinate system
|
||||
vn.Normalize();
|
||||
|
||||
d = -Vector3.Dot(va, vn);
|
||||
|
||||
// Set near clip plane
|
||||
near = d; // + _clippingDistance;
|
||||
|
||||
l = Vector3.Dot(vr, va) * near / d;
|
||||
r = Vector3.Dot(vr, vb) * near / d;
|
||||
b = Vector3.Dot(vu, va) * near / d;
|
||||
t = Vector3.Dot(vu, vc) * near / d;
|
||||
|
||||
Matrix4x4 p = new Matrix4x4(); // projection matrix
|
||||
p[0, 0] = 2.0f * near / (r - l);
|
||||
p[0, 1] = 0.0f;
|
||||
p[0, 2] = (r + l) / (r - l);
|
||||
p[0, 3] = 0.0f;
|
||||
|
||||
p[1, 0] = 0.0f;
|
||||
p[1, 1] = 2.0f * near / (t - b);
|
||||
p[1, 2] = (t + b) / (t - b);
|
||||
p[1, 3] = 0.0f;
|
||||
|
||||
p[2, 0] = 0.0f;
|
||||
p[2, 1] = 0.0f;
|
||||
p[2, 2] = (far + near) / (near - far);
|
||||
p[2, 3] = 2.0f * far * near / (near - far);
|
||||
|
||||
p[3, 0] = 0.0f;
|
||||
p[3, 1] = 0.0f;
|
||||
p[3, 2] = -1.0f;
|
||||
p[3, 3] = 0.0f;
|
||||
|
||||
Matrix4x4 rm = new Matrix4x4(); // rotation matrix;
|
||||
rm[0, 0] = vr.x;
|
||||
rm[0, 1] = vr.y;
|
||||
rm[0, 2] = vr.z;
|
||||
rm[0, 3] = 0.0f;
|
||||
|
||||
rm[1, 0] = vu.x;
|
||||
rm[1, 1] = vu.y;
|
||||
rm[1, 2] = vu.z;
|
||||
rm[1, 3] = 0.0f;
|
||||
|
||||
rm[2, 0] = vn.x;
|
||||
rm[2, 1] = vn.y;
|
||||
rm[2, 2] = vn.z;
|
||||
rm[2, 3] = 0.0f;
|
||||
|
||||
rm[3, 0] = 0.0f;
|
||||
rm[3, 1] = 0.0f;
|
||||
rm[3, 2] = 0.0f;
|
||||
rm[3, 3] = 1.0f;
|
||||
|
||||
Matrix4x4 tm = new Matrix4x4(); // translation matrix;
|
||||
tm[0, 0] = 1.0f;
|
||||
tm[0, 1] = 0.0f;
|
||||
tm[0, 2] = 0.0f;
|
||||
tm[0, 3] = -pe.x;
|
||||
|
||||
tm[1, 0] = 0.0f;
|
||||
tm[1, 1] = 1.0f;
|
||||
tm[1, 2] = 0.0f;
|
||||
tm[1, 3] = -pe.y;
|
||||
|
||||
tm[2, 0] = 0.0f;
|
||||
tm[2, 1] = 0.0f;
|
||||
tm[2, 2] = 1.0f;
|
||||
tm[2, 3] = -pe.z;
|
||||
|
||||
tm[3, 0] = 0.0f;
|
||||
tm[3, 1] = 0.0f;
|
||||
tm[3, 2] = 0.0f;
|
||||
tm[3, 3] = 1.0f;
|
||||
|
||||
Matrix4x4 worldToCameraMatrix = rm * tm;
|
||||
return p * worldToCameraMatrix;
|
||||
}
|
||||
|
||||
// Extended sign: returns -1, 0 or 1 based on sign of a
|
||||
private static float sgn(float a)
|
||||
{
|
||||
if (a > 0.0f) return 1.0f;
|
||||
if (a < 0.0f) return -1.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// Given position/normal of the plane, calculates plane in camera space.
|
||||
public static Vector4 CameraSpacePlane(Matrix4x4 worldToCameraMatrix, Vector3 pos, Vector3 normal, float sideSign, float clippingPlaneOffset)
|
||||
{
|
||||
Vector3 offsetPos = pos + normal * clippingPlaneOffset;
|
||||
Vector3 cpos = worldToCameraMatrix.MultiplyPoint(offsetPos);
|
||||
Vector3 cnormal = worldToCameraMatrix.MultiplyVector(normal).normalized * sideSign;
|
||||
return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos, cnormal));
|
||||
}
|
||||
|
||||
/*
|
||||
// Calculates reflection matrix around the given plane
|
||||
public static void CalculateReflectionMatrix(ref Matrix4x4 reflectionMat, Vector4 plane)
|
||||
{
|
||||
reflectionMat.m00 = (1F - 2F * plane[0] * plane[0]);
|
||||
reflectionMat.m01 = (-2F * plane[0] * plane[1]);
|
||||
reflectionMat.m02 = (-2F * plane[0] * plane[2]);
|
||||
reflectionMat.m03 = (-2F * plane[3] * plane[0]);
|
||||
|
||||
reflectionMat.m10 = (-2F * plane[1] * plane[0]);
|
||||
reflectionMat.m11 = (1F - 2F * plane[1] * plane[1]);
|
||||
reflectionMat.m12 = (-2F * plane[1] * plane[2]);
|
||||
reflectionMat.m13 = (-2F * plane[3] * plane[1]);
|
||||
|
||||
reflectionMat.m20 = (-2F * plane[2] * plane[0]);
|
||||
reflectionMat.m21 = (-2F * plane[2] * plane[1]);
|
||||
reflectionMat.m22 = (1F - 2F * plane[2] * plane[2]);
|
||||
reflectionMat.m23 = (-2F * plane[3] * plane[2]);
|
||||
|
||||
reflectionMat.m30 = 0F;
|
||||
reflectionMat.m31 = 0F;
|
||||
reflectionMat.m32 = 0F;
|
||||
reflectionMat.m33 = 1F;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SerializableCurve
|
||||
{
|
||||
public SerializableKeyframe[] keys;
|
||||
public string postWrapMode;
|
||||
public string preWrapMode;
|
||||
|
||||
[Serializable]
|
||||
public class SerializableKeyframe
|
||||
{
|
||||
public Single inTangent;
|
||||
public Single inWeight;
|
||||
public Single outTangent;
|
||||
public Single outWeight;
|
||||
public Int32 weightedMode;
|
||||
//public Int32 tangentMode;
|
||||
public Single time;
|
||||
public Single value;
|
||||
|
||||
public SerializableKeyframe(Keyframe original, int index)
|
||||
{
|
||||
inTangent = original.inTangent;
|
||||
inWeight = original.inWeight;
|
||||
|
||||
outTangent = original.outTangent;
|
||||
outWeight = original.outWeight;
|
||||
|
||||
weightedMode = (int)original.weightedMode;
|
||||
//tangentMode = original.tangentMode;
|
||||
|
||||
time = original.time;
|
||||
value = original.value;
|
||||
}
|
||||
}
|
||||
|
||||
public SerializableCurve(AnimationCurve original)
|
||||
{
|
||||
postWrapMode = getWrapModeAsString(original.postWrapMode);
|
||||
preWrapMode = getWrapModeAsString(original.preWrapMode);
|
||||
keys = new SerializableKeyframe[original.length];
|
||||
for (int i = 0; i < original.keys.Length; i++)
|
||||
{
|
||||
keys[i] = new SerializableKeyframe(original.keys[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
public AnimationCurve toCurve()
|
||||
{
|
||||
AnimationCurve res = new AnimationCurve();
|
||||
res.postWrapMode = getWrapMode(postWrapMode);
|
||||
res.preWrapMode = getWrapMode(preWrapMode);
|
||||
Keyframe[] newKeys = new Keyframe[keys.Length];
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
SerializableKeyframe aux = keys[i];
|
||||
Keyframe newK = new Keyframe();
|
||||
newK.inTangent = aux.inTangent;
|
||||
newK.inWeight = aux.inWeight;
|
||||
newK.outTangent = aux.outTangent;
|
||||
newK.outWeight = aux.outWeight;
|
||||
//newK.tangentMode = aux.tangentMode;
|
||||
newK.weightedMode = (WeightedMode)aux.weightedMode;
|
||||
newK.time = aux.time;
|
||||
newK.value = aux.value;
|
||||
newKeys[i] = newK;
|
||||
}
|
||||
res.keys = newKeys;
|
||||
return res;
|
||||
}
|
||||
|
||||
private WrapMode getWrapMode(String mode)
|
||||
{
|
||||
if (mode.Equals("Clamp"))
|
||||
{
|
||||
return WrapMode.Clamp;
|
||||
}
|
||||
if (mode.Equals("ClampForever"))
|
||||
{
|
||||
return WrapMode.ClampForever;
|
||||
}
|
||||
if (mode.Equals("Default"))
|
||||
{
|
||||
return WrapMode.Default;
|
||||
}
|
||||
if (mode.Equals("Loop"))
|
||||
{
|
||||
return WrapMode.Loop;
|
||||
}
|
||||
if (mode.Equals("Once"))
|
||||
{
|
||||
return WrapMode.Once;
|
||||
}
|
||||
if (mode.Equals("PingPong"))
|
||||
{
|
||||
return WrapMode.PingPong;
|
||||
}
|
||||
Debug.LogError("Wat is this wrap mode???");
|
||||
return WrapMode.Default;
|
||||
}
|
||||
|
||||
private string getWrapModeAsString(WrapMode mode)
|
||||
{
|
||||
if (mode.Equals(WrapMode.Clamp))
|
||||
{
|
||||
return "Clamp";
|
||||
}
|
||||
if (mode.Equals(WrapMode.ClampForever))
|
||||
{
|
||||
return "ClampForever";
|
||||
}
|
||||
if (mode.Equals(WrapMode.Default))
|
||||
{
|
||||
return "Default";
|
||||
}
|
||||
if (mode.Equals(WrapMode.Loop))
|
||||
{
|
||||
return "Loop";
|
||||
}
|
||||
if (mode.Equals(WrapMode.Once))
|
||||
{
|
||||
return "Once";
|
||||
}
|
||||
if (mode.Equals(WrapMode.PingPong))
|
||||
{
|
||||
return "PingPong";
|
||||
}
|
||||
Debug.LogError("Wat is this wrap mode???");
|
||||
return "f you";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user