From 5f0ab1f62dc4083575754e069e5be33e69e9f814 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 8 Jun 2013 14:13:47 +1200 Subject: [PATCH] Add functions for calculating voxel bounding boxes. --- OpenRA.Game/Graphics/Util.cs | 29 +++++++++++++++++++++++++++++ OpenRA.Game/Graphics/Voxel.cs | 27 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/OpenRA.Game/Graphics/Util.cs b/OpenRA.Game/Graphics/Util.cs index 1d08371ddb..278c514f93 100644 --- a/OpenRA.Game/Graphics/Util.cs +++ b/OpenRA.Game/Graphics/Util.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using OpenRA.FileFormats.Graphics; namespace OpenRA.Graphics @@ -229,5 +230,33 @@ namespace OpenRA.Graphics return mtx; } + + public static float[] MatrixAABBMultiply(float[] mtx, float[] bounds) + { + // Corner offsets + var ix = new uint[] {0,0,0,0,3,3,3,3}; + var iy = new uint[] {1,1,4,4,1,1,4,4}; + var iz = new uint[] {2,5,2,5,2,5,2,5}; + + // Vectors to opposing corner + var ret = new float[] {float.MaxValue, float.MaxValue, float.MaxValue, + float.MinValue, float.MinValue, float.MinValue}; + + // Transform vectors and find new bounding box + for (var i = 0; i < 8; i++) + { + var vec = new float[] {bounds[ix[i]], bounds[iy[i]], bounds[iz[i]], 1}; + var tvec = Util.MatrixVectorMultiply(mtx, vec); + + ret[0] = Math.Min(ret[0], tvec[0]/tvec[3]); + ret[1] = Math.Min(ret[1], tvec[1]/tvec[3]); + ret[2] = Math.Min(ret[2], tvec[2]/tvec[3]); + ret[3] = Math.Max(ret[3], tvec[0]/tvec[3]); + ret[4] = Math.Max(ret[4], tvec[1]/tvec[3]); + ret[5] = Math.Max(ret[5], tvec[2]/tvec[3]); + } + + return ret; + } } } diff --git a/OpenRA.Game/Graphics/Voxel.cs b/OpenRA.Game/Graphics/Voxel.cs index dcabecfcd3..d69500cf97 100644 --- a/OpenRA.Game/Graphics/Voxel.cs +++ b/OpenRA.Game/Graphics/Voxel.cs @@ -164,5 +164,32 @@ namespace OpenRA.Graphics }); } } + + public float[] Bounds(uint frame) + { + var ret = new float[] {float.MaxValue,float.MaxValue,float.MaxValue, + float.MinValue,float.MinValue,float.MinValue}; + + for (uint j = 0; j < limbs.Length; j++) + { + var b = new float[] + { + 0, 0, 0, + (limbs[j].Bounds[3] - limbs[j].Bounds[0]), + (limbs[j].Bounds[4] - limbs[j].Bounds[1]), + (limbs[j].Bounds[5] - limbs[j].Bounds[2]) + }; + + // Calculate limb bounding box + var bb = Util.MatrixAABBMultiply(TransformationMatrix(j, frame), b); + for (var i = 0; i < 3; i++) + { + ret[i] = Math.Min(ret[i], bb[i]); + ret[i+3] = Math.Max(ret[i+3], bb[i+3]); + } + } + + return ret; + } } }