public static void ProcessGeometry(this GameWindow window) { GL.Disable(EnableCap.Texture2D); Vector4 ambient = new Vector4(0.2f, 0.2f, 0.2f, 1.0f); Vector4 diffuse = new Vector4(1.0f, 1.0f, 1.0f, 1.0f); Vector4 specular = new Vector4(0.0f, 0.0f, 0.0f, 1.0f); GL.Material(MaterialFace.Front, MaterialParameter.Ambient, ambient); GL.Material(MaterialFace.Front, MaterialParameter.Diffuse, diffuse); GL.Material(MaterialFace.Front, MaterialParameter.Specular, specular); GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 40.0f); // Floor Vertex [] [] room = { floorVerts, northWallVerts, southWallVerts, rightWallVerts, leftWallVerts }; GL.Begin(PrimitiveType.Quads); for (int i = 0; i < room.Length; i++) { if (room [i].Length < 4) { continue; } Vertex [] verts = room [i]; Vector3k normal = MathUtils.CalculateSurfaceNormal(verts); GL.Normal3(normal.ToVec3d()); for (int v = 0; v < 4; v++) { GL.Vertex3(verts [v].Pos.ToVec3()); } } GL.End(); }
/// <summary> /// Performs movement and collision detection in the Z plane. /// </summary> protected virtual void DoZMovement() { Accum velZAbs = FixedMath.Abs(vel.Z); if (vel.Z == Accum.Zero) { DoZCollisionDetection(true); } else if (velZAbs < this.Height) { bCylinder.Position += vel; if (DoZCollisionDetection(true) == CollisionType.SpcColResp_StopMovement) { vel = Vector3k.Zero; } } else { Accum moveCount = FixedMath.Ceil(velZAbs / this.Height); Accum stepVel = vel.Z / this.Height; for (int i = 0; i < moveCount; i += 1) { bCylinder.Position += stepVel; if (DoZCollisionDetection(true) == CollisionType.SpcColResp_StopMovement) { vel = Vector3k.Zero; return; } } if (DoZCollisionDetection(true) == CollisionType.SpcColResp_StopMovement) { vel = Vector3k.Zero; } } }
/// <summary> /// Performs movement and collision detection in the XY plane. /// </summary> protected virtual void DoMovement() { if ((vel.X | vel.Y) == Accum.Zero) { DoXYCollisionDetection(true); } else if (FixedMath.Abs(vel.X * vel.X + vel.Y * vel.Y) < (this.Radius * this.Radius)) { bCylinder.X += vel.X; bCylinder.Y += vel.Y; if (DoXYCollisionDetection(true) == CollisionType.SpcColResp_StopMovement) { vel = Vector3k.Zero; } } else { Accum moveCount = FixedMath.Ceil((vel.X * vel.X + vel.Y * vel.Y) / this.Radius); Vector3k stepVel = new Vector3k(vel.X / this.Radius, vel.Y / this.Radius, Accum.Zero); for (int i = 0; i < moveCount; i += 1) { bCylinder.X += vel.X; bCylinder.Y += vel.Y; if (DoXYCollisionDetection(true) == CollisionType.SpcColResp_StopMovement) { vel = Vector3k.Zero; return; } } if (DoXYCollisionDetection(true) == CollisionType.SpcColResp_StopMovement) { vel = Vector3k.Zero; } } }
/// <summary> /// Detects collisions in the XY plane. /// </summary> /// <param name="performResponse">Whether to fix any collisions. Defaults to true.</param> /// <returns>A CollisionType indicating whether a collision happened.</returns> public virtual CollisionType DoXYCollisionDetection(bool performResponse = true) { if (this.CheckFlags(ActorFlags.NoInteraction)) // Don't do collision detection if NoInteraction is set. { return(CollisionType.None); } Vector3k deltaDist = Vector3k.Zero; Actor firstCollision = null; bool spcColRespStopMove = false; foreach (Actor act in Core.Ticker.Thinkers) // Iterate through all actors. { if (act == null || act == this) // Skip if the actor is null or act refers to itself { continue; } if (act.CheckFlags(ActorFlags.NoBlockmap) || act.CheckFlags(ActorFlags.NoInteraction)) // Skip the actor if it has NoBlockmap or NoInteraction { continue; } Vector3k distXY = bCylinder.IntersectionDistXY(act.bCylinder); if (distXY.LengthSquared < FixedMath.Square(this.Radius + act.Radius)) { if (performResponse) { deltaDist += (((act.Radius + this.Radius) / distXY.Length) - Accum.One) * distXY; } if (firstCollision == null) { firstCollision = act; } if (SpecialCollisionResponseXY(performResponse, act, act == firstCollision)) { spcColRespStopMove = true; } } } if (performResponse) { bCylinder.Position += deltaDist; } if (spcColRespStopMove) { return(CollisionType.SpcColResp_StopMovement); } else if (firstCollision != null) { return(CollisionType.Collision); } else { return(CollisionType.None); } }
public Vector3k IntersectionDist(BoundingCylinder b) { Vector3k dist = new Vector3k(this.X - b.X, this.Y - b.Y, Accum.Zero); dist.Z = IntersectionDistZ(b); return(dist); }
protected Actor() { maxHealth = health = 1000; prevPos = bCylinder.Position = vel = Vector3k.Zero; speed = angle = pitch = Accum.Zero; prevAngle = prevPitch = Accum.Zero; flags = 0; gravity = Accum.One; bCylinder = new BoundingCylinder(new Accum(16), new Accum(20), new Vector3k(Accum.Zero, Accum.Zero, Accum.Zero)); cam = new Camera(); }
/// <summary> /// Changes the actor's position /// </summary> /// <param name="newPos">The values to change the position by</param> /// <param name="interpolate">Whether the actor should interpolate to the new position</param> public virtual void ChangePosition(Vector3k newPos, bool interpolate = false) { if (interpolate) { prevPos = bCylinder.Position; bCylinder.Position += newPos; } else { prevPos = (bCylinder.Position += newPos); } }
/// <summary> /// Set the actor's position /// </summary> /// <param name="newPos">The position to set the actor to</param> /// <param name="interpolate">Whether the actor should interpolate to the new position</param> public virtual void SetPosition(Vector3k newPos, bool interpolate = false) { if (interpolate) { prevPos = bCylinder.Position; bCylinder.Position = newPos; } else { prevPos = bCylinder.Position = newPos; } }
public override void Tick() { base.Tick(); Camera.UpdateFromActor(this); if (state == null) { ObjFlags |= GameObjFlags.EuthanizeMe; } else if (stTime != -1 && --stTime <= 0) { if (state.Next != null) { ChangeState(state.Next); } else { GConsole.Debug.WriteLine("Actor tried to change to null state."); stTime = -1; } } if (ObjFlags.HasFlag(GameObjFlags.EuthanizeMe)) { return; } DoMovement(); DoZMovement(); Accum friction = GetFriction(); vel.X *= ((Math.Abs(vel.X.Value) > MINVELOCITY) ? friction : Accum.Zero); vel.Y *= ((Math.Abs(vel.Y.Value) > MINVELOCITY) ? friction : Accum.Zero); if (bCylinder.X < Constants.CoordinatesMin || bCylinder.Y < Constants.CoordinatesMin || bCylinder.Z < Constants.CoordinatesMin || bCylinder.X > Constants.CoordinatesMax || bCylinder.Y > Constants.CoordinatesMax || bCylinder.Z > Constants.CoordinatesMax) { this.Destroy(); } if (!flags.HasFlag(ActorFlags.NoGravity) && gravity > 0 && bCylinder.Z > 0) { vel.Z -= ((flags & ActorFlags.NoInteraction) == ActorFlags.NoInteraction) ? GetLocalGravity() : GetGravity(); } prevPos = bCylinder.Position; }
public BoundingCylinder(Accum radius, Accum height, Vector3k pos) { Radius = radius; Height = height; _position = pos; }
/// <summary> /// Changes the actor's velocity vector. /// </summary> /// <param name="newVel">The values to change the velocity by</param> public virtual void ChangeVelocity(Vector3k newVel) { vel += newVel; }
/// <summary> /// Sets the actor's velocity vector. /// </summary> /// <param name="newVel">The new velocity values</param> public virtual void SetVelocity(Vector3k newVel) { vel = newVel; }