public override void Update(float deltaTime) { //While the bullet hasnt hit anything, be a bullet if (!hasHit) { //Set Vector3 to forward MthLib.Vector3 move = new MthLib.Vector3(0f, -speed * deltaTime, 0f); //Create a rotation matrix MthLib.Matrix3 rotMatrix = new MthLib.Matrix3(); //MathLibrary uses radians, while Raylib uses degrees rotMatrix.SetRotateZ(local.rotation * (float)(Math.PI / 180f)); //Rotate movement to be in the dirrection the bullet is facing, and update local local.point += rotMatrix * move; //Check for collision Collision(); } else { //Display smoke for set amount of time, then delete object count += deltaTime; if (count >= 0.1f) { //Destroy the bullet FreeMemory(); return; } } }
public static bool PointOBBcolliding(MthLib.Vector3 point, MthLib.Matrix3 obb) { //Find nessesary values MthLib.Vector3 diff = point - new MthLib.Vector3(obb.m3, obb.m6, 0); MthLib.Vector3 xExtent = new MthLib.Vector3(obb.m1, obb.m4, 0); MthLib.Vector3 yExtent = new MthLib.Vector3(obb.m2, obb.m5, 0); //Check if the point is within the extents bool insideX = Math.Abs(diff.Dot(xExtent)) > xExtent.Magnitude(); bool insideY = Math.Abs(diff.Dot(yExtent)) > yExtent.Magnitude(); //If it is within both, it is inside the OBB return(insideX && insideY); }
public override void Update(float deltaTime) { //***** Look with mouse ***** /* * //Get the difference between the mouse and the turret * MthLib.Vector3 diff = new MthLib.Vector3(rl.Raylib.GetMouseX(), rl.Raylib.GetMouseY(), 0f); * diff -= global.point; * //Remove the parents rotation and add the rotation of the mouse relative to the tank. 90 is added because Atan2 starts at 90 degrees * local.rotation = 90 - (global.rotation - local.rotation) + (float)Math.Atan2(diff.y, diff.x) * (float)(180/Math.PI); */ //***** Look with keys ***** //Turn left if (rl.Raylib.IsKeyDown(left)) { local.rotation -= rotSpeed * deltaTime; } //Turn right if (rl.Raylib.IsKeyDown(right)) { local.rotation += rotSpeed * deltaTime; } //Fix rotation to not loop around if (local.rotation < 0f) { local.rotation += 360f; } else if (local.rotation > 360f) { local.rotation -= 360f; } //Create bullet at the top of the barrel if (rl.Raylib.IsKeyPressed(shoot) /* || rl.Raylib.IsMouseButtonPressed(rl.MouseButton.MOUSE_LEFT_BUTTON)*/) { GameObject bullet = new BulletClass(null, bulletImg, 700f, global.rotation); //Multiply imgSize by a small amount to keep bullet from colliding with the tank MthLib.Vector3 offset = new MthLib.Vector3(0f, imgSize.y * 1.2f, 0f); //Create rotation matrix MthLib.Matrix3 rot = new MthLib.Matrix3(); rot.SetRotateZ(global.rotation * (float)(Math.PI / 180f)); //Rotate the length of the barrel by its rotation to find the offset offset = rot * offset; bullet.SetLocation(global.point.x - offset.x, global.point.y - offset.y); } }
/// <summary> /// Returns the corner locations of an OBB /// </summary> private static Rect GetCorners(MthLib.Matrix3 obb) { //Get nessesary values MthLib.Vector3 center = new MthLib.Vector3(obb.m3, obb.m6, 0); MthLib.Vector3 xExtent = new MthLib.Vector3(obb.m1, obb.m4, 0); MthLib.Vector3 yExtent = new MthLib.Vector3(obb.m2, obb.m5, 0); return(new Rect { FL = center - xExtent + yExtent, FR = center + xExtent + yExtent, BL = center - xExtent - yExtent, BR = center + xExtent - yExtent }); }
private static bool IsOverlapping(MthLib.Vector3 normal, Rect rect1, Rect rect2) { //Project the rect's corners onto the normal float dot1 = normal.Dot(rect1.FL); float dot2 = normal.Dot(rect1.FR); float dot3 = normal.Dot(rect1.BL); float dot4 = normal.Dot(rect1.BR); //Find the furthest points float min1 = Math.Min(dot1, Math.Min(dot2, Math.Min(dot3, dot4))); float max1 = Math.Max(dot1, Math.Max(dot2, Math.Max(dot3, dot4))); //Repeat for the second rect dot1 = normal.Dot(rect2.FL); dot2 = normal.Dot(rect2.FR); dot3 = normal.Dot(rect2.BL); dot4 = normal.Dot(rect2.BR); float min2 = Math.Min(dot1, Math.Min(dot2, Math.Min(dot3, dot4))); float max2 = Math.Max(dot1, Math.Max(dot2, Math.Max(dot3, dot4))); //Are the projections overlapping? return(min1 <= max2 && min2 <= max1); }
public static bool OBBcolliding(MthLib.Matrix3 obj1, MthLib.Matrix3 obj2) { //Get the corners of both colliders Rect rect1 = GetCorners(obj1); Rect rect2 = GetCorners(obj2); //4 axis have to be tested to know if they are colliding //If a single axis is not overlapping, they are not colliding //Get the normal for the axis, then check for overlap on it MthLib.Vector3 normal = GetNormal(rect1.BL, rect1.FL); if (!IsOverlapping(normal, rect1, rect2)) { return(false); } normal = GetNormal(rect1.FL, rect1.FR); if (!IsOverlapping(normal, rect1, rect2)) { return(false); } normal = GetNormal(rect2.BL, rect2.FL); if (!IsOverlapping(normal, rect1, rect2)) { return(false); } normal = GetNormal(rect2.FL, rect2.FR); if (!IsOverlapping(normal, rect1, rect2)) { return(false); } //If all of the axis overlapped, then they are colliding return(true); }
public static bool PointAABBcolliding(MthLib.Vector3 point, AABB aabb) { //Return NOT outside the collider return(!(point.x < aabb.min.x || point.y < aabb.min.y || point.x > aabb.max.x || point.y > aabb.max.y)); }
/// <summary> /// Get the normal of a line from start to end, pointing left relative to start /// </summary> private static MthLib.Vector3 GetNormal(MthLib.Vector3 start, MthLib.Vector3 end) { MthLib.Vector3 dir = end - start; //Return the normal by flipping x and y and making one negitive return(new MthLib.Vector3(-dir.y, dir.x, dir.z)); }
public Actor(Vector3 position) : this(position.X, position.Y, position.Z) { }
public override void Update(float deltaTime) { //Turn left if (rl.Raylib.IsKeyDown(left)) { local.rotation -= rotSpeed * deltaTime; } //Turn right if (rl.Raylib.IsKeyDown(right)) { local.rotation += rotSpeed * deltaTime; } //Fix rotation to not loop around if (local.rotation < 0f) { local.rotation += 360f; } else if (local.rotation > 360f) { local.rotation -= 360f; } //Forward if (rl.Raylib.IsKeyPressed(up)) { accel -= acceleration; } if (rl.Raylib.IsKeyReleased(up)) { accel += acceleration; } //Backward if (rl.Raylib.IsKeyPressed(down)) { accel += acceleration; } if (rl.Raylib.IsKeyReleased(down)) { accel -= acceleration; } //When accel is 0, reduce speed to 0 if (accel == 0f && speed != 0f) { float temp = (speed > 0f) ? -acceleration : acceleration; speed += temp * deltaTime; //If close to 0, set to 0 to prevent jittering if (speed > -limit && speed < limit) { speed = 0f; } } else if (speed > -maxSpeed && speed < maxSpeed) { //Update speed. deltaTime should be a small value, so speed should only go slightly over maxSpeed speed += accel * deltaTime; } //Put speed into a vector to rotate it to the dirrection the tank is facing MthLib.Vector3 move = new MthLib.Vector3(0f, speed, 0f); //Create a rotation matrix, converting to radians MthLib.Matrix3 rotMatrix = new MthLib.Matrix3(); rotMatrix.SetRotateZ(local.rotation * (float)(Math.PI / 180f)); //Rotate movement and update local local.point += rotMatrix * move; //Check for collision Collision(); }
public Actor() { LocalPosition = new Vector3(); UpdateTransform(); }
public void SetScale(Vector3 scale) { _scale = Matrix4.CreateScale(scale); }
public void Rotate(Vector3 radians) { _rotationAngle += radians; _rotation *= Matrix4.CreateCombinedRotation(radians); }
public void SetRotation(Vector3 radians) { _rotationAngle = radians; _rotation = Matrix4.CreateCombinedRotation(radians); }
public void SetTranslation(Vector3 position) { _translation = Matrix4.CreateTranslation(position); }
public Actor(float x, float y, float z) { LocalPosition = new Vector3(x, y, z); UpdateTransform(); }
private void Collision() { //Update collider location and rotation UpdateColliderLoc(); //Rotation matrix of the difference in rotation MthLib.Matrix3 rotMatrix = new MthLib.Matrix3(); rotMatrix.SetRotateZ((local.rotation - global.rotation) * (float)(Math.PI / 180f)); //Rotate the extents, then put them back in the matrix MthLib.Vector3 x = new MthLib.Vector3(collider.m1, collider.m4, 0); x = rotMatrix * x; collider.m1 = x.x; collider.m4 = x.y; MthLib.Vector3 y = new MthLib.Vector3(collider.m2, collider.m5, 0); y = rotMatrix * y; collider.m2 = y.x; collider.m5 = y.y; //Get an AABB for rough collision before using OBB AABB aabb = CollisionFuncs.OBBtoAABB(collider); //Check if going out of bounds. Because the tank needs to stay inside, just AABB needs to be tested if (!CollisionFuncs.AABBwithin(aabb, GameManager.screenBox)) { //Tank is out of bounds; reset transform local = global; return; } //Go through all core objects and check for collision with other tanks foreach (GameObject obj in GameManager.coreObjects) { //If it isnt a tank, move on if (obj.tag != "Tank") { continue; } TankClass tank = obj as TankClass; //If the tank is this tank, move on if (tank == this) { continue; } //At this point, the tank must be a different tank, so it can be collided with //The collider is OBB, so it needs to be made an AABB AABB otherAABB = CollisionFuncs.OBBtoAABB(tank.collider); if (CollisionFuncs.AABBcolliding(aabb, otherAABB)) { //If they are colliding, check OBB collision if (CollisionFuncs.OBBcolliding(collider, tank.collider)) { //They are colliding, so reset transform local = global; return; } } } }