public Vector3 Normal(Vector3 a, Vector3 b, Vector3 c) { var dir = Vector3.Cross(b - a, c - a); var norm = Vector3.Normalize(dir); return(norm); }
/// <summary> /// Set the pitch of the camera to an angle in degreees. /// </summary> /// <param name="angle">The camera's new pitch (clamped 0 to 360).</param> public void RotatePitchTo(float angle) { pitch = angle; //pitch constraints of (0 < pitch <= 360) if (pitch >= 360) { pitch %= 360; } if (pitch < 0) { pitch = 360 + (pitch % -360); } //Simple 2d trig. Excluding roll, the right axis will always be parallel to the X/Z plane. //With this assumption, the right axis will always lie on the unit circle. float pitchRad = pitch * (MathHelper.Pi / 180f); rightAxis.X = (float)Math.Cos(pitchRad); rightAxis.Z = (float)Math.Sin(pitchRad); //Use this to recalculate the proper position of the up axis, without it we get shrinking/scaling issues because the axes are not coordinated //not necessary to rotate right axis in RotUpAxis because the right vector is always parallel to the X/Z plane RotateHeading(0); //update the lookAxis lookAxis = Vector3.Normalize(Vector3.Cross(rightAxis, upAxis)); //update the view matrix so our changes are reflected in the world RebuildView(); }
protected override void OnMouseMove(MouseEventArgs e) { float deltaX = e.Location.X - mPreviousMousePosition.X; float deltaY = e.Location.Y - mPreviousMousePosition.Y; switch (e.Button) { case MouseButtons.Left: { float cameraSpeed = ModifierKeys.HasFlag(Keys.Shift) ? 0.04f : ModifierKeys.HasFlag(Keys.Control) ? 0.00125f : 0.005f; var dirRight = Vector3.Normalize(Vector3.Cross(mCamDirection, sCamUp)); var dirUp = Vector3.Normalize(Vector3.Cross(mCamDirection, dirRight)); mCamPosition -= (dirRight * deltaX + dirUp * deltaY) * cameraSpeed; break; } case MouseButtons.Right: mCamRotation.X += deltaX * 0.1f; mCamRotation.Y -= deltaY * 0.1f; break; } if (e.Button != MouseButtons.None) { mShouldRedraw = true; } mPreviousMousePosition = e.Location; base.OnMouseMove(e); }
private void calculateNormals() { int triangleIndex = 0; for (int i = 0; i < normals.Length - 2; i++) { Vector3 A = vertices[indices[triangleIndex]]; Vector3 B = vertices[indices[triangleIndex + 1]]; Vector3 C = vertices[indices[triangleIndex + 2]]; Vector3 norm = Vector3.Normalize(Vector3.Cross(C - A, B - A)); normals[i] += norm; normals[i + 1] += norm; normals[i + 2] += norm; normals[i] = Vector3.Normalize(normals[i]); normals[i + 1] = Vector3.Normalize(normals[i + 1]); normals[i + 2] = Vector3.Normalize(normals[i + 2]); verticesData[i, 1] += norm; verticesData[i + 1, 1] += norm; verticesData[i + 2, 1] += norm; verticesData[i, 1] = Vector3.Normalize(verticesData[i, 1]); verticesData[i + 1, 1] = Vector3.Normalize(verticesData[i + 1, 1]); verticesData[i + 2, 1] = Vector3.Normalize(verticesData[i + 2, 1]); triangleIndex += 3; } }
public float intersects(Sphere sphere, ref Vector3 collisionPoint, ref Vector3 surfaceNormal) { float t = intersects(sphere); if (t < float.PositiveInfinity) { // get the collision point and surface normal this.Direction.Normalize(); collisionPoint = this.Origin + (Vector3)((float)t * this.Direction); surfaceNormal = Vector3.Subtract(collisionPoint, sphere.Position); surfaceNormal.Normalize(); collisionPoint = sphere.Position + sphere.Radius * surfaceNormal; } return t; }
/// <summary> /// Make this camera look at a specific point in the world. /// </summary> /// <param name="position">The point to look at.</param> public void LookAt(Vector3 position) { //store the line between the camera and the other IPoint3D, but only on the X/Z plane, then normalize it to get a unit vector. Vector2 pitchVec = Vector2.Normalize(new Vector2(position.X - Position.X, position.Z - Position.Z)); //convert vector to angle and roatate the right axis to that angle RotatePitchTo((float)(Math.Atan2(pitchVec.Y, pitchVec.X) * (180f / MathHelper.Pi) - 90)); //update lookAxis, the normalized vector of the line between this camera and the IPoint3D. lookAxis = Vector3.Normalize(Vector3.Subtract(position, Position)); //update the heading variable and upAxis RotateHeadingTo((float)Math.Asin(-lookAxis.Y) * (180f / MathHelper.Pi)); //update the view matrix so our changes are reflected in the world RebuildView(); }
public void RotateCamera(float angle, Rotation rotation) { Matrix4 rot; switch (rotation) { case RSSE2.Rotation.RollLeft: rot = Matrix4.CreateFromAxisAngle(direction, -angle / 180 * MathHelper.Pi); break; case RSSE2.Rotation.RollRight: rot = Matrix4.CreateFromAxisAngle(direction, angle / 180 * MathHelper.Pi); break; case Rotation.YawLeft: rot = Matrix4.CreateFromAxisAngle(top, angle / 180 * MathHelper.Pi); break; case Rotation.YawRight: rot = Matrix4.CreateFromAxisAngle(top, -angle / 180 * MathHelper.Pi); break; case Rotation.PitchUp: rot = Matrix4.CreateFromAxisAngle(OpenTK.Vector3.Cross(top, direction), -angle / 180 * MathHelper.Pi); break; case Rotation.PitchDown: rot = Matrix4.CreateFromAxisAngle(OpenTK.Vector3.Cross(top, direction), angle / 180 * MathHelper.Pi); break; default: rot = Matrix4.Identity; break; } direction = new OpenTK.Vector3(new Vector4(direction) * rot); direction.Normalize(); top = new OpenTK.Vector3(new Vector4(top) * rot); top.Normalize(); Paint(); }
private void UpdateCamera() { float x = MathHelper.DegreesToRadians(mCamRotation.X); float y = MathHelper.DegreesToRadians(mCamRotation.Y); float yCos = ( float )Math.Cos(y); var front = new Vector3 { X = ( float )Math.Cos(x) * yCos, Y = ( float )Math.Sin(y), Z = ( float )Math.Sin(x) * yCos }; mCamDirection = Vector3.Normalize(front); float cameraSpeed = (ModifierKeys & SPEED_UP_KEY) != 0 ? CAMERA_SPEED_FAST : (ModifierKeys & SLOW_DOWN_KEY) != 0 ? CAMERA_SPEED_SLOW : CAMERA_SPEED; if (mUp && !mDown) { mCamPosition += mCamDirection * cameraSpeed; } else if (mDown && !mUp) { mCamPosition -= mCamDirection * cameraSpeed; } if (mLeft && !mRight) { mCamPosition -= Vector3.Normalize(Vector3.Cross(mCamDirection, sCamUp)) * cameraSpeed; } else if (mRight && !mLeft) { mCamPosition += Vector3.Normalize(Vector3.Cross(mCamDirection, sCamUp)) * cameraSpeed; } if (mLeft || mRight || mUp || mDown) { mShouldRedraw = true; } }
/// <summary> /// Set the heading of the camera as an angle in degrees. /// </summary> /// <param name="angle">The camera's new heading (clamped -90 to 90).</param> public void RotateHeadingTo(float angle) { heading = angle; //heading constraints of (-90 <= heading <= 90) if (heading >= 90) { heading = 90; } if (heading <= -90) { heading = -90; } //the radius of the circle that the up axis will have to lie on - think of a unit sphere as differently sized circles stacked vertically. float headingRad = heading * (MathHelper.Pi / 180f); float radius = (float)Math.Sin(headingRad); //The cos of the heading will get us the height of the up axis. upAxis.Y = (float)Math.Cos(headingRad); //X and Z: rotate right axis 90 degrees for the direction of upAxis on the X/Z plane, //use cos/sin to get the X and Z coordinates in the unit circle in the middle of the sphere (think of stacked circles again), //scale by our new radius to get X and Z coordinates on the circle that upAxis.Y is on (multiply by radius) float headingDirection = (pitch + 90) * (MathHelper.Pi / 180f); upAxis.X = radius * (float)Math.Cos(headingDirection); upAxis.Z = radius * (float)Math.Sin(headingDirection); //update the lookAxis lookAxis = Vector3.Normalize(Vector3.Cross(rightAxis, upAxis)); //update the view matrix so our changes are reflected in the world RebuildView(); }
public void PreviewMesh(Mesh mesh) { _mesh = mesh; viewMatrixData = Matrix4.CreateRotationY(-(float)Math.PI / 4) * Matrix4.CreateRotationX(-(float)Math.PI / 6); if (_vaoModel != 0) { GL.DeleteVertexArray(_vaoModel); GL.DeleteBuffer(_indexBufferObject); GL.DeleteBuffer(_vertexBufferObject); } Visible = true; // Vertices verticeData = new float[mesh.m_Vertices.Length * 2]; for (int v = 0; v < mesh.m_Vertices.Length; v += 3) { for (int i = 0; i < 3; i++) { verticeData[v * 2 + i] = mesh.m_Vertices[v + i]; } } // Calculate Bounding float[] min = new float[3]; float[] max = new float[3]; for (int i = 0; i < 3; i++) { min[i] = verticeData[i]; max[i] = verticeData[i]; } for (int v = 0; v < verticeData.Length; v += 6) { for (int i = 0; i < 3; i++) { min[i] = Math.Min(min[i], verticeData[v + i]); max[i] = Math.Max(max[i], verticeData[v + i]); } } // Calculate modelMatrix Vector3 dist = Vector3.One, offset = Vector3.Zero; for (int i = 0; i < 3; i++) { dist[i] = max[i] - min[i]; offset[i] = (max[i] + min[i]) / 2; } float d = Math.Max(1e-5f, dist.Length); modelMatrixData = Matrix4.CreateTranslation(-offset) * Matrix4.CreateScale(2f / d); // Indicies indiceData = mesh.m_SubMeshes.SelectMany(m => m.indices).ToArray(); // calculate normal by ourself int[] normalCalculatedCount = new int[verticeData.Length / 6]; for (int i = 0; i < indiceData.Length; i += 3) { Vector3 vertex0 = new Vector3(verticeData[indiceData[i + 0] * 6], verticeData[indiceData[i + 0] * 6 + 1], verticeData[indiceData[i + 0] * 6 + 2]); Vector3 vertex1 = new Vector3(verticeData[indiceData[i + 1] * 6], verticeData[indiceData[i + 1] * 6 + 1], verticeData[indiceData[i + 1] * 6 + 2]); Vector3 vertex2 = new Vector3(verticeData[indiceData[i + 2] * 6], verticeData[indiceData[i + 2] * 6 + 1], verticeData[indiceData[i + 2] * 6 + 2]); Vector3 normal = Vector3.Cross(vertex1 - vertex0, vertex2 - vertex0); normal.Normalize(); for (int j = 0; j < 3; j++) { verticeData[indiceData[i + j] * 6 + 3] += normal.X; verticeData[indiceData[i + j] * 6 + 4] += normal.Y; verticeData[indiceData[i + j] * 6 + 5] += normal.Z; normalCalculatedCount[indiceData[i + j]]++; } } for (int i = 0; i < normalCalculatedCount.Length; i++) { if (normalCalculatedCount[i] == 0) { verticeData[i * 6 + 3] = 0; verticeData[i * 6 + 4] = 1; verticeData[i * 6 + 5] = 0; } else { verticeData[i * 6 + 3] /= normalCalculatedCount[i]; verticeData[i * 6 + 4] /= normalCalculatedCount[i]; verticeData[i * 6 + 5] /= normalCalculatedCount[i]; } } _vertexBufferObject = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferObject); GL.BufferData(BufferTarget.ArrayBuffer, verticeData.Length * sizeof(float), verticeData, BufferUsageHint.StaticDraw); _indexBufferObject = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBufferObject); GL.BufferData(BufferTarget.ElementArrayBuffer, indiceData.Length * sizeof(uint), indiceData, BufferUsageHint.StaticDraw); _vaoModel = GL.GenVertexArray(); GL.BindVertexArray(_vaoModel); var positionLocation = _shader.GetAttribLocation("aPos"); GL.EnableVertexAttribArray(positionLocation); GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0); var normalLocation = _shader.GetAttribLocation("aNormal"); GL.EnableVertexAttribArray(normalLocation); GL.VertexAttribPointer(normalLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float)); ChangeGLSize(Size); Invalidate(); }
protected override void Update(float deltaTime) { GameLogic(); Vector3 vel = inputDir(); if (vel != Vector3.Zero) { if (vel != Vector3.Zero) { vel.Normalize(); } if (UseGlobalForward) { vel = new Vector3(new Vector4(vel, 0) * Owner.GetWorldTransform()); } Vector3 vec = new Vector3(vel.X * deltaTime * MoveSpeed, vel.Y * deltaTime * JumpForce, vel.Z * deltaTime * MoveSpeed); Byt3.Engine.Physics.BEPUutilities.Vector3 v = new Byt3.Engine.Physics.BEPUutilities.Vector3(vec.X, vec.Y, vec.Z); Collider.PhysicsCollider.ApplyLinearImpulse(ref v); } if (Grounded) { CurrentGravity = 0; } else { CurrentGravity += GravityIncUngrounded * deltaTime; } Byt3.Engine.Physics.BEPUutilities.Vector3 grav = new Vector3(0, -CurrentGravity, 0); Collider.PhysicsCollider.ApplyLinearImpulse(ref grav); if (jump && Grounded) { Byt3.Engine.Physics.BEPUutilities.Vector3 jumpAcc = computeJumpAcc(); Collider.PhysicsCollider.ApplyLinearImpulse(ref jumpAcc); AudioSource.Clip = JumpSound; AudioSource.Play(); } if (Mouse.GetCursorState().LeftButton == ButtonState.Pressed) { time += deltaTime; if (time >= BulletThreshold) { time = 0; SpawnProjectile(); } } else { { time = 0; } } }
public vec3 normalize(vec3 v) { v.Normalize(); return(v); }