/// <summary> /// Draws the twist constraints accoriding in Unity using Giszmos /// </summary> /// <param name="b">The bone with its constraints</param> /// <param name="refBone">The to be twisted against</param> /// <param name="poss">The position of where it should be drawn</param> /// <param name="scale">The scale of the constraints</param> public static void DrawTwistConstraints(Bone b, Bone refBone, OpenTK.Vector3 poss, float scale) { if (b.Orientation.Xyz.IsNaN() || refBone.Orientation.Xyz.IsNaN()) { return; } OpenTK.Vector3 thisY = b.GetYAxis(); OpenTK.Quaternion referenceRotation = refBone.Orientation * b.ParentPointer; OpenTK.Vector3 parentY = OpenTK.Vector3.Transform(OpenTK.Vector3.UnitY, referenceRotation); OpenTK.Vector3 parentZ = OpenTK.Vector3.Transform(OpenTK.Vector3.UnitZ, referenceRotation); OpenTK.Quaternion rot = QuaternionHelper2.GetRotationBetween(parentY, thisY); OpenTK.Vector3 reference = OpenTK.Vector3.Transform(parentZ, rot); reference.Normalize(); Debug.DrawRay(poss.Convert(), (b.GetZAxis() * scale * 2).Convert(), Color.cyan); float startTwistLimit = OpenTK.MathHelper.DegreesToRadians(b.StartTwistLimit); OpenTK.Vector3 m = OpenTK.Vector3.Transform(reference, OpenTK.Quaternion.FromAxisAngle(thisY, startTwistLimit)); m.Normalize(); Debug.DrawRay(poss.Convert(), m.Convert() * scale, Color.yellow); float endTwistLimit = OpenTK.MathHelper.DegreesToRadians(b.EndTwistLimit); OpenTK.Vector3 m2 = OpenTK.Vector3.Transform(reference, OpenTK.Quaternion.FromAxisAngle(thisY, endTwistLimit)); m2.Normalize(); Debug.DrawRay(poss.Convert(), m2.Convert() * scale, Color.magenta); Debug.DrawLine((poss + (m * scale)).Convert(), (poss + (m2 * scale)).Convert(), Color.cyan); }
OpenTK.Vector3 VectorProjection(OpenTK.Vector3 basis, OpenTK.Vector3 v) { float length = v.Length; OpenTK.Vector3 result = basis; result.Normalize(); return(result * ((float)OpenTK.Vector3.Dot(result, v))); }
OpenTK.Vector3 CalcNormal(OpenTK.Vector3 _v1, OpenTK.Vector3 _v2, OpenTK.Vector3 _v3) { OpenTK.Vector3 v1 = _v2 - _v1; OpenTK.Vector3 v2 = _v3 - _v1; OpenTK.Vector3 normal = OpenTK.Vector3.Cross(v1, v2); normal.Normalize(); return(normal); }
public Data.Mesh3D LightMesh(Data.Mesh3D mesh) { Data.Mesh3D res_msh = new Data.Mesh3D(mesh.TriData.Length, mesh.VertexData.Length); Data.Vertex[] verts = mesh.VertexData; Data.Tri[] tris = mesh.TriData; System.Collections.Generic.List <MapVertex> lVerts = new System.Collections.Generic.List <MapVertex>(); int vi = 0; foreach (Data.Tri tri in tris) { MapVertex lvert = new MapVertex(); lvert.Verts[0] = verts[tri.V0]; lvert.Verts[1] = verts[tri.V1]; lvert.Verts[2] = verts[tri.v2]; MapVertex dvert = new MapVertex(); dvert.Verts[0] = verts[tri.V0]; dvert.Verts[1] = verts[tri.V1]; dvert.Verts[2] = verts[tri.v2]; OpenTK.Vector3 tri_norm = verts[tri.V0].Norm; tri_norm.Normalize(); OpenTK.Vector3 pointonplane = lvert.Verts[0].Pos; if (Abs(tri_norm.X) > Abs(tri_norm.Y) && Abs(tri_norm.X) > Abs(tri_norm.Z)) { lvert.Plane = 1; } else { if (Abs(tri_norm.Y) > Abs(tri_norm.X) && Abs(tri_norm.Y) > Abs(tri_norm.Z)) { lvert.Plane = 2; } else { lvert.Plane = 3; } } switch (lvert.Plane) { case 1: break; } lvert.VI = vi; lVerts.Add(lvert); } return(res_msh); }
/// <summary> /// Draws an irregeular cone /// </summary> /// <param name="strains">The x,y,z,w radii</param> /// <param name="top">The position of the top of the cone</param> /// <param name="L1">The direction of the cone</param> /// <param name="rot">The rotation of the cone</param> /// <param name="resolution">The amount of lines the cone shoud be drawn from</param> /// <param name="scale">The height of the cone</param> public static void CreateIrregularCone(OpenTK.Vector4 strains, OpenTK.Vector3 top, OpenTK.Vector3 L1, OpenTK.Quaternion rot, int resolution, float scale) { L1.Normalize(); List <OpenTK.Vector3> positions = new List <OpenTK.Vector3>(); positions.AddRange(GetQuarter(strains.X, strains.Y, top, L1, rot, resolution, 1, scale)); positions.AddRange(GetQuarter(strains.Z, strains.Y, top, L1, rot, resolution, 2, scale)); positions.AddRange(GetQuarter(strains.Z, strains.W, top, L1, rot, resolution, 3, scale)); positions.AddRange(GetQuarter(strains.X, strains.W, top, L1, rot, resolution, 4, scale)); OpenTK.Vector3 prev = positions.First(); Color c; Color c2 = Color.black; int i = 0; foreach (OpenTK.Vector3 v in positions) { float part = ((float)i % ((float)resolution / 4f)) / ((float)resolution / 4f); if (i < resolution * 0.25) { //Q1 c = Color.Lerp(Color.blue, Color.red, part); } else if (i < resolution * 0.5) { //Q4 c = Color.Lerp(Color.red, Color.green, part); } else if (i < resolution * 0.75) { //Q3 c = Color.Lerp(Color.green, Color.yellow, part); } else { //Q2 c = Color.Lerp(Color.yellow, Color.blue, part); } i++; DrawLine(v, prev, c2); DrawLine(top, v, c); prev = v; } c = Color.blue; DrawLine(prev, positions.First(), c); DrawLine(top, positions.First(), c); //return positions.ToArray(); }
private void BetterCamera(OpenTK.Vector3 average_point) { { const float yFov = 1.00899694f; // 75 const float near = 10; const float far = 7000; float aspect_ratio = GLControl.Width / GLControl.Height; OpenTK.Matrix4 projection; projection = OpenTK.Matrix4.CreatePerspectiveFieldOfView(yFov, aspect_ratio, near, far); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GL.LoadMatrix(ref projection); } OpenTK.Vector3 eye; float radius = Program.camera.GetDistance(); float theta = Program.camera.GetAngleZ(); float phi = Program.camera.GetAngleX(); Program.form.labelAngle.Text = "Angle: " + theta + " " + phi; eye.X = radius * (float)Math.Cos((double)theta) * (float)Math.Cos((double)phi); eye.Y = radius * (float)Math.Sin((double)theta); eye.Z = radius * (float)Math.Cos((double)theta) * (float)Math.Sin((double)phi); OpenTK.Vector3 eye_direction = eye; eye_direction.Normalize(); OpenTK.Vector3 zero = new OpenTK.Vector3(0.0f, 0.0f, 0.0f); OpenTK.Vector3 up = new OpenTK.Vector3(0.0f, 1.0f, 0.0f); OpenTK.Vector3 right = OpenTK.Vector3.Cross(eye_direction, up); //up = OpenTK.Vector3.Cross(right, eye_direction); OpenTK.Matrix4 lookat; lookat = OpenTK.Matrix4.LookAt(eye, zero, up); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.MultMatrix(ref lookat); GL.Translate(average_point); }
public void Forward(double?distPtr, bool drawLine) { double distance = distPtr.HasValue ? distPtr.Value : this.Distance; if (drawLine) { float thickness = (float)(this.Thickness / 2); float length = (float)distance; var currentPosition = OpenTK.Vector3.Transform(zeroVector, stack.Peek().Translation); OpenTK.Vector3[] points = new OpenTK.Vector3[numEdges * 2]; if (this.stack.Peek().fPoints.Count > 0) { OpenTK.Vector3 x1 = new OpenTK.Vector3(1, 0, 0); OpenTK.Vector3 vx1 = OpenTK.Vector3.Transform(x1, this.stack.Peek().fMatrix); OpenTK.Vector3 vx2 = OpenTK.Vector3.Transform(x1, this.stack.Peek().Rotation); float angle = OpenTK.Vector3.CalculateAngle(vx1, vx2); OpenTK.Vector3 rotateAxis = OpenTK.Vector3.Cross(vx1, vx2); for (int i = 0; i < numEdges; ++i) { var p = this.stack.Peek().fPoints[numEdges + i] - currentPosition; p.Normalize(); if (angle > minAngle) { p = OpenTK.Vector3.Transform(p, OpenTK.Matrix4.CreateFromAxisAngle(rotateAxis, angle)); } p = p * thickness; points[i] = currentPosition + p; points[i + numEdges] = currentPosition + p + vx2 * length; } } else { // Create corner points. for (int i = 0; i < numEdges; ++i) { float angle = (float)((i + 0.5f) * (Math.PI * 2) / numEdges); points[i].Y = (float)(thickness * Math.Sin(angle)); points[i].Z = (float)(thickness * Math.Cos(angle)); points[i].X = 0; points[i] = currentPosition + OpenTK.Vector3.Transform(points[i], stack.Peek().Rotation); points[i + numEdges].Y = (float)(thickness * Math.Sin(angle)); points[i + numEdges].Z = (float)(thickness * Math.Cos(angle)); points[i + numEdges].X = length; points[i + numEdges] = currentPosition + OpenTK.Vector3.Transform(points[i + numEdges], stack.Peek().Rotation); } } if (simpleMode) { BuildUpperCap(points, stack.Peek().Color); BuildLowerCap(points, stack.Peek().Color); } else if (this.stack.Peek().fPoints.Count == 0) { BuildLowerCap(points, stack.Peek().Color); } OpenTK.Vector3[] wallPoints = null; if (simpleMode) { wallPoints = points; } else { var previousPoints = this.stack.Peek().fPoints; if (previousPoints.Count > 0) { // Update end points of previous tube, // and start points of this tube. float angle = AngleBetween(this.stack.Peek().fMatrix, stack.Peek().Rotation); if (angle > minAngle) { float r = angle / (float)(Math.PI / 2); float scale = 1.0f + r * r * r; OpenTK.Vector3 x1 = new OpenTK.Vector3(1, 0, 0); OpenTK.Vector3 v1 = OpenTK.Vector3.Transform(x1, this.stack.Peek().fMatrix); OpenTK.Vector3 v2 = OpenTK.Vector3.Transform(x1, this.stack.Peek().Rotation); OpenTK.Vector3 v3 = (v1 + v2) * 0.5f; v3.Normalize(); OpenTK.Vector3 noScaleDirection = OpenTK.Vector3.Cross(v1, v2); OpenTK.Vector3 upDirection = OpenTK.Vector3.Cross(noScaleDirection, v3); for (int i = 0; i < numEdges; ++i) { OpenTK.Vector3 p = (previousPoints[numEdges + i] + points[i]) * 0.5f; OpenTK.Vector3 dir = (p - currentPosition); p = currentPosition + VectorProjection(noScaleDirection, dir) + VectorProjection(upDirection, dir) * scale; previousPoints[numEdges + i] = points[i] = p; } } else { for (int i = 0; i < numEdges; ++i) { OpenTK.Vector3 p = (previousPoints[numEdges + i] + points[i]) * 0.5f; previousPoints[numEdges + i] = points[i] = p; } } // Render previous tube. wallPoints = previousPoints.ToArray(); } this.stack.Peek().fPoints = points.ToList(); this.stack.Peek().fMatrix = stack.Peek().Rotation; } if (wallPoints != null) { BuildWalls(wallPoints, stack.Peek().Color); } } else { if (this.stack.Peek().fPoints.Count > 0) { BuildWalls( stack.Peek().fPoints.ToArray(), stack.Peek().Color); BuildUpperCap( stack.Peek().fPoints.ToArray(), stack.Peek().Color); stack.Peek().fPoints.Clear(); } } var offset = OpenTK.Vector3.Transform( new OpenTK.Vector3((float)distance, 0, 0), stack.Peek().Rotation); stack.Peek().Translation = OpenTK.Matrix4.Mult( OpenTK.Matrix4.CreateTranslation(offset), stack.Peek().Translation); var currentPos = OpenTK.Vector3.Transform(zeroVector, stack.Peek().Translation); this.minPoint = OpenTK.Vector3.ComponentMin(this.minPoint, currentPos); this.maxPoint = OpenTK.Vector3.ComponentMax(this.maxPoint, currentPos); if (this.surfacePoints != null) { this.surfacePoints.Add(currentPos); this.surfaceColors.Add(stack.Peek().Color); if (this.surfacePoints.Count == 3) { // Build new triangle. Add(this.triVertexes, this.surfacePoints[0]); Add(this.triVertexes, this.surfacePoints[1]); Add(this.triVertexes, this.surfacePoints[2]); Add(this.triColors, this.surfaceColors[0]); Add(this.triColors, this.surfaceColors[1]); Add(this.triColors, this.surfaceColors[2]); Add(this.triVertexes, this.surfacePoints[2]); Add(this.triVertexes, this.surfacePoints[1]); Add(this.triVertexes, this.surfacePoints[0]); Add(this.triColors, this.surfaceColors[2]); Add(this.triColors, this.surfaceColors[1]); Add(this.triColors, this.surfaceColors[0]); this.surfacePoints.RemoveAt(1); this.surfaceColors.RemoveAt(1); } } }
public Data.Mesh3D LightMesh(Data.Mesh3D mesh, OpenTK.Matrix4 world_mat) { Data.Mesh3D res_msh = new Data.Mesh3D(mesh.TriData.Length * 3, mesh.VertexData.Length); Data.Vertex[] verts = mesh.VertexData; Data.Tri[] tris = mesh.TriData; int vi = 0; foreach (Data.Vertex ov in mesh.VertexData) { res_msh.SetVertex(vi, ov.Pos, ov.Tan, ov.BiNorm, ov.Norm, ov.UV); vi++; } res_msh.Transform(world_mat); int ti = 0; foreach (Data.Tri tri in tris) { res_msh.SetTri(ti, tri.V0, tri.V1, tri.v2); ti++; MapVertex lvert = new MapVertex(); lvert.Verts[0] = verts[tri.V0]; lvert.Verts[1] = verts[tri.V1]; lvert.Verts[2] = verts[tri.v2]; MapVertex dvert = new MapVertex(); dvert.Verts[0] = verts[tri.V0]; dvert.Verts[1] = verts[tri.V1]; dvert.Verts[2] = verts[tri.v2]; OpenTK.Vector3 tri_norm = verts[tri.V0].Norm; tri_norm.Normalize(); OpenTK.Vector3 pointonplane = lvert.Verts[0].Pos; int flag = -1; if (Math.Abs(tri_norm.X) > Math.Abs(tri_norm.Y) && Math.Abs(tri_norm.X) > Math.Abs(tri_norm.Z)) { flag = 1; lvert.Verts[0].UV.X = dvert.Verts[0].Pos.Y; lvert.Verts[0].UV.Y = dvert.Verts[0].Pos.Z; lvert.Verts[1].UV.X = dvert.Verts[1].Pos.Y; lvert.Verts[1].UV.Y = dvert.Verts[1].Pos.Z; lvert.Verts[2].UV.X = dvert.Verts[2].Pos.Y; lvert.Verts[2].UV.Y = dvert.Verts[2].Pos.Z; } else if (Math.Abs(tri_norm.Y) > Math.Abs(tri_norm.X) && Math.Abs(tri_norm.Y) > Math.Abs(tri_norm.Z)) { flag = 2; lvert.Verts[0].UV.X = dvert.Verts[0].Pos.X; lvert.Verts[0].UV.Y = dvert.Verts[0].Pos.Z; lvert.Verts[1].UV.X = dvert.Verts[1].Pos.X; lvert.Verts[1].UV.Y = dvert.Verts[1].Pos.Z; lvert.Verts[2].UV.X = dvert.Verts[2].Pos.X; lvert.Verts[2].UV.Y = dvert.Verts[2].Pos.Z; } else { flag = 3; lvert.Verts[0].UV.X = dvert.Verts[0].Pos.X; lvert.Verts[0].UV.Y = dvert.Verts[0].Pos.Y; lvert.Verts[1].UV.X = dvert.Verts[1].Pos.X; lvert.Verts[1].UV.Y = dvert.Verts[1].Pos.Y; lvert.Verts[2].UV.X = dvert.Verts[2].Pos.X; lvert.Verts[2].UV.Y = dvert.Verts[2].Pos.Y; } float min_u = lvert.Verts[0].UV.X; float min_v = lvert.Verts[0].UV.Y; float max_u = lvert.Verts[0].UV.X; float max_v = lvert.Verts[0].UV.Y; for (int i = 0; i < 3; i++) { if (lvert.Verts[i].UV.X < min_u) { min_u = lvert.Verts[i].UV.X; } if (lvert.Verts[i].UV.X < min_v) { min_v = lvert.Verts[i].UV.Y; } if (lvert.Verts[i].UV.X > max_u) { max_u = lvert.Verts[i].UV.X; } if (lvert.Verts[i].UV.Y > max_v) { max_v = lvert.Verts[i].UV.Y; } } float delta_u = max_u - min_u; float delta_v = max_v - min_v; for (int i = 0; i < 3; i++) { lvert.Verts[i].UV.X = lvert.Verts[i].UV.X - min_u; lvert.Verts[i].UV.Y = lvert.Verts[i].UV.Y - min_v; lvert.Verts[i].UV.X = lvert.Verts[i].UV.X / delta_u; lvert.Verts[i].UV.Y = lvert.Verts[i].UV.Y / delta_v; } float dist = (tri_norm.X * pointonplane.X + tri_norm.Y * pointonplane.Y + tri_norm.Z * pointonplane.Z); float X, Y, Z; OpenTK.Vector3 UVVector = OpenTK.Vector3.Zero; OpenTK.Vector3 vec1 = OpenTK.Vector3.Zero, vec2 = OpenTK.Vector3.Zero; switch (flag) { case 1: X = -(tri_norm.Y * min_u + tri_norm.Z * min_v + dist) / tri_norm.X; UVVector.X = X; UVVector.Y = min_u; UVVector.Z = min_v; X = -(tri_norm.Y * max_u + tri_norm.Z * min_v + dist) / tri_norm.X; vec1.X = X; vec1.Y = max_u; vec1.Z = min_v; X = -(tri_norm.Y * min_u + tri_norm.Z * max_v + dist) / tri_norm.X; vec2.X = X; vec2.Y = min_u; vec2.Z = max_v; break; case 2: Y = -(tri_norm.X * min_u + tri_norm.Z * min_v + dist) / tri_norm.Y; UVVector.X = min_u; UVVector.Y = Y; UVVector.Z = min_v; Y = -(tri_norm.X * max_u + tri_norm.Z * min_v + dist) / tri_norm.Y; vec1.X = max_u; vec1.Y = Y; vec1.Z = min_v; Y = -(tri_norm.X * min_u + tri_norm.Z * max_v + dist) / tri_norm.Y; vec2.X = min_u; vec2.Y = Y; vec2.Z = max_v; break; case 3: Z = -(tri_norm.X * min_u + tri_norm.Y * min_v + dist) / tri_norm.Z; UVVector.X = min_u; UVVector.Y = min_v; UVVector.Z = Z; Z = -(tri_norm.X * max_u + tri_norm.Y * min_v + dist) / tri_norm.Z; vec1.X = max_u; vec1.Y = min_v; vec1.Z = Z; Z = -(tri_norm.X * min_u + tri_norm.Y * max_v + dist) / tri_norm.Z; vec2.X = min_u; vec2.Y = max_v; vec2.Z = Z; break; } OpenTK.Vector3 edge1; edge1.X = vec1.X - UVVector.X; edge1.Y = vec1.Y - UVVector.Y; edge1.Z = vec1.Z - UVVector.Z; OpenTK.Vector3 edge2; edge2.X = vec2.X - UVVector.X; edge2.Y = vec2.Y - UVVector.Y; edge2.Z = vec2.Z - UVVector.Z; // Console.WriteLine ( "Grabbing TexLeaf" ); TreeLeaf tex_node = FinalMap.Insert(Tri_W, Tri_H); byte[] rgb = new byte[Tri_W * Tri_H * 3]; OpenTK.Vector3[,] lumels = new OpenTK.Vector3[Tri_W, Tri_H]; for (int iX = 0; iX < Tri_W; iX++) { for (int iY = 0; iY < Tri_H; iY++) { float ufactor = (iX / (float)Tri_W); float vfactor = (iY / (float)Tri_H); OpenTK.Vector3 newedge1; newedge1.X = edge1.X * ufactor; newedge1.Y = edge1.Y * ufactor; newedge1.Z = edge1.Z * ufactor; OpenTK.Vector3 newedge2; newedge2.X = edge2.X * vfactor; newedge2.Y = edge2.Y * vfactor; newedge2.Z = edge2.Z * vfactor; int rloc = (iY * Tri_W * 3) + iX * 3; lumels[iX, iY].X = UVVector.X + newedge2.X + newedge1.X; lumels[iX, iY].Y = UVVector.Y + newedge2.Y + newedge1.Y; lumels[iX, iY].Z = UVVector.Z + newedge2.Z + newedge1.Z; rgb[rloc] = 255; rgb[rloc + 1] = 0; rgb[rloc + 2] = 0; } } for (int cv = 0; cv < 3; cv++) { float lx = ((tex_node.RC.X + 1) + (tex_node.RC.W - 2) * lvert.Verts[cv].UV.X) / tex_node.Root.RC.W; float ly = ((tex_node.RC.Y + 1) + (tex_node.RC.H - 2) * lvert.Verts[cv].UV.Y) / tex_node.Root.RC.H; lvert.Verts[cv].UV.X = lx; lvert.Verts[cv].UV.Y = ly; // Console.WriteLine ( "LX:" + lx + " LY:" + ly ); res_msh.VertexData [ tri.V0 // ].UV = new OpenTK.Vector2 ( lx, ly ); } res_msh.VertexData[tri.V0].UV = lvert.Verts[0].UV; res_msh.VertexData[tri.V1].UV = lvert.Verts[1].UV; res_msh.VertexData[tri.v2].UV = lvert.Verts[2].UV; tex_node.SetRaw(rgb); } res_msh.Material = new Material.Material3D(); res_msh.Final(); return(res_msh); }
private static List <OpenTK.Vector3> GetQuarter( float a, float b, OpenTK.Vector3 top, OpenTK.Vector3 L1, OpenTK.Quaternion rot, int resolution, int p, float scale) { OpenTK.Quaternion extraRot = OpenTK.Quaternion.Identity; OpenTK.Vector3 L2 = L1; if (a > 90 && b > 90) { L2 = -L1; a = 180 - a; b = 180 - b; } else if ((a > 90) ^ (b > 90)) { #region Crazy cone OpenTK.Vector3 right = OpenTK.Vector3.Transform(OpenTK.Vector3.UnitX, rot); OpenTK.Vector3 forward = OpenTK.Vector3.Transform(OpenTK.Vector3.UnitZ, rot); L2 = right; switch (p) { case 1: if (a > 90) { L2 = right; } else { L2 = forward; } break; case 2: if (a > 90) { L2 = -right; } else { L2 = forward; } break; case 3: if (a > 90) { L2 = -right; } else { L2 = -forward; } break; case 4: if (a > 90) { L2 = right; } else { L2 = -forward; } break; default: break; } if (a > 90) { a = a - 90; } else { b = b - 90; } float angle = OpenTK.Vector3.CalculateAngle(L2, L1); OpenTK.Vector3 axis = OpenTK.Vector3.Cross(L2, L1); extraRot = OpenTK.Quaternion.FromAxisAngle(axis, angle); extraRot = OpenTK.Quaternion.Invert(extraRot); #endregion } float A = Mathf.Tan(OpenTK.MathHelper.DegreesToRadians(Math.Min(89.99f, a))); float B = Mathf.Tan(OpenTK.MathHelper.DegreesToRadians(Math.Min(89.99f, b))); List <OpenTK.Vector3> te = new List <OpenTK.Vector3>(); float part = resolution * (p / 4f); float start = resolution * ((p - 1f) / 4f); for (float i = start; i < part; i++) { float angle = i / resolution * 2.0f * Mathf.PI; float x = A * Mathf.Cos(angle); float z = B * Mathf.Sin(angle); OpenTK.Vector3 t = new OpenTK.Vector3(x, 0.0f, z); t = OpenTK.Vector3.Transform(t, extraRot * rot); t += L2; t.Normalize(); t *= scale; t += top; te.Add(t); } return(te); }
public static OpenTK.Vector3 ToNormalized(this OpenTK.Vector3 left) { left.Normalize(); return(left); }
private static List<OpenTK.Vector3> GetQuarter( float a, float b, OpenTK.Vector3 top, OpenTK.Vector3 L1, OpenTK.Quaternion rot, int resolution, int p, float scale) { OpenTK.Quaternion extraRot = OpenTK.Quaternion.Identity; OpenTK.Vector3 L2 = L1; if (a > 90 && b > 90) { L2 = -L1; a = 180 - a; b = 180 - b; } else if ((a > 90) ^ (b > 90)) { #region Crazy cone OpenTK.Vector3 right = OpenTK.Vector3.Transform(OpenTK.Vector3.UnitX, rot); OpenTK.Vector3 forward = OpenTK.Vector3.Transform(OpenTK.Vector3.UnitZ, rot); L2 = right; switch (p) { case 1: if (a > 90) L2 = right; else L2 = forward; break; case 2: if (a > 90) L2 = -right; else L2 = forward; break; case 3: if (a > 90) L2 = -right; else L2 = -forward; break; case 4: if (a > 90) L2 = right; else L2 = -forward; break; default: break; } if (a > 90) a = a - 90; else b = b - 90; float angle = OpenTK.Vector3.CalculateAngle(L2, L1); OpenTK.Vector3 axis = OpenTK.Vector3.Cross(L2, L1); extraRot = OpenTK.Quaternion.FromAxisAngle(axis, angle); extraRot = OpenTK.Quaternion.Invert(extraRot); #endregion } float A = Mathf.Tan(OpenTK.MathHelper.DegreesToRadians(Math.Min(89.99f, a))); float B = Mathf.Tan(OpenTK.MathHelper.DegreesToRadians(Math.Min(89.99f, b))); List<OpenTK.Vector3> te = new List<OpenTK.Vector3>(); float part = resolution * (p / 4f); float start = resolution * ((p - 1f) / 4f); for (float i = start; i < part; i++) { float angle = i / resolution * 2.0f * Mathf.PI; float x = A * Mathf.Cos(angle); float z = B * Mathf.Sin(angle); OpenTK.Vector3 t = new OpenTK.Vector3(x, 0.0f, z ); t = OpenTK.Vector3.Transform(t, extraRot * rot ); t += L2; t.Normalize(); t *= scale; t += top; te.Add(t); } return te; }