private void UpdateSenzorToCamera() { // - translate by (-0.5, -aspectRatio * 0.5) // - scale by (width, height, 1) // - translate by (shiftX, shiftY, distanceZ) // - [tilt around X by tiltX, ...] var matrix = Matrix4d.CreateTranslation(-0.5, AspectRatio * -0.5, 0); matrix = Matrix4d.Mult(matrix, Matrix4d.Scale(Width, Width, 1)); matrix = Matrix4d.Mult(matrix, Matrix4d.CreateTranslation(Shift)); TiltMatrix = Matrix4d.Identity; if (Tilt.X != 0) { TiltMatrix = Matrix4d.CreateRotationX(Tilt.X); } if (Tilt.Y != 0) { TiltMatrix = Matrix4d.Mult(TiltMatrix, Matrix4d.CreateRotationY(Tilt.Y)); } if (Tilt.Z != 0) { TiltMatrix = Matrix4d.Mult(TiltMatrix, Matrix4d.CreateRotationZ(Tilt.Z)); } matrix = Matrix4d.Mult(matrix, TiltMatrix); SenzorToCamera = matrix; }
// we rotate around the centre point. hoff/voff allows you to place the bitmap to the side public static Vector3d[] GetVertices(Vector3d centre, Vector3 rotationdeg, float width, float height, float hoffset = 0, float voffset = 0) { Matrix4d rm = Matrix4d.Identity; if (rotationdeg.X != 0) { rm *= Matrix4d.CreateRotationX((float)(rotationdeg.X * Math.PI / 180.0f)); } if (rotationdeg.Y != 0) { rm *= Matrix4d.CreateRotationY((float)(rotationdeg.Y * Math.PI / 180.0f)); } if (rotationdeg.Z != 0) { rm *= Matrix4d.CreateRotationZ((float)(rotationdeg.Z * Math.PI / 180.0f)); } width /= 2; height /= 2; Vector3d[] points = new Vector3d[] // bitmap is placed on map, centred if hoff,voff=0. { Vector3d.Transform(new Vector3d(-width + hoffset, 0, height + voffset), rm) + centre, // top left, rotate and transform Vector3d.Transform(new Vector3d(width + hoffset, 0, height + voffset), rm) + centre, // top right Vector3d.Transform(new Vector3d(width + hoffset, 0, -height + voffset), rm) + centre, // bot right Vector3d.Transform(new Vector3d(-width + hoffset, 0, -height + voffset), rm) + centre, // bot left }; return(points); }
public static CollisionResult CircleVsUnmovableLineSegment( // lineV1 and lineV2 are specified clockwise. Vector2d lineV1, Vector2d lineV2, Vector2d circlePosition, Vector2d circleVelocity, double circleRadius ) { // Get the relative position of the circle centre to v1. Vector2d relativeCirclePosition = circlePosition - lineV1; // Rotate everything so that the line segment is lying flat along the X axis with v1 at the origin. // Figure out the angle to rotate by. Vector2d v2RelativePosition = lineV2 - lineV1; double angleToRotateByRadians = Math.Atan2(v2RelativePosition.Y, v2RelativePosition.X); // Produce a matrix to rotate everything by that amount. var rotationMatrix = Matrix4d.CreateRotationZ(angleToRotateByRadians).Inverted(); double lineLength = v2RelativePosition.Length; // Perform the rotation. Vector3d rotatedCirclePosition = Vector3d.Transform(new Vector3d(relativeCirclePosition.X, relativeCirclePosition.Y, 0.0), rotationMatrix); Vector3d rotatedCircleVelocity = Vector3d.Transform(new Vector3d(circleVelocity.X, circleVelocity.Y, 0.0), rotationMatrix); // Determine whether the circle is intersecting. bool intersection = rotatedCirclePosition.X > 0 && rotatedCirclePosition.X < lineLength && rotatedCirclePosition.Y - circleRadius < 0 && rotatedCirclePosition.Y + circleRadius > 0; if (!intersection) { // Return a negative collision result. return(new CollisionResult { DidCollide = false, NewCirclePosition = circlePosition, // Use the original circle velocity. NewCircleVelocity = circleVelocity }); } else { // make the circle's Y velocity positive in this frame of reference, Vector3d postCollisionRotatedCircleVelocity = new Vector3d(rotatedCircleVelocity.X, Math.Abs(rotatedCircleVelocity.Y), 0); // Rotate the new velocity back. Vector3d postCollisionCircleVelocity = Vector3d.Transform(postCollisionRotatedCircleVelocity, rotationMatrix.Inverted()); var newVelocity = postCollisionCircleVelocity.Xy * 1.005; // Return as a positive collision result. return(new CollisionResult { DidCollide = true, NewCirclePosition = circlePosition + newVelocity, NewCircleVelocity = newVelocity }); } }
public void ActualModelRender() { Matrix4d mat = PreRot * Matrix4d.CreateRotationZ((Direction.Yaw * Utilities.PI180)) * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(GetPosition())); TheClient.MainWorldView.SetMatrix(2, mat); model.CustomAnimationAdjustments = new Dictionary <string, Matrix4>(SavedAdjustmentsOTK); model.Draw(aHTime, hAnim, aTTime, tAnim, aLTime, lAnim); // TODO: Render held item! }
/// <summary> /// Random direction around the [0,0,1] vector. /// Normal distribution is used, using required variance. /// </summary> /// <param name="rnd">Random generator to be used.</param> /// <param name="variance">Variance of the deviation angle in radians.</param> /// <returns></returns> public static Vector3d RandomDirectionNormal(RandomJames rnd, double variance) { // result: [0,0,1] * rotX(deviation) * rotZ(orientation) double deviation = rnd.Normal(0.0, variance); double orientation = rnd.RandomDouble(0.0, Math.PI); Matrix4d mat = Matrix4d.CreateRotationX(deviation) * Matrix4d.CreateRotationZ(orientation); return(new Vector3d(mat.Row2)); // [0,0,1] * mat }
/// <summary> /// Render a cylinder between two points. /// </summary> /// <param name="start">The initial point.</param> /// <param name="end">The ending point.</param> /// <param name="width">The width of the cylinder.</param> public void RenderCylinder(Location start, Location end, float width) { float len = (float)(end - start).Length(); Location vecang = Utilities.VectorToAngles(start - end); Matrix4d mat = Matrix4d.CreateRotationY((float)(90 * Utilities.PI180)) * Matrix4d.Scale(len, width, width) * Matrix4d.CreateRotationY((float)(vecang.Y * Utilities.PI180)) * Matrix4d.CreateRotationZ((float)(vecang.Z * Utilities.PI180)) * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(start)); Client.Central.MainWorldView.SetMatrix(2, mat); Client.Central.Models.Cylinder.Draw(); // TODO: Models reference in constructor - or client reference? }
/// <summary> /// Render a line between two points. /// </summary> /// <param name="start">The initial point.</param> /// <param name="end">The ending point.</param> public void RenderLine(Location start, Location end) { // TODO: Efficiency! float len = (float)(end - start).Length(); Location vecang = Utilities.VectorToAngles(start - end); Matrix4d mat = Matrix4d.Scale(len, 1, 1) * Matrix4d.CreateRotationY((float)(vecang.Y * Utilities.PI180)) * Matrix4d.CreateRotationZ((float)(vecang.Z * Utilities.PI180)) * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(start)); Client.Central.MainWorldView.SetMatrix(2, mat); // TODO: Client reference! GL.BindVertexArray(Line._VAO); GL.DrawElements(PrimitiveType.Lines, 2, DrawElementsType.UnsignedInt, IntPtr.Zero); }
/// <summary> /// Render a cylinder between two points. /// </summary> /// <param name="start">The initial point.</param> /// <param name="end">The ending point.</param> /// <param name="width">The width of the cylinder.</param> /// <param name="view">The relevant view.</param> public void RenderCylinder(Location start, Location end, float width, View3D view) { float len = (float)(end - start).Length(); Location vecang = Utilities.VectorToAngles(start - end); vecang.Yaw += 180; Matrix4d mat = Matrix4d.CreateRotationY((float)(90 * Utilities.PI180)) * Matrix4d.Scale(len, width, width) * Matrix4d.CreateRotationY((float)(vecang.Y * Utilities.PI180)) * Matrix4d.CreateRotationZ((float)(vecang.Z * Utilities.PI180)) * Matrix4d.CreateTranslation(start.ToOpenTK3D()); view.SetMatrix(2, mat); Models.Cylinder.Draw(); // TODO: Models reference in constructor - or client reference? }
/// <summary> /// Render a cylinder between two points. /// </summary> /// <param name="context">The sourcing render context.</param> /// <param name="start">The initial point.</param> /// <param name="end">The ending point.</param> /// <param name="width">The width of the cylinder.</param> /// <param name="view">The relevant view.</param> public void RenderCylinder(RenderContext context, Location start, Location end, float width, View3D view) { float len = (float)(end - start).Length(); Location vecang = MathUtilities.VectorToAngles(start - end); vecang.Yaw += 180; Matrix4d mat = Matrix4d.CreateRotationY((float)(90 * MathUtilities.PI180)) * Matrix4d.Scale(len, width, width) * Matrix4d.CreateRotationY((float)(vecang.Y * MathUtilities.PI180)) * Matrix4d.CreateRotationZ((float)(vecang.Z * MathUtilities.PI180)) * Matrix4d.CreateTranslation(start.ToOpenTK3D()); view.SetMatrix(2, mat); Models.Cylinder.Draw(context); }
public static CollisionResult CircleVsUnmovablePoint( double circleRadius, // Point position in game coords. // This is also the collision point. Vector2d pointPosition, // Circle position in game coords. Vector2d circlePosition, Vector2d circleVelocity ) { Vector2d collisionPoint = pointPosition; double velocityMagnitude = circleVelocity.Length; if ((circlePosition - pointPosition).Length < circleRadius) { //var newVelocity = (circlePosition - pointPosition).Normalized() * velocityMagnitude; Vector2d relativeCirclePosition = circlePosition - pointPosition; double relativeAngleOfCircleRadians = Math.Atan2(relativeCirclePosition.Y, relativeCirclePosition.X) - Math.PI / 2; var rotationMatrix = Matrix4d.CreateRotationZ(relativeAngleOfCircleRadians).Inverted(); Vector3d rotatedCirclePosition = Vector3d.Transform(new Vector3d(relativeCirclePosition.X, relativeCirclePosition.Y, 0.0), rotationMatrix); Vector3d rotatedCircleVelocity = Vector3d.Transform(new Vector3d(circleVelocity.X, circleVelocity.Y, 0.0), rotationMatrix); // make the circle's Y velocity positive in this frame of reference, Vector3d postCollisionRotatedCircleVelocity = new Vector3d(rotatedCircleVelocity.X, Math.Abs(rotatedCircleVelocity.Y), 0); // Rotate the new velocity back. Vector3d postCollisionCircleVelocity = Vector3d.Transform(postCollisionRotatedCircleVelocity, rotationMatrix.Inverted()); var newVelocity = postCollisionCircleVelocity.Xy * 1.005; // Return as a positive collision result. return(new CollisionResult { DidCollide = true, NewCirclePosition = circlePosition + newVelocity, NewCircleVelocity = newVelocity }); } else { // Return original velocity return(new CollisionResult { DidCollide = false, NewCirclePosition = circlePosition, NewCircleVelocity = circleVelocity }); } }
/// <summary> /// Render a line between two points. /// </summary> /// <param name="start">The initial point.</param> /// <param name="end">The ending point.</param> /// <param name="view">The relevant view.</param> public void RenderLine(Location start, Location end, View3D view) { // TODO: Efficiency! float len = (float)(end - start).Length(); Location vecang = Utilities.VectorToAngles(start - end); vecang.Yaw += 180; Matrix4d mat = Matrix4d.Scale(len, 1, 1) * Matrix4d.CreateRotationY((float)(vecang.Y * Utilities.PI180)) * Matrix4d.CreateRotationZ((float)(vecang.Z * Utilities.PI180)) * Matrix4d.CreateTranslation(start.ToOpenTK3D()); view.SetMatrix(2, mat); GL.BindVertexArray(Line._VAO); GL.DrawElements(PrimitiveType.Lines, 2, DrawElementsType.UnsignedInt, IntPtr.Zero); }
/// <summary>Calculate the Projection matrix - projects the 3d model space to the 2D screen</summary> public void CalculateModelMatrix(Vector3d lookatd, Vector3d eyepositiond, double camerarotation) { LookAt = new Vector3((float)lookatd.X, (float)lookatd.Y, (float)lookatd.Z); // record for shader use EyePosition = new Vector3((float)eyepositiond.X, (float)eyepositiond.Y, (float)eyepositiond.Z); EyeDistance = (float)((lookatd - eyepositiond).Length); // System.Diagnostics.Debug.WriteLine($"CMM {lookat} {eyeposition} dist {EyeDistance} {cameradirection} {camerarotation}"); Matrix4d mat; if (InPerspectiveMode) { Vector3d camnormal = new Vector3d(0, ModelAxisPositiveZAwayFromViewer ? -1 : 1, 0); if (camerarotation != 0) // if we have camera rotation, then rotate the up vector { Matrix4d rot = Matrix4d.CreateRotationZ((float)camerarotation.Radians()); camnormal = Vector3d.Transform(camnormal, rot); } mat = Matrix4d.LookAt(eyepositiond, lookatd, camnormal); // from eye, look at target, with normal giving the rotation of the look } else { Size scr = ViewPort.Size; double orthoheight = (OrthographicDistance / 5.0f) * scr.Height / scr.Width; // this comes from the projection calculation, and allows us to work out the scale factor the eye vs lookat has double scaler = orthoheight / EyeDistance; // no create scale, do it manually. Matrix4d scale = new Matrix4d(new Vector4d(scaler, 0, 0, 0), new Vector4d(0, scaler, 0, 0), new Vector4d(0, 0, scaler, 0), new Vector4d(0, 0, 0, 1)); mat = Matrix4d.CreateTranslation(-lookatd.X, 0, -lookatd.Z); // we offset by the negative of the position to give the central look mat = Matrix4d.Mult(mat, scale); // translation world->View = scale + offset Matrix4d rotcam = Matrix4d.CreateRotationX(90.0 * Math.PI / 180.0f); // flip 90 along the x axis to give the top down view mat = Matrix4d.Mult(mat, rotcam); } // and turn it to float model matrix ModelMatrix = new Matrix4((float)mat.M11, (float)mat.M12, (float)mat.M13, (float)mat.M14, (float)mat.M21, (float)mat.M22, (float)mat.M23, (float)mat.M24, (float)mat.M31, (float)mat.M32, (float)mat.M33, (float)mat.M34, (float)mat.M41, (float)mat.M42, (float)mat.M43, (float)mat.M44); //System.Diagnostics.Debug.WriteLine("MM\r\n{0}", ModelMatrix); ProjectionModelMatrix = Matrix4.Mult(ModelMatrix, ProjectionMatrix); // order order order ! so important. CountMatrixCalcs++; }
/// <summary> /// Random direction around the givent center vector. /// Normal distribution is used, using required variance. /// </summary> /// <param name="rnd">Random generator to be used.</param> /// <param name="dir">Central direction.</param> /// <param name="variance">Variance of the deviation angle in radians.</param> /// <returns></returns> public static Vector3d RandomDirectionNormal(RandomJames rnd, Vector3d dir, double variance) { // Matrix3d fromz: [0,0,1] -> dir // Vector4d delta: [0,0,1] * rotX(deviation) * rotZ(orientation) // result: delta * fromz dir.Normalize(); Vector3d axis1, axis2; GetAxes(ref dir, out axis1, out axis2); Matrix4d fromz = new Matrix4d(new Vector4d(axis1), new Vector4d(axis2), new Vector4d(dir), Vector4d.UnitW); //fromz.Transpose(); double deviation = rnd.Normal(0.0, variance); double orientation = rnd.RandomDouble(0.0, Math.PI); Matrix4d mat = Matrix4d.CreateRotationX(deviation) * Matrix4d.CreateRotationZ(orientation) * fromz; return(new Vector3d(mat.Row2)); // [0,0,1] * mat }
private Vector3d MapMoveToSphere(double radius, Vector2 startPosition, Vector2 endPosition) { var deltaFromStartPixels = endPosition - startPosition; var deltaOnSurface = new Vector2d( deltaFromStartPixels.X / radius, deltaFromStartPixels.Y / radius); var lengthOnSurfaceRadi = deltaOnSurface.Length; // get this rotation on the surface of the sphere about y var positionAboutY = Vector3d.Transform(Vector3d.UnitZ, Matrix4d.CreateRotationY(lengthOnSurfaceRadi)); // get the angle that this distance travels around the sphere var angleToTravel = Math.Atan2(-deltaOnSurface.Y, deltaOnSurface.X); // now rotate that position about z in the direction of the screen vector return(Vector3d.Transform(positionAboutY, Matrix4d.CreateRotationZ(angleToTravel))); }
public override void Render() { TheClient.SetEnts(); TheClient.Rendering.SetColor(TheClient.Rendering.AdaptColor(ClientUtilities.Convert(GetPosition()), color)); TheClient.Rendering.SetMinimumLight(0.0f); // TODO: Prevent model flipping (Possibly related to animation?) Matrix4d mat = PreRot * Matrix4d.CreateRotationZ((Direction.Yaw * Utilities.PI180)) * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(GetPosition())); TheClient.MainWorldView.SetMatrix(2, mat); model.CustomAnimationAdjustments = new Dictionary <string, Matrix4>(SavedAdjustmentsOTK); model.Draw(aHTime, hAnim, aTTime, tAnim, aLTime, lAnim); TheClient.Rendering.SetColor(Color4.White); // TODO: Render held item! if (IsTyping) { TheClient.Textures.GetTexture("ui/game/typing").Bind(); // TODO: store! TheClient.Rendering.RenderBillboard(GetPosition() + new Location(0, 0, 4), new Location(2), TheClient.MainWorldView.CameraPos); } }
private void WriteNextMtx(int hnumber, sbyte bnumber, sbyte pnumber, Matrix4d testmtx, ref int ofs) { sbyte child = Hierarchies[hnumber][bnumber].Child; sbyte sibling = Hierarchies[hnumber][bnumber].Sibling; Matrix4d localmtx = testmtx; localmtx = Matrix4d.Mult(Matrix4d.CreateTranslation(Hierarchies[hnumber][bnumber].Translation), testmtx); localmtx = Matrix4d.Mult(Matrix4d.CreateRotationZ(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.Z / 182.0444444f)), localmtx); localmtx = Matrix4d.Mult(Matrix4d.CreateRotationY(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.Y / 182.0444444f)), localmtx); localmtx = Matrix4d.Mult(Matrix4d.CreateRotationX(MathHelper.DegreesToRadians((float)Hierarchies[hnumber][bnumber].Rotation.X / 182.0444444f)), localmtx); if (Hierarchies[hnumber][bnumber].DisplayList != 0) { WriteMtxData(localmtx.M11, hnumber, ref ofs); WriteMtxData(localmtx.M12, hnumber, ref ofs); WriteMtxData(localmtx.M13, hnumber, ref ofs); WriteMtxData(localmtx.M14, hnumber, ref ofs); WriteMtxData(localmtx.M21, hnumber, ref ofs); WriteMtxData(localmtx.M22, hnumber, ref ofs); WriteMtxData(localmtx.M23, hnumber, ref ofs); WriteMtxData(localmtx.M24, hnumber, ref ofs); WriteMtxData(localmtx.M31, hnumber, ref ofs); WriteMtxData(localmtx.M32, hnumber, ref ofs); WriteMtxData(localmtx.M33, hnumber, ref ofs); WriteMtxData(localmtx.M34, hnumber, ref ofs); WriteMtxData(localmtx.M41, hnumber, ref ofs); WriteMtxData(localmtx.M42, hnumber, ref ofs); WriteMtxData(localmtx.M43, hnumber, ref ofs); WriteMtxData(localmtx.M44, hnumber, ref ofs); ofs += 0x20; } if (child > -1 && child != bnumber) { WriteNextMtx(hnumber, child, bnumber, localmtx, ref ofs); } if (sibling > -1 && sibling != bnumber) { WriteNextMtx(hnumber, sibling, pnumber, testmtx, ref ofs); } }
public void RenderBillboard(Location pos, Location scale, Location facing) { // TODO: Quaternion magic? Location relang = Utilities.VectorToAngles(pos - facing); if (relang.IsInfinite() || relang.IsNaN()) { throw new Exception("Unable to handle billboard: relang=" + relang); } Matrix4d mat = Matrix4d.Scale(ClientUtilities.ConvertD(scale)) * Matrix4d.CreateTranslation(-0.5f, -0.5f, 0f) * Matrix4d.CreateRotationY((float)((relang.Y - 90) * Utilities.PI180)) * Matrix4d.CreateRotationZ((float)(relang.Z * Utilities.PI180)) * Matrix4d.CreateTranslation(ClientUtilities.ConvertD(pos)); Client.Central.MainWorldView.SetMatrix(2, mat); // TODO: Client reference! GL.BindVertexArray(Square._VAO); GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, IntPtr.Zero); GL.BindVertexArray(0); }
private void ButtonViewIsometric_Click(object sender, EventArgs e) => glControlReciProGonio.WorldMatrix = Matrix4d.CreateRotationZ(-Math.PI / 4) * Matrix4d.CreateRotationX(-0.4 * Math.PI);
public LensRayTransferFunction.Parameters ConvertSurfaceRayToParameters( Ray ray, Vector3d canonicalNormal, double surfaceSinTheta, Sphere sphericalSurface, ElementSurface surface) { //Console.WriteLine("ray->parameters"); // - convert origin // *- transform to hemispherical coordinates // - find out if it is on the surface // *- scale with respect to the spherical cap // *- normalize Vector3d unitSpherePos = (ray.Origin - sphericalSurface.Center) * sphericalSurface.RadiusInv; unitSpherePos.Z *= canonicalNormal.Z; //Console.WriteLine("unit sphere position: {0}", unitSpherePos); Vector2d originParametric = Sampler.SampleSphereWithUniformSpacingInverse( unitSpherePos, surfaceSinTheta, 1); // - convert direction // *- transform from camera space to local frame // *- compute normal at origin //Console.WriteLine("ray origin: {0}", ray.Origin); Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(ray.Origin); normalLocal.Normalize(); // TODO: check if it is unnecessary //Console.WriteLine("local normal: {0}", normalLocal); // *- create rotation quaternion from canonical normal to local // normal Vector3d direction = ray.Direction; //Console.WriteLine("local direction: {0}", direction); if (surface.Convex) { direction = -direction; } Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal); //Console.WriteLine("rotation axis: {0}", rotationAxis); if (rotationAxis.Length > 0) { double angle = Math.Acos(Vector3d.Dot(normalLocal, canonicalNormal)); //Console.WriteLine("angle: {0}", angle); double positionPhi = originParametric.Y; // first transformed to the frame of the local normal //Console.WriteLine("position phi: {0}", positionPhi); Matrix4d rotMatrix = Matrix4d.CreateFromAxisAngle(rotationAxis, -angle); // then rotate the local direction around Z using the position phi rotMatrix = rotMatrix * Matrix4d.CreateRotationZ(2 * Math.PI * -positionPhi); direction = Vector3d.Transform(direction, rotMatrix); } //Console.WriteLine("abs. direction: {0}", direction); // *- transform to hemispherical coordinates // - find out if it is within the local hemisphere double sinTheta = direction.Z / canonicalNormal.Z; double dirTheta = Math.Asin(sinTheta); double cosTheta = Math.Sqrt(1 - sinTheta * sinTheta); double dirPhi = Math.Atan2(direction.Y, direction.X); if (dirPhi < 0) { // map [-PI; PI] to [0; 2*PI] dirPhi += 2 * Math.PI; } // *- normalize Vector2d directionParametric = new Vector2d( dirTheta / (0.5 * Math.PI), dirPhi / (2 * Math.PI)); //Console.WriteLine("position parameters: {0}", new Vector2d( // originParametric.X, originParametric.Y)); return(new LensRayTransferFunction.Parameters( originParametric.X, originParametric.Y, directionParametric.X, directionParametric.Y)); }
public void RotateZ(double angle) { matrix = Matrix4d.CreateRotationZ(angle) * matrix; inverse_matrix *= Matrix4d.CreateRotationZ(-angle); }
public override Entity Create(Region tregion, byte[] data) { DataStream ds = new DataStream(data); DataReader dr = new DataReader(ds); GenericCharacterEntity ent = new GenericCharacterEntity(tregion); ent.SetPosition(Location.FromDoubleBytes(dr.ReadBytes(24), 0)); ent.SetOrientation(new BEPUutilities.Quaternion(dr.ReadFloat(), dr.ReadFloat(), dr.ReadFloat(), dr.ReadFloat())); ent.SetMass(dr.ReadFloat()); ent.CBAirForce = dr.ReadFloat(); ent.CBAirSpeed = dr.ReadFloat(); ent.CBCrouchSpeed = dr.ReadFloat(); ent.CBDownStepHeight = dr.ReadFloat(); ent.CBGlueForce = dr.ReadFloat(); ent.CBHHeight = dr.ReadFloat(); ent.CBJumpSpeed = dr.ReadFloat(); ent.CBMargin = dr.ReadFloat(); ent.CBMaxSupportSlope = dr.ReadFloat(); ent.CBMaxTractionSlope = dr.ReadFloat(); ent.CBProneSpeed = dr.ReadFloat(); ent.CBRadius = dr.ReadFloat(); ent.CBSlideForce = dr.ReadFloat(); ent.CBSlideJumpSpeed = dr.ReadFloat(); ent.CBSlideSpeed = dr.ReadFloat(); ent.CBStandSpeed = dr.ReadFloat(); ent.CBStepHeight = dr.ReadFloat(); ent.CBTractionForce = dr.ReadFloat(); ent.PreRot *= Matrix4d.CreateRotationX(dr.ReadFloat() * Utilities.PI180); ent.PreRot *= Matrix4d.CreateRotationY(dr.ReadFloat() * Utilities.PI180); ent.PreRot *= Matrix4d.CreateRotationZ(dr.ReadFloat() * Utilities.PI180); ent.mod_scale = dr.ReadFloat(); ent.PreRot = Matrix4d.Scale(ent.mod_scale) * ent.PreRot; ent.color = System.Drawing.Color.FromArgb(dr.ReadInt()); byte dtx = dr.ReadByte(); ent.Visible = (dtx & 1) == 1; ent.ShouldShine = (dtx & 32) == 32; int solidity = (dtx & (2 | 4 | 8 | 16)); if (solidity == 2) { ent.CGroup = CollisionUtil.Solid; } else if (solidity == 4) { ent.CGroup = CollisionUtil.NonSolid; } else if (solidity == (2 | 4)) { ent.CGroup = CollisionUtil.Item; } else if (solidity == 8) { ent.CGroup = CollisionUtil.Player; } else if (solidity == (2 | 8)) { ent.CGroup = CollisionUtil.Water; } else if (solidity == (2 | 4 | 8)) { ent.CGroup = CollisionUtil.WorldSolid; } else if (solidity == 16) { ent.CGroup = CollisionUtil.Character; } ent.model = tregion.TheClient.Models.GetModel(tregion.TheClient.Network.Strings.StringForIndex(dr.ReadInt())); dr.Close(); return(ent); }
public static void CalculateOrbit(ref LookAheadState lookAheadState, State state) { var mu = Constants.EarthGravitationalConstant; var radiusVector = state.Position; var velocityVector = state.Velocity; var h = Vector3d.Cross( radiusVector, velocityVector ); var r = radiusVector.Length; var eccentricityVector = ( (velocityVector.LengthSquared - mu / r) * radiusVector - Vector3d.Dot(radiusVector, velocityVector) * velocityVector ) / mu; var eccentricity = eccentricityVector.Length; var specificOrbitalEnergy = velocityVector.LengthSquared / 2 - mu / r; var semiMajorAxis = -mu / (2 * specificOrbitalEnergy); var semiMinorAxis = semiMajorAxis * Math.Sqrt(1 - eccentricity * eccentricity); var apoapsis = (1 + eccentricity) * semiMajorAxis; var periapsis = (1 - eccentricity) * semiMajorAxis; var semiLatusRectum = periapsis * (1 + eccentricity); var thetaFromPeriapsis = Math.Acos(((semiLatusRectum - r) / (eccentricity * r)) % (Math.PI * 2)); var actualRotation = Math.Atan2(radiusVector.Y, radiusVector.X) + Math.PI / 2; double argumentOfPeriapsis; if (h.Z < 0) { thetaFromPeriapsis = Math.PI * 2 - thetaFromPeriapsis; argumentOfPeriapsis = actualRotation - thetaFromPeriapsis; //rotationMatrix = Matrix4d.Mult(rotationMatrix, Matrix4d.RotateY(Math.PI)); } else { argumentOfPeriapsis = actualRotation - thetaFromPeriapsis; } var rotationMatrix = Matrix4d.CreateRotationZ(argumentOfPeriapsis); int highAccuracyPoints = lookAheadState.FuturePositions.Length / 2; double highAccuracyAngle = Math.PI / 20; if (SampleOrbit(ref lookAheadState.FuturePositions, ref rotationMatrix, semiLatusRectum, eccentricity, thetaFromPeriapsis, highAccuracyAngle, 0, highAccuracyPoints)) { SampleOrbit(ref lookAheadState.FuturePositions, ref rotationMatrix, semiLatusRectum, eccentricity, thetaFromPeriapsis - highAccuracyAngle, Math.PI * 2 - highAccuracyAngle, highAccuracyPoints, lookAheadState.FuturePositions.Length - highAccuracyPoints); } //double approximatePerimeter = Math.PI * (3 * (semiMajorAxis + semiMinorAxis) - Math.Sqrt((3*semiMajorAxis + semiMinorAxis) * (semiMajorAxis + 3*semiMinorAxis))); lookAheadState.Apoapsis = apoapsis - Constants.EarthRadius; lookAheadState.Periapsis = periapsis - Constants.EarthRadius; lookAheadState.Eccentricity = eccentricity; lookAheadState.SemiMajorAxis = semiMajorAxis; lookAheadState.SemiMinorAxis = semiMinorAxis; lookAheadState.SemiLatusRectum = semiLatusRectum; lookAheadState.ArgumentOfPeriapsis = argumentOfPeriapsis; lookAheadState.Theta = thetaFromPeriapsis; //Title = string.Format("e{0,2:F}, {1,2:F} km {2,2:F} km, r {3,2:F}, v {4,2:F} {5,2:F} {6,2:F} {7,2:F}, a{8,2:F} b{9,2:F}", e, (apoapsis - Constants.EarthRadius)/1000, (periapsis - Constants.EarthRadius) / 1000, (radiusVector.Length - Constants.EarthRadius) /1000, velocityVector.Length / 1000, theta2, actualRotation, offset, (a - Constants.EarthRadius)/1000, (b - Constants.EarthRadius)/1000); /* * GL.PushMatrix(); * //GL.Rotate(offset / Math.PI * 180, Vector3d.UnitZ); * GL.LineWidth(2f); * GL.Color3(1f, 0f, 0f); * GL.Begin(PrimitiveType.LineLoop); * for (var theta = 0.0; theta < Math.PI * 2.0; theta += 0.01) * { * GL.Vertex3(Math.Sin(theta) * b, Math.Cos(theta) * a + (apoapsis - a), 0); * } * GL.End(); * GL.PopMatrix(); */ }
/// <summary> /// Convert a ray with origin at the back or front lens surface from /// its parametric representation. /// </summary> /// <param name="position">Position on lens surface in parameteric /// representation (normalized hemispherical coordinates).</param> /// <param name="direction">Direction of the ray with respect to the /// local frame in parameteric representation (normalized hemispherical /// coordinates). /// </param> /// <param name="canonicalNormal">Normal of the lens surface /// hemisphere (typically (0,0,1) for the back surface or (0,0,-1) for /// the front surface).</param> /// <param name="surfaceSinTheta">Sine of the surface spherical cap /// theta angle.</param> /// <param name="sphericalSurface">Lens surface represented as a /// sphere.</param> /// <param name="surface">Lens surface with its normal field.</param> /// <returns>Ray corresponding to its parametric representation. /// </returns> public Ray ConvertParametersToSurfaceRay( LensRayTransferFunction.Parameters parameters, Vector3d canonicalNormal, double surfaceSinTheta, Sphere sphericalSurface, ElementSurface surface) { //Console.WriteLine("parameters->ray"); //Console.WriteLine("position parameters: {0}", parameters.Position); // uniform spacing sampling for LRTF sampling Vector3d unitSpherePos = Sampler.SampleSphereWithUniformSpacing( parameters.Position, surfaceSinTheta, 1); //Console.WriteLine("unit sphere position: {0}", unitSpherePos); unitSpherePos.Z *= canonicalNormal.Z; Vector3d lensPos = sphericalSurface.Center + sphericalSurface.Radius * unitSpherePos; //Console.WriteLine("ray origin: {0}", lensPos); // - get normal N at P Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(lensPos); // - compute direction D from spherical coordinates (wrt normal Z = (0,0,+/-1)) double theta = 0.5 * Math.PI * parameters.DirectionTheta; double phi = 2 * Math.PI * parameters.DirectionPhi; double cosTheta = Math.Cos(theta); Vector3d directionZ = new Vector3d( Math.Cos(phi) * cosTheta, Math.Sin(phi) * cosTheta, Math.Sin(theta) * canonicalNormal.Z); // - rotate D from Z to N frame // - using a (normalized) quaternion Q // - N and Z should be assumed to be already normalized // - more efficient method: Efficiently building a matrix to // rotate one vector to another [moller1999] normalLocal.Normalize(); // TODO: check if it is unnecessary //Console.WriteLine("abs. direction: {0}", directionZ); //Console.WriteLine("local normal: {0}", normalLocal); Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal); //Console.WriteLine("rotation axis: {0}", rotationAxis); Vector3d rotatedDir = directionZ; if (rotationAxis.Length > 0) { double angle = Math.Acos(Vector3d.Dot(canonicalNormal, normalLocal)); //Console.WriteLine("angle: {0}", angle); // first the local direction must be rotated around using the position phi! //Console.WriteLine("position phi: {0}", parameters.PositionPhi); Matrix4d rotMatrix = Matrix4d.CreateRotationZ(2 * Math.PI * parameters.PositionPhi); // only then can be transformed to the frame of the local normal rotMatrix = rotMatrix * Matrix4d.CreateFromAxisAngle(rotationAxis, angle); rotatedDir = Vector3d.Transform(directionZ, rotMatrix); } if (surface.Convex) { rotatedDir = -rotatedDir; } //Console.WriteLine("local direction: {0}", rotatedDir); Ray result = new Ray(lensPos, rotatedDir); return(result); }
/// <summary> /// 起動時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FormRotationMatrix_Load(object sender, EventArgs e) { #region glControlの追加 (デザイナが壊れるため) // // glControlReciProObjects // this.glControlReciProObjects = new GLControlAlpha { AllowMouseScaling = false, AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(273, 248), Margin = new Padding(0), Name = "glControlReciProObjects", NodeCoefficient = 1, ProjWidth = 1D, Size = new Size(130, 130), }; this.glControlReciProObjects.WorldMatrixChanged += new System.EventHandler(this.GlControlReciProAxes_WorldMatrixChanged); // // glControlReciProAxes // this.glControlReciProAxes = new GLControlAlpha { AllowMouseScaling = false, AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(273, 114), Margin = new Padding(0), Name = "glControlReciProAxes", NodeCoefficient = 1, ProjWidth = 2.8D, Size = new Size(130, 130), }; glControlReciProAxes.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged); // // glControlReciProGonio // this.glControlReciProGonio = new GLControlAlpha { AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(5, 114), Margin = new Padding(0), Name = "glControlReciProGonio", ProjWidth = 5D, Size = new Size(264, 264), }; glControlReciProGonio.WorldMatrixChanged += new EventHandler(this.GlControlReciProAxes_WorldMatrixChanged); // // glControlExpObjects // this.glControlExpObjects = new GLControlAlpha { AllowMouseScaling = false, AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(273, 248), Margin = new Padding(0), Name = "glControlExpObjects", ProjWidth = 1D, Size = new Size(130, 130), }; this.glControlExpObjects.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged); // // glControlExpAxes // this.glControlExpAxes = new GLControlAlpha { AllowMouseScaling = false, AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(273, 114), Margin = new System.Windows.Forms.Padding(0), Name = "glControlExpAxes", ProjWidth = 2.8D, Size = new Size(130, 130), }; this.glControlExpAxes.WorldMatrixChanged += new EventHandler(GlControlReciProAxes_WorldMatrixChanged); // // glControlExpGonio // this.glControlExpGonio = new GLControlAlpha { AllowMouseTranslating = false, Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right, BorderStyle = BorderStyle.Fixed3D, DisablingOpenGL = false, Location = new Point(5, 114), Margin = new Padding(0), Name = "glControlExpGonio", ProjWidth = 5D, Size = new Size(264, 264), }; this.glControlExpGonio.WorldMatrixChanged += new System.EventHandler(this.GlControlReciProAxes_WorldMatrixChanged); groupBox2.Controls.Add(glControlExpObjects); groupBox2.Controls.Add(glControlExpAxes); groupBox2.Controls.Add(glControlExpGonio); groupBox1.Controls.Add(glControlReciProObjects); groupBox1.Controls.Add(glControlReciProAxes); groupBox1.Controls.Add(glControlReciProGonio); #endregion glControlReciProGonio.WorldMatrix = Matrix4d.CreateRotationZ(-Math.PI / 4) * Matrix4d.CreateRotationX(-0.4 * Math.PI); SetRotation(); numericBoxPhi.TextBoxBackColor = numericBoxExp1.TextBoxBackColor = Color.FromArgb(255, 180, 180, 0); numericBoxTheta.TextBoxBackColor = numericBoxExp2.TextBoxBackColor = Color.FromArgb(255, 0, 180, 180); numericBoxPsi.TextBoxBackColor = numericBoxExp3.TextBoxBackColor = Color.FromArgb(255, 180, 0, 180); numericBoxPhi.TextBoxForeColor = numericBoxExp1.TextBoxForeColor = numericBoxTheta.TextBoxForeColor = numericBoxExp2.TextBoxForeColor = numericBoxPsi.TextBoxForeColor = numericBoxExp3.TextBoxForeColor = Color.FromArgb(255, 255, 255, 255); }