/// <summary> /// Simulate object to the given time. /// </summary> /// <param name="time">Required target time.</param> /// <param name="puz">Puzzle context.</param> /// <returns>False in case of expiry.</returns> public bool Simulate(double time, Puzzle puz) { if (time <= simTime) { return(true); } if (Math.Abs(angleLeft) > 1.0e-6) { // Rotate the whole cube. double dt = time - simTime; double dangle = Math.Min(Math.Abs(angleLeft), dt * speed); int sign = Math.Sign(angleLeft); Matrix4d dm = Matrix4d.Rotate(axis, dangle * sign); objectMatrix *= dm; angleLeft -= dangle * sign; } simTime = time; return(true); }
public TorusKnot(int pathsteps, int shapevertices, double radius, int p, int q, int TexCount, bool useDL) : base(useDL) { Trace.Assert(pathsteps >= MINPathSteps, "A Path must have at least " + MINPathSteps + " Steps to form a volume."); Trace.Assert(shapevertices >= MINShapeVertices, "A Shape must contain at least " + MINShapeVertices + " Vertices to be considered valid and create a volume."); Trace.Assert(TexCount >= 1, "at least 1 Texture set is required."); PrimitiveMode = OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip; Vector3d[] PathPositions = new Vector3d[pathsteps]; #region Find the center Points for each step on the path for (int i = 0; i < pathsteps; i++) { double Angle = (i / (double)pathsteps) * TwoPi; double AngleTimesP = Angle * p; double AngleTimesQ = Angle * q; double r = (0.5 * (2.0 + System.Math.Sin(AngleTimesQ))); PathPositions[i] = new Vector3d((r * System.Math.Cos(AngleTimesP)), (r * System.Math.Cos(AngleTimesQ)), (r * System.Math.Sin(AngleTimesP))); } #endregion Find the center Points for each step on the path #region Find the Torus length Vector3d result; double[] Lengths = new double[pathsteps]; Vector3d.Subtract(ref PathPositions[pathsteps - 1], ref PathPositions[0], out result); Lengths[0] = result.Length; double TotalLength = result.Length; for (int i = 1; i < pathsteps; i++) // skipping { Vector3d.Subtract(ref PathPositions[i - 1], ref PathPositions[i], out result); Lengths[i] = result.Length; TotalLength += result.Length; } Trace.WriteLine("the TorusKnot's length is: " + TotalLength + " "); #endregion Find the Torus length VertexArray = new VertexT2dN3dV3d[pathsteps * shapevertices]; #region Loft a circle Shape along the path double TwoPiThroughVert = TwoPi / shapevertices; // precalc for reuse for (uint i = 0; i < pathsteps; i++) { Vector3d last, next, normal, tangent; if (i == pathsteps - 1) { next = PathPositions[0]; } else { next = PathPositions[i + 1]; } if (i == 0) { last = PathPositions[pathsteps - 1]; } else { last = PathPositions[i - 1]; } Vector3d.Subtract(ref next, ref last, out tangent); // Guesstimate tangent tangent.Normalize(); Vector3d.Add(ref next, ref last, out normal); // Approximate N normal.Normalize(); Vector3d.Multiply(ref normal, radius, out normal); // scale the shape to desired radius for (uint j = 0; j < shapevertices; j++) { uint index = i * (uint)shapevertices + j; // Create a point on the plane and rotate it Matrix4d RotationMatrix = Matrix4d.Rotate(tangent, -(j * TwoPiThroughVert)); Vector3d point = Vector3d.TransformVector(normal, RotationMatrix); Vector3d.Add(ref PathPositions[i], ref point, out VertexArray[index].Position); // Since the used shape is a circle, the Vertex normal's heading is easy to find Vector3d.Subtract(ref VertexArray[index].Position, ref PathPositions[i], out VertexArray[index].Normal); VertexArray[index].Normal.Normalize(); // just generate some semi-useful UVs to fill blanks VertexArray[index].TexCoord = new Vector2d((double)(i / TotalLength / TexCount), j / (shapevertices - 1.0)); } } #endregion Loft a circle Shape along the path PathPositions = null; // not needed anymore uint currentindex = 0; #region Build a Triangle strip from the Vertices IndexArray = new uint[pathsteps * (shapevertices * 2 + 2)]; // 2 triangles per vertex, +2 due to added degenerate triangles for (uint i = 0; i < pathsteps; i++) { uint RowCurrent = i * (uint)shapevertices; uint RowBelow; if (i == pathsteps - 1) { RowBelow = 0; // for the last row, the first row is the following } else { RowBelow = (i + 1) * (uint)shapevertices; } // new ring begins here for (uint j = 0; j < shapevertices; j++) { IndexArray[currentindex++] = RowCurrent + j; IndexArray[currentindex++] = RowBelow + j; } // ring ends here, repeat first 2 vertices to insert 2 degenerate triangles to reach following ring IndexArray[currentindex++] = RowCurrent; IndexArray[currentindex++] = RowBelow; } #endregion Build a Triangle strip from the Vertices }
public static Matrix4d GetRotationMatrix(this Quaterniond quaternion) { return(Matrix4d.Rotate(quaternion)); }
public void Update(double elapsedTime, EntityManager entityManager) { var delta = (elapsedTime - _lastUpdate) * 5; var forward = _camera.Target - _camera.Position; forward.Normalize(); var up = _camera.Up; up.Normalize(); var right = Vector3d.Cross(forward, up); right.Normalize(); if (_keyboardInputProcessor.IsButtonDown(Key.W)) { var result = Vector3d.Multiply(new Vector3d(forward.X, 0, forward.Z), delta); _camera.Target += result; _camera.Position += result; } if (_keyboardInputProcessor.IsButtonDown(Key.S)) { var result = Vector3d.Multiply(new Vector3d(-forward.X, 0, -forward.Z), delta); _camera.Target += result; _camera.Position += result; } if (_keyboardInputProcessor.IsButtonDown(Key.D)) { var result = Vector3d.Multiply(new Vector3d(right.X, 0, right.Z), delta); _camera.Target += result; _camera.Position += result; } if (_keyboardInputProcessor.IsButtonDown(Key.A)) { var result = Vector3d.Multiply(new Vector3d(-right.X, 0, -right.Z), delta); _camera.Target += result; _camera.Position += result; } if (_keyboardInputProcessor.IsButtonDown(Key.E)) { var rotation = Matrix4d.Rotate(new Vector3d(0, 1, 0), -delta * 0.2); _camera.Position = _camera.Target + Vector3d.Transform(_camera.Position - _camera.Target, rotation); } if (_keyboardInputProcessor.IsButtonDown(Key.Q)) { var rotation = Matrix4d.Rotate(new Vector3d(0, 1, 0), delta * 0.2); _camera.Position = _camera.Target + Vector3d.Transform(_camera.Position - _camera.Target, rotation); } if (_keyboardInputProcessor.IsButtonDown(Key.LShift)) { _camera.Position += Vector3d.Multiply(new Vector3d(0, 1, 0), delta); } if (_keyboardInputProcessor.IsButtonDown(Key.LControl)) { _camera.Position += Vector3d.Multiply(new Vector3d(0, 1, 0), -delta); } _lastUpdate = elapsedTime; }
protected void Rotate(double angle) { rotation *= Matrix4d.Rotate(Vector3d.UnitZ, angle); UpdateMatrix(); }