// Ignore, doesn't work. Bad. private static Vector3 EulerAnglesFromQuat(Quaternion q) { float singularityTest = q.Z * q.X - q.W * q.Y; float yawY = 2f * (q.W * q.Z + q.X * q.Y); float yawX = (float)(1f - 2f * (Math.Pow(q.Y, 2) + Math.Pow(q.Z, 2))); float singularityThreshold = 0.4999995f; Vector3 eulerAngles = Vector3.Zero; if (singularityTest < singularityThreshold) { eulerAngles.X = -90f; eulerAngles.Y = (float)Math.Atan2(yawY, yawX); eulerAngles.Z = WMath.Clamp(-eulerAngles.Y - (2f * (float)Math.Atan2(q.X, q.W)), (float)-Math.PI, (float)Math.PI); } else if (singularityTest > singularityThreshold) { eulerAngles.X = 90; eulerAngles.Y = (float)Math.Atan2(yawY, yawX); eulerAngles.Z = WMath.Clamp(eulerAngles.Y - (2f * (float)Math.Atan2(q.X, q.W)), (float)-Math.PI, (float)Math.PI); } else { eulerAngles.X = (float)Math.Asin(2f * (singularityTest)); eulerAngles.Y = (float)Math.Atan2(yawY, yawX); eulerAngles.Z = (float)Math.Atan2(-2f * (q.W * q.X + q.Y * q.Z), (1f - 2f * (Math.Pow(q.X, 2) + Math.Pow(q.Y, 2)))); } return(eulerAngles); }
private void CameraRotation() { Vector2D deltas = Input.MouseDelta; double ax = (Angles.X + (deltas.X * Input.MouseSensivity * Time.DeltaTime)) % 360.0D; double ay = WMath.Clamp((Angles.Y + (deltas.Y * Input.MouseSensivity * Time.DeltaTime)), -89.9D, 89.9D); Angles = new Vector2D(ax, ay); this.FPSCamera.WObject.Rotation = new Engine.Quaternion(-ay, ax, 0.0F); }
private void DoApplicationTick() { // Poll the mouse at a high resolution System.Drawing.Point mousePos = m_glControl.PointToClient(System.Windows.Forms.Cursor.Position); mousePos.X = WMath.Clamp(mousePos.X, 0, m_glControl.Width); mousePos.Y = WMath.Clamp(mousePos.Y, 0, m_glControl.Height); WInput.SetMousePosition(new Vector2(mousePos.X, mousePos.Y)); ProcessTick(); WInput.Internal_UpdateInputState(); m_glControl.SwapBuffers(); }
private void AnimateDisplayName() { ItemNameCooldown -= Time.Delta; if (ItemNameCooldown < 0.0) { ItemNameLabel.Enabled = false; } else if (ItemNameCooldown < ItemNameTime) { Color256 col = ItemNameLabel.Color; col.A = WMath.Clamp(ItemNameCooldown / ItemNameDisappearTime, 0, 1); ItemNameLabel.Color = col; } }
public void AnimateWalk(Vector3D velocity) { if (PlayerLeftLeg == null || PlayerRightLeg == null) { return; } double speed = WMath.Clamp(velocity.XZ.Length, 0, Player.WalkSpeed); CurrentWalkAnimationTime += Time.Delta * speed * WalkAnimationSpeedCoef; double t = WMath.Remap(Math.Cos(CurrentWalkAnimationTime), -1, 1, 0, 1); double speedCoef = speed <= 0.05D ? 0.0D : speed / Player.WalkSpeed; double currentAngle = WMath.Lerp(-WalkAnimationMaxAngle * speedCoef, WalkAnimationMaxAngle * speedCoef, t);//WMath.Remap(CurrentWalkAnimationTime, 0, 1, -WalkAnimationMaxAngle * speedCoef, WalkAnimationMaxAngle * speedCoef); Quaternion leftRotLeg = new Quaternion(-currentAngle * WalkAnimationLegCoef, 0, 0); Quaternion rightRotLeg = new Quaternion(currentAngle * WalkAnimationLegCoef, 0, 0); Quaternion rightRotArm = new Quaternion(-currentAngle, 0, 0); Quaternion leftRotArm = new Quaternion(currentAngle, 0, 0); PlayerLeftLeg.LocalRotation = leftRotLeg; PlayerRightLeg.LocalRotation = rightRotLeg; PlayerRightArm.LocalRotation *= rightRotArm; PlayerLeftArm.LocalRotation *= leftRotArm; Vector3D flattenVel = new Vector3D(velocity.X, 0, velocity.Z); Vector3D flattenDir = flattenVel.Normalized; double flattenSpeed = flattenVel.Length; if (flattenSpeed >= 0.1D) { double currentTorsoAngle = Quaternion.AngleY(PlayerTorso.Rotation, Quaternion.Identity); double rawNewAngle = (Math.Atan2(flattenDir.X, flattenDir.Z) * WMath.RadToDeg) * -1; double deltaAngle = WMath.DeltaAngle(currentTorsoAngle, rawNewAngle); deltaAngle = WMath.Clamp(deltaAngle, -HeadMaxAngleToBody, HeadMaxAngleToBody); PlayerTorso.LocalRotation *= new Quaternion(0, -deltaAngle * WalkAnimationTorsoOrientCoef * Time.Delta, 0); } }
public static void GlobalToLocal(Vector3F global, out Vector3I ChunkPosition, out Vector3I LocalPosition) { ChunkPosition = new Vector3I( ((int)global.X / Chunk.Width) + (global.X < 0.0F ? -1 : 0), //X position ((int)global.Z / Chunk.Depth) + (global.Z < 0.0F ? -1 : 0), //Y position 0); //Z dimension float localX = global.X % Chunk.Width; if (localX < 0) { localX += Chunk.Width; } float localZ = global.Z % Chunk.Depth; if (localZ < 0) { localZ += Chunk.Depth; } LocalPosition = new Vector3I((int)localX, WMath.Clamp((int)global.Y, 0, 255), (int)localZ); }
private void RenderFrame() { m_frameBuffer.Bind(); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); GL.Viewport(0, 0, m_frameBuffer.Width, m_frameBuffer.Height); float deltaTime = m_dtStopwatch.ElapsedMilliseconds / 1000f; m_dtStopwatch.Restart(); m_renderCamera.Tick(deltaTime); m_lineBatcher.Tick(deltaTime); m_skeletonLineBatcher.Tick(deltaTime); deltaTime = WMath.Clamp(deltaTime, 0, 0.25f); // quarter second max because debugging m_timeSinceStartup += deltaTime; if (m_modelRenderOptions.AnimateLight) { // Rotate our light float angleInRad = m_timeSinceStartup % WMath.DegreesToRadians(360f); m_mainLight.Position = new Vector4(CalculateLightPosition(angleInRad), 0); } if (m_modelRenderOptions.ShowGrid) { DrawFixedGrid(); } if (m_modelRenderOptions.DepthPrePass) { foreach (var j3d in m_loadedModels) { // Render a depth-only pre pass. We need to tell it to render translucent and opaque objects so that // they both write in to the depth buffer (it's a specific pre-pass so they should) j3d.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix, Matrix4.Identity, true, true, true); } } foreach (var j3d in m_loadedModels) { j3d.Tick(deltaTime); } foreach (var j3d in m_loadedModels) { j3d.SetHardwareLight(0, m_mainLight); j3d.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix, Matrix4.Identity, true, false); } foreach (var j3d in m_loadedModels) { // Do a second render pass after all objects to render translucent ones. j3d.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix, Matrix4.Identity, false, true); } if (m_modelRenderOptions.ShowPivot) { m_lineBatcher.DrawLine(Vector3.Zero, new Vector3(50, 0, 0), WLinearColor.Red, 0, 0); m_lineBatcher.DrawLine(Vector3.Zero, new Vector3(0, 50, 0), WLinearColor.Green, 0, 0); m_lineBatcher.DrawLine(Vector3.Zero, new Vector3(0, 0, 50), WLinearColor.Blue, 0, 0); } if (m_modelRenderOptions.ShowBoundingBox) { foreach (var j3d in m_loadedModels) { j3d.DrawBoundsForShapes(true, false, m_lineBatcher); } } if (m_modelRenderOptions.ShowBoundingSphere) { foreach (var j3d in m_loadedModels) { j3d.DrawBoundsForShapes(false, true, m_lineBatcher); } } if (m_modelRenderOptions.ShowBoneBoundingBox) { foreach (var j3d in m_loadedModels) { j3d.DrawBoundsForJoints(true, false, m_lineBatcher); } } if (m_modelRenderOptions.ShowBoneBoundingSphere) { foreach (var j3d in m_loadedModels) { j3d.DrawBoundsForJoints(false, true, m_lineBatcher); } } if (m_modelRenderOptions.ShowBones) { foreach (var j3d in m_loadedModels) { j3d.DrawBones(m_skeletonLineBatcher); } } // Debug Rendering if (WInput.GetKey(Key.I)) { GL.Disable(EnableCap.CullFace); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.DstAlpha, BlendingFactorDest.Zero); m_alphaVisualizationShader.Bind(); m_screenQuad.Draw(); } // Blit the framebuffer to the backbuffer so it shows up on screen. m_lineBatcher.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix); m_skeletonLineBatcher.Render(m_renderCamera.ViewMatrix, m_renderCamera.ProjectionMatrix, true); m_frameBuffer.BlitToBackbuffer(m_viewportWidth, m_viewportHeight); }
protected internal override void Update() { base.Update(); if (!Hovered && Editing && Input.IsPressing(Keys.MouseLeftButton)) { Editing = false; this.OnLeaveEdit?.Invoke(); } if (!Graphics.Window.Focused) { Editing = false; } bool textEdited = false; int chars = Text == null ? 0 : Text.Length; KeysModifiers modifiers = Input.GetModifiers(); if (Editing) { Keys[] keys = Input.GetAllKeys(KeyStates.Pressing); for (int i = 0; i < keys.Length; i++) { if (keys[i] != Keys.Back && Text?.Length >= MaxChars) { Text = Text.Substring(0, MaxChars); textEdited = true; break; } if (keys[i].IsKeyboard() && !keys[i].IsModifier()) { if (keys[i] == Keys.Escape || keys[i] == Keys.Enter) { bool stop = true; if (AllowNewLine) { if (modifiers.HasFlag(KeysModifiers.Shift)) { stop = false; Text += "\n"; textEdited = true; } } if (stop) { this.Editing = false; this.OnLeaveEdit?.Invoke(); break; } } else if (keys[i] == Keys.Back) { Text = Text.Substring(0, WMath.Clamp(Text.Length - 1, 0, int.MaxValue)); textEdited = true; } else if (keys[i] == Keys.Space) { Text += " "; textEdited = true; } else if (keys[i] == Keys.Tab) { Text += " "; textEdited = true; } else { textEdited = true; Text += keys[i].ToString(modifiers); } } } } if (_FirstRun || textEdited) { _FirstRun = false; if (!string.IsNullOrEmpty(this.Text)) { this.Label.Color = this.TextColor; this.Label.Text = this.Text; } else { this.Label.Color = this.EmptyTextColor; this.Label.Text = this.EmptyText; } } if (Editing) { this.IdleColor = this.EditingColor; this.HoverColor = this.EditingColor; } else { this.IdleColor = this.NotEditingColor; this.HoverColor = this.TextInputHoverColor; } }
public void Render(Matrix4 viewMatrix, Matrix4 projectionMatrix, Matrix4 modelMatrix) { m_viewMatrix = viewMatrix; m_projMatrix = projectionMatrix; m_modelMatrix = modelMatrix; IList <SkeletonJoint> boneList = (m_currentBoneAnimation != null) ? JNT1Tag.AnimatedJoints : JNT1Tag.BindJoints; Matrix4[] boneTransforms = new Matrix4[boneList.Count]; ApplyBonePositionsToAnimationTransforms(boneList, boneTransforms); // Assume that all bone animations constantly invalidate the skinning. if (m_currentBoneAnimation != null) { m_skinningInvalid = true; } // We'll only transform the position and normal vertices if skinning has been invalidated. if (m_skinningInvalid) { foreach (var shape in SHP1Tag.Shapes) { var transformedPositions = new List <Vector3>(shape.VertexData.Position.Count); var transformedNormals = new List <Vector3>(shape.VertexData.Normal.Count); //List<WLinearColor> colorOverride = new List<WLinearColor>(); for (int i = 0; i < shape.VertexData.Position.Count; i++) { // This is relative to the vertex's original packet's matrix table. ushort posMtxIndex = (ushort)(shape.VertexData.PositionMatrixIndexes[i]); // We need to calculate which packet data table that is. int originalPacketIndex = 0; for (int p = 0; p < shape.MatrixDataTable.Count; p++) { if (i >= shape.MatrixDataTable[p].FirstRelevantVertexIndex && i < shape.MatrixDataTable[p].LastRelevantVertexIndex) { originalPacketIndex = p; break; } } // Now that we know which packet this vertex belongs to, we can get the index from it. // If the Matrix Table index is 0xFFFF then it means "use previous", and we have to // continue backwards until it is no longer 0xFFFF. ushort matrixTableIndex; do { matrixTableIndex = shape.MatrixDataTable[originalPacketIndex].MatrixTable[posMtxIndex]; originalPacketIndex--; } while (matrixTableIndex == 0xFFFF); bool isPartiallyWeighted = DRW1Tag.IsPartiallyWeighted[matrixTableIndex]; ushort indexFromDRW1 = DRW1Tag.TransformIndexTable[matrixTableIndex]; Matrix4 finalMatrix = Matrix4.Zero; if (isPartiallyWeighted) { EVP1.Envelope envelope = EVP1Tag.Envelopes[indexFromDRW1]; for (int b = 0; b < envelope.NumBones; b++) { Matrix4 sm1 = EVP1Tag.InverseBindPose[envelope.BoneIndexes[b]]; Matrix4 sm2 = boneTransforms[envelope.BoneIndexes[b]]; finalMatrix = finalMatrix + Matrix4.Mult(Matrix4.Mult(sm1, sm2), envelope.BoneWeights[b]); } } else { // If the vertex is not weighted then we use a 1:1 movement with the bone matrix. finalMatrix = boneTransforms[indexFromDRW1]; } // Multiply the data from the model file by the finalMatrix to put it in the correct (skinned) position transformedPositions.Add(Vector3.Transform(shape.VertexData.Position[i], finalMatrix)); if (shape.VertexData.Normal.Count > 0) { Vector3 transformedNormal = Vector3.TransformNormal(shape.VertexData.Normal[i], finalMatrix); transformedNormals.Add(transformedNormal); } //colorOverride.Add(isPartiallyWeighted ? WLinearColor.Black : WLinearColor.White); } // Re-upload to the GPU. shape.OverrideVertPos = transformedPositions; //shape.VertexData.Color0 = colorOverride; if (transformedNormals.Count > 0) { shape.OverrideNormals = transformedNormals; } shape.UploadBuffersToGPU(true); } m_skinningInvalid = false; } //if (WInput.GetKeyDown(System.Windows.Input.Key.O)) // m_shapeIndex--; //if (WInput.GetKeyUp(System.Windows.Input.Key.P)) // m_shapeIndex++; m_shapeIndex = WMath.Clamp(m_shapeIndex, 0, SHP1Tag.ShapeCount - 1); RenderMeshRecursive(INF1Tag.HierarchyRoot); // We're going to restore some semblance of state after rendering ourselves, as models often modify weird and arbitrary GX values. GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Enable(EnableCap.CullFace); GL.CullFace(CullFaceMode.Back); GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); GL.Enable(EnableCap.Dither); }
public static ushort[] CreateTerrain(int chunkx, int chunky, bool save = false, bool erase = false) { ushort[] blocks = new ushort[Chunk.Width * Chunk.Height * Chunk.Depth]; string id; ushort cacheindex = 0; Dictionary <string, ushort> idscache = new Dictionary <string, ushort>(); for (int z = 0; z < Chunk.Depth; z++) { for (int y = 0; y < Chunk.Height; y++) { for (int x = 0; x < Chunk.Width; x++) { id = "winecrash:air"; const float scale = 0.025F; const float contScale = 0.001F; const float mountainScale = 0.005F; const float shiftX = 0; //Début des farlands : 16000000 | Grosses Farlands : 200000000 const float shiftZ = 0; //todo: auré tu fais chier avec tes commentaires. const float caveScale = 0.1F; const float thresold = 0.3F; float xsample = (chunkx * Chunk.Width + shiftX + x); float ysample = (chunky * Chunk.Depth + shiftZ + z); float continentValue = continents.GetValue(xsample * contScale, ysample * contScale); double continentalHeight = WMath.Remap(WMath.Clamp(Math.Exp(continentValue), 0.0, 65.0), -1.0D, 1.0D, 55.0D, 63.0D); float landValue = details.GetValue(xsample * scale, ysample * scale); double landHeight = WMath.Remap(landValue, -1.0D, 1.0D, 0.0D, 30.0D); float mountainValue = (float)WMath.Remap(mountainMult.GetValue(xsample * mountainScale, ysample * mountainScale), -1.0, 1.0, 0.0, 1.0); mountainValue = (float)WMath.Clamp(Math.Pow(mountainValue, 4.0), 0.0, 1.0); double final = continentalHeight + (landHeight * mountainValue); int height = (int)final; bool waterlevel = height < 64; if (y == height) { if (waterlevel) { id = "winecrash:sand"; //sand } else { id = "winecrash:grass"; //grass } } else if (y < height) { if (y > height - 3) { if (waterlevel) { id = "winecrash:sand"; //sand } else { id = "winecrash:dirt"; //dirt } } else { id = "winecrash:stone"; } } /*if(isCave) * { * id = "winecrash:air"; * }*/ if (y == 2) { if (World.WorldRandom.NextDouble() < 0.33D) { id = "winecrash:bedrock"; } } else if (y == 1) { if (World.WorldRandom.NextDouble() < 0.66D) { id = "winecrash:bedrock"; } } else if (y == 0) { id = "winecrash:bedrock"; } if (!idscache.TryGetValue(id, out cacheindex)) { cacheindex = ItemCache.GetIndex(id); idscache.Add(id, cacheindex); } //Server.Log(id); blocks[x + Chunk.Width * y + Chunk.Width * Chunk.Height * z] = cacheindex;//new Block(id); } } } if (save) { string fileName = "save/" + $"c{chunkx}_{chunky}.json"; if (erase) { File.WriteAllText(fileName, ToJSON(blocks)); } else if (!File.Exists(fileName)) { File.WriteAllText(fileName, ToJSON(blocks)); } } return(blocks); }
protected override void Update() { if (Input.IsPressing(Keys.End)) { FreeCTRL = !FreeCTRL; } if (!FreeCTRL) { return; } double newSpeed = Input.MouseScrollDelta * MoveScrollSensivity * Time.DeltaTime; this.MoveSpeed += newSpeed + MoveSpeed * Input.MouseScrollDelta * 0.2D; this.MoveSpeed = WMath.Clamp(this.MoveSpeed, 0.01D, double.PositiveInfinity); //if(Input.IsPressed(Keys.Mouse)) //Debug.Log(this.WObject.Position); /*Vector2D deltas = Input.MouseDelta; * * double ax = (Angles.X + (deltas.X * Input.MouseSensivity * (float)Time.DeltaTime)) % 360.0F; * double ay = WMath.Clamp((Angles.Y + (deltas.Y * Input.MouseSensivity * (float)Time.DeltaTime)), -90.0F, 90.0F); * * Angles = new Vector2D(ax, ay); * * this.WObject.Rotation = new Quaternion(-ay, ax, 0.0F);*/ Vector3D fwd = this.WObject.Forward; Vector3D rght = this.WObject.Right; Vector3D up = this.WObject.Up; Vector3D pos = this.WObject.Position; if (Input.IsPressed(Keys.Z)) { fwd *= MoveSpeed * Time.DeltaTime; } else if (Input.IsPressed(Keys.S)) { fwd *= -MoveSpeed * Time.DeltaTime; } else { fwd *= 0.0D; } if (Input.IsPressed(Keys.Q)) { rght *= -MoveSpeed * Time.DeltaTime; } else if (Input.IsPressed(Keys.D)) { rght *= MoveSpeed * Time.DeltaTime; } else { rght *= 0.0D; } if (Input.IsPressed(Keys.Space)) { up *= MoveSpeed * Time.DeltaTime; } else if (Input.IsPressed(Keys.LeftShift)) { up *= -MoveSpeed * Time.DeltaTime; } else { up *= 0.0D; } Player.Instance.WObject.Position += fwd - rght + up; if (Input.IsPressed(Keys.F3) && Input.IsPressing(Keys.A)) { Debug.Log("Reconstructing"); Debug.Log(Chunk.Chunks.Count); foreach (Chunk chunk in Chunk.Chunks) { Task.Run(chunk.Construct); } } if (Input.IsPressing(Keys.K)) { //Player.Instance.WObject.Position = new Vector3F(140_000_000F, 128F, 0.0F); Player.Instance.ForceInvokeChunkChange(); } }
public Sweep SweepCollide(Chunk c, BoxCollider b) { //force = Vector3D.Zero; //translation = Vector3D.Zero; RigidBody rb = b.WObject.GetModule <RigidBody>(); Vector3D bc = b.Center; Vector3D be = b.Extents * 4; Vector3D cc = c.WObject.Position + Vector3D.Up * Chunk.Height / 2.0D + Vector3D.Right * Chunk.Width / 2.0D + Vector3D.Forward * Chunk.Depth / 2.0D; Vector3D ce = Vector3D.One * new Vector3D(Chunk.Width, Chunk.Height, Chunk.Depth) / 2.0D; // if outside of chunk, no collision. if ( //Y cc.Y - ce.Y > bc.Y + be.Y || // if too low cc.Y + ce.Y < bc.Y - be.Y || // if too high //X cc.X - ce.X > bc.X + be.X || // if too much left cc.X + ce.X < bc.X - be.X || // if too much right //Z cc.Z - ce.Z > bc.Z + be.Z || // if too much behind cc.Z + ce.Z < bc.Z - be.Z // if too much forward ) { return(new Sweep()); } else // the box collider is within the chunk { // max coords Vector3D max = bc + be; Vector3D min = bc - be; Vector3D cmax = new Vector3D( WMath.Clamp(max.X, c.Coordinates.X * Chunk.Width, c.Coordinates.X * Chunk.Width + (Chunk.Width - 1)), WMath.Clamp(max.Y, 0, 255), WMath.Clamp(max.Z, c.Coordinates.Y * Chunk.Depth, c.Coordinates.Y * Chunk.Depth + (Chunk.Depth - 1)) ); Vector3D cmin = new Vector3D( WMath.Clamp(min.X, c.Coordinates.X * Chunk.Width, c.Coordinates.X * Chunk.Width + (Chunk.Width - 1)), WMath.Clamp(min.Y, 0, 255), WMath.Clamp(min.Z, c.Coordinates.Y * Chunk.Depth, c.Coordinates.Y * Chunk.Depth + (Chunk.Depth - 1)) ); World.GlobalToLocal(cmax, out _, out Vector3I maxBpos); World.GlobalToLocal(cmin, out _, out Vector3I minBpos); List <AABBCollider> colliders = new List <AABBCollider>(); for (int z = minBpos.Z; z <= maxBpos.Z; z++) { for (int y = minBpos.Y; y <= maxBpos.Y; y++) { for (int x = minBpos.X; x <= maxBpos.X; x++) { if (c[x, y, z].Collides) { Vector3D blockExtents = new Vector3D(0.5D); Vector3D blockCenter = new Vector3D(x + c.Coordinates.X * Chunk.Width, y, z + c.Coordinates.Y * Chunk.Depth) + blockExtents; FreeBoxCollider collider = new FreeBoxCollider() { Center = blockCenter, Extents = blockExtents }; colliders.Add(collider); } } } } Sweep resultingSweep = new BoxBoxCollisionProvider().SweepCollideInto(b, rb.Velocity * Time.PhysicsDelta, colliders.ToArray()); for (int i = 0; i < colliders.Count; i++) { colliders[i].Delete(); } colliders.Clear(); colliders = null; return(resultingSweep); } }