/// <summary> /// Creates all the necessary things to draw the object /// </summary> /// <returns>A Frame with the data needed to draw the object</returns> public virtual Frame Draw() { verticesCollection.Clear(); indicesCollection.Clear(); FaceCoordinates rotetedCoords = drawCoordinates.Rotate(RotationAngle); // calculate the coordinates of the for vertices. Vector3 tLeft = rotetedCoords.TopLeft; Vector3 tRight = rotetedCoords.TopRight; Vector3 bLeft = rotetedCoords.BottomLeft; Vector3 bRight = rotetedCoords.BottomRight; Vector2[] texture = spriteAtlas.GetSprite(spriteID); verticesCollection.Add(new VertexPositionNormalTexture(tRight, Vector3.Zero, texture[1])); verticesCollection.Add(new VertexPositionNormalTexture(bRight, Vector3.Zero, texture[0])); verticesCollection.Add(new VertexPositionNormalTexture(tLeft, Vector3.Zero, texture[2])); verticesCollection.Add(new VertexPositionNormalTexture(bLeft, Vector3.Zero, texture[3])); int startIndex = verticesCollection.Count - 4; indicesCollection.Add(startIndex); indicesCollection.Add(startIndex + 1); indicesCollection.Add(startIndex + 2); indicesCollection.Add(startIndex + 1); indicesCollection.Add(startIndex + 3); indicesCollection.Add(startIndex + 2); return(new Frame(null, null, verticesCollection, indicesCollection, new Vector2())); }
/// <summary> /// Based in the position of the Block calculate the positons of the verticies of the block. /// </summary> /// <param name="frontCoords">The coordinates of the top face of the cube</param> /// <param name="backCoords">The coordinates of the botton face of the cube</param> protected void PrepareCoordinates(out FaceCoordinates frontCoords, out FaceCoordinates backCoords) { float x = 0; float y = 0; float width = 1; float height = 1; PrepareCoordinates(x, y, width, height, out frontCoords, out backCoords); }
/// <summary> /// Creates an instance of GameObject /// </summary> /// <param name="startUpPosition">The initial position for the object</param> /// <param name="startUpRotation">The initial rotation of the object</param> /// <param name="shape">The shape of the object</param> protected GameObject(Vector3 startUpPosition, float startUpRotation, CompactRectangle shape) { drawCoordinates = new FaceCoordinates(startUpPosition, shape.Width, shape.Height); Position3 = startUpPosition; RotationAngle = startUpRotation; this.shape = shape; this.spriteID = 0; verticesCollection = new List <VertexPositionNormalTexture>(); indicesCollection = new List <int>(); }
/// <summary> /// Roteate a slope by 90° (rotation = 1), 180° (rotation = 2) or 270° (rotation = 3) /// </summary> /// <param name="frontCoordinates"></param> /// <param name="rotation"></param> protected FaceCoordinates RotateSlope(FaceCoordinates frontCoordinates, byte rotation) { for (int i = 0; i < rotation; i++) { Vector3 topLeft = frontCoordinates.BottomLeft; Vector3 topRight = frontCoordinates.TopLeft; Vector3 bottomRight = frontCoordinates.TopRight; Vector3 bottomLeft = frontCoordinates.BottomRight; frontCoordinates.TopLeft = topLeft; frontCoordinates.TopRight = topRight; frontCoordinates.BottomRight = bottomRight; frontCoordinates.BottomLeft = bottomLeft; } return(frontCoordinates); }
/// <summary> /// Based in the position of the Block calculate the positons of the verticies of the block. /// </summary> /// <param name="frontCoords">The coordinates of the top face of the cube</param> /// <param name="backCoords">The coordinates of the botton face of the cube</param> /// <param name="x">X position of the TopLeft corner.</param> /// <param name="y">Y position of the TopLeft corner.</param> /// <param name="width"></param> /// <param name="height"></param> protected void PrepareCoordinates(float x, float y, float width, float height, out FaceCoordinates frontCoords, out FaceCoordinates backCoords) { Vector3 position = Position; position.Y *= -1; //Coordinates of the cube Vector3 topLeftFront = (new Vector3(x, -y, 1f) + position) * GlobalScalar; Vector3 topRightFront = (new Vector3(x + width, -y, 1f) + position) * GlobalScalar; Vector3 bottomLeftFront = (new Vector3(x, -(y + height), 1f) + position) * GlobalScalar; Vector3 bottomRightFront = (new Vector3(x + width, -(y + height), 1f) + position) * GlobalScalar; frontCoords = new FaceCoordinates(topLeftFront, topRightFront, bottomRightFront, bottomLeftFront); Vector3 topLeftBack = (new Vector3(x, -y, 0.0f) + position) * GlobalScalar; Vector3 topRightBack = (new Vector3(x + width, -y, 0.0f) + position) * GlobalScalar; Vector3 bottomLeftBack = (new Vector3(x, -(y + height), 0.0f) + position) * GlobalScalar; Vector3 bottomRightBack = (new Vector3(x + width, -(y + height), 0.0f) + position) * GlobalScalar; backCoords = new FaceCoordinates(topLeftBack, topRightBack, bottomRightBack, bottomLeftBack); }
protected void CreateBottomVertices(FaceCoordinates frontCoords, FaceCoordinates backCoords, Vector2[] texture) { if (!Bottom) { return; } Coors.Add(new VertexPositionNormalTexture(frontCoords.BottomRight, Vector3.Zero, texture[2])); Coors.Add(new VertexPositionNormalTexture(backCoords.BottomRight, Vector3.Zero, texture[1])); Coors.Add(new VertexPositionNormalTexture(backCoords.BottomLeft, Vector3.Zero, texture[0])); Coors.Add(new VertexPositionNormalTexture(frontCoords.BottomLeft, Vector3.Zero, texture[3])); int startIndex = Coors.Count - 4; IndexBufferCollection.Add(startIndex); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 3); }
protected void CreateLeftVertices(FaceCoordinates frontCoords, FaceCoordinates backCoords, Vector2[] texture) { if (!Left) { return; } Coors.Add(new VertexPositionNormalTexture(frontCoords.TopLeft, Vector3.Zero, texture[3])); Coors.Add(new VertexPositionNormalTexture(backCoords.BottomLeft, Vector3.Zero, texture[1])); Coors.Add(new VertexPositionNormalTexture(frontCoords.BottomLeft, Vector3.Zero, texture[2])); Coors.Add(new VertexPositionNormalTexture(backCoords.TopLeft, Vector3.Zero, texture[0])); //Left also has a strange index buffer order... int startIndex = Coors.Count - 4; IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 3); IndexBufferCollection.Add(startIndex); }
/// <summary> /// Creates a Low Slope. /// </summary> /// <param name="subType"></param> /// <param name="rotation"></param> protected void SetLowSlope(byte subType, byte rotation) { //Sample is a right slope, use it for orientation, it gets rotated to fit all other directions FaceCoordinates frontCoordinates; FaceCoordinates backCoordinates; PrepareCoordinates(out frontCoordinates, out backCoordinates); float slopeScalar = 1f; switch (subType) { case 26: slopeScalar = 0.5f; break; case 45: slopeScalar = 0; break; case 7: slopeScalar = 0.875f; break; } Vector3 middleTopLeft = frontCoordinates.TopLeft; Vector3 middleTopRight = frontCoordinates.TopRight; Vector3 middleBottomRight = frontCoordinates.BottomRight; Vector3 middleBottomLeft = frontCoordinates.BottomLeft; var middleCoordinates = new FaceCoordinates(middleTopLeft, middleTopRight, middleBottomRight, middleBottomLeft); if (rotation > 0) { frontCoordinates = RotateSlope(frontCoordinates, rotation); backCoordinates = RotateSlope(backCoordinates, rotation); middleCoordinates = RotateSlope(middleCoordinates, rotation); } middleCoordinates.TopLeft.Z -= slopeScalar * GlobalScalar.Z; middleCoordinates.TopRight.Z -= slopeScalar * GlobalScalar.Z; middleCoordinates.BottomRight.Z -= slopeScalar * GlobalScalar.Z; middleCoordinates.BottomLeft.Z -= slopeScalar * GlobalScalar.Z; //Lid face if (Lid) { RotationType lidRotation = Lid.Rotation; lidRotation = RotateEnum(lidRotation, rotation); Vector2[] texPos = textures.GetNormalTexture((UInt32)Lid.TileNumber, Lid.Rotation, Lid.Flip); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.TopRight, Vector3.Zero, texPos[2])); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.BottomRight, Vector3.Zero, texPos[1])); Coors.Add(new VertexPositionNormalTexture(backCoordinates.BottomLeft, Vector3.Zero, texPos[0])); Coors.Add(new VertexPositionNormalTexture(backCoordinates.TopLeft, Vector3.Zero, texPos[3])); int startIndex = Coors.Count - 4; IndexBufferCollection.Add(startIndex); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 3); } BlockFace topFace = null; BlockFace bottomFace = null; BlockFace rightFace = null; switch (rotation) { case 0: //No rotation topFace = Top; bottomFace = Bottom; rightFace = Right; break; case 1: // topFace = Left; bottomFace = Right; rightFace = Top; break; case 2: topFace = Bottom; bottomFace = Top; rightFace = Left; break; case 3: topFace = Right; bottomFace = Left; rightFace = Bottom; break; } //Top face if (topFace) { Vector2[] texPos = textures.GetNormalTexture((UInt32)topFace.TileNumber, topFace.Rotation, topFace.Flip); Vector2 center = GetCenterPosition(ref texPos[3], ref texPos[0], slopeScalar); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.TopRight, Vector3.Zero, center)); Coors.Add(new VertexPositionNormalTexture(backCoordinates.TopRight, Vector3.Zero, texPos[0])); Coors.Add(new VertexPositionNormalTexture(backCoordinates.TopLeft, Vector3.Zero, texPos[1])); int startIndex = Coors.Count - 3; IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 0); } //Bottom face if (bottomFace) { Vector2[] texPos = textures.GetNormalTexture((UInt32)bottomFace.TileNumber, bottomFace.Rotation, bottomFace.Flip); Vector2 center = GetCenterPosition(ref texPos[2], ref texPos[1], slopeScalar); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.BottomRight, Vector3.Zero, center)); Coors.Add(new VertexPositionNormalTexture(backCoordinates.BottomRight, Vector3.Zero, texPos[1])); Coors.Add(new VertexPositionNormalTexture(backCoordinates.BottomLeft, Vector3.Zero, texPos[0])); int startIndex = Coors.Count - 3; IndexBufferCollection.Add(startIndex); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 2); } //Right face if (rightFace) //this face is not supported by GTA2, the editor removes this face. { Vector2[] texPos = textures.GetNormalTexture((UInt32)rightFace.TileNumber, rightFace.Rotation, rightFace.Flip); Vector2 center = GetCenterPosition(ref texPos[1], ref texPos[2], slopeScalar); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.TopRight, Vector3.Zero, center)); center = GetCenterPosition(ref texPos[0], ref texPos[3], slopeScalar); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.BottomRight, Vector3.Zero, center)); Coors.Add(new VertexPositionNormalTexture(backCoordinates.BottomRight, Vector3.Zero, texPos[3])); Coors.Add(new VertexPositionNormalTexture(backCoordinates.TopRight, Vector3.Zero, texPos[2])); int startIndex = Coors.Count - 4; IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 0); IndexBufferCollection.Add(startIndex); IndexBufferCollection.Add(startIndex + 3); IndexBufferCollection.Add(startIndex + 2); } }
protected void SetUpSlopeHigh(byte subType, byte rotation) { //Sample is a right slope, use it for orientation, it gets rotated to fit all other directions FaceCoordinates frontCoordinates; FaceCoordinates backCoordinates; PrepareCoordinates(out frontCoordinates, out backCoordinates); float middleSlopeScalar = 1f; float frontSlopeScalar = 0f; switch (subType) { case 26: middleSlopeScalar = 0.5f; frontSlopeScalar = 0; break; case 7: middleSlopeScalar = 0.875f; frontSlopeScalar = 0.75f; break; case 8: middleSlopeScalar = 0.75f; frontSlopeScalar = 0.625f; break; case 9: middleSlopeScalar = 0.625f; frontSlopeScalar = 0.5f; break; case 10: middleSlopeScalar = 0.5f; frontSlopeScalar = 0.375f; break; case 11: middleSlopeScalar = 0.375f; frontSlopeScalar = 0.25f; break; case 12: middleSlopeScalar = 0.25f; frontSlopeScalar = 0.125f; break; case 13: middleSlopeScalar = 0.125f; frontSlopeScalar = 0; break; } Vector3 middleTopLeft = frontCoordinates.TopLeft; Vector3 middleTopRight = frontCoordinates.TopRight; Vector3 middleBottomRight = frontCoordinates.BottomRight; Vector3 middleBottomLeft = frontCoordinates.BottomLeft; var middleCoordinates = new FaceCoordinates(middleTopLeft, middleTopRight, middleBottomRight, middleBottomLeft); if (rotation > 0) { frontCoordinates = RotateSlope(frontCoordinates, rotation); backCoordinates = RotateSlope(backCoordinates, rotation); middleCoordinates = RotateSlope(middleCoordinates, rotation); } frontCoordinates.TopLeft.Z -= frontSlopeScalar * GlobalScalar.Z; frontCoordinates.TopRight.Z -= frontSlopeScalar * GlobalScalar.Z; frontCoordinates.BottomRight.Z -= frontSlopeScalar * GlobalScalar.Z; frontCoordinates.BottomLeft.Z -= frontSlopeScalar * GlobalScalar.Z; middleCoordinates.TopLeft.Z -= middleSlopeScalar * GlobalScalar.Z; middleCoordinates.TopRight.Z -= middleSlopeScalar * GlobalScalar.Z; middleCoordinates.BottomRight.Z -= middleSlopeScalar * GlobalScalar.Z; middleCoordinates.BottomLeft.Z -= middleSlopeScalar * GlobalScalar.Z; //Front face (diagonal) if (Lid.TileNumber > 0) { RotationType lidRotation = Lid.Rotation; lidRotation = RotateEnum(lidRotation, rotation); Vector2[] texPos = textures.GetNormalTexture((UInt32)Lid.TileNumber, Lid.Rotation, Lid.Flip); Coors.Add(new VertexPositionNormalTexture(frontCoordinates.TopRight, Vector3.Zero, texPos[2])); Coors.Add(new VertexPositionNormalTexture(frontCoordinates.BottomRight, Vector3.Zero, texPos[1])); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.BottomLeft, Vector3.Zero, texPos[0])); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.TopLeft, Vector3.Zero, texPos[3])); int startIndex = Coors.Count - 4; IndexBufferCollection.Add(startIndex + 0); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 0); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 3); } BlockFace topFace = null; BlockFace bottomFace = null; BlockFace leftFace = null; BlockFace rightFace = null; switch (rotation) { case 0: topFace = Top; bottomFace = Bottom; leftFace = Left; rightFace = Right; break; case 1: topFace = Left; bottomFace = Right; leftFace = Bottom; rightFace = Top; break; case 2: topFace = Bottom; bottomFace = Top; leftFace = Right; rightFace = Left; break; case 3: topFace = Right; bottomFace = Left; leftFace = Top; rightFace = Bottom; break; } //Top face if (topFace) { Vector2[] texPos = textures.GetNormalTexture((UInt32)topFace.TileNumber, topFace.Rotation, topFace.Flip); Vector2 center = GetCenterPosition(ref texPos[0], ref texPos[3], frontSlopeScalar); Coors.Add(new VertexPositionNormalTexture(frontCoordinates.TopRight, Vector3.Zero, center)); //was 3 Coors.Add(new VertexPositionNormalTexture(backCoordinates.TopRight, Vector3.Zero, texPos[0])); Coors.Add(new VertexPositionNormalTexture(backCoordinates.TopLeft, Vector3.Zero, texPos[1])); center = GetCenterPosition(ref texPos[1], ref texPos[2], middleSlopeScalar); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.TopLeft, Vector3.Zero, center)); int startIndex = Coors.Count - 4; IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 0); IndexBufferCollection.Add(startIndex + 3); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 0); } //Bottom face if (bottomFace) { Vector2[] texPos = textures.GetNormalTexture((UInt32)bottomFace.TileNumber, bottomFace.Rotation, bottomFace.Flip); Vector2 center = GetCenterPosition(ref texPos[2], ref texPos[1], frontSlopeScalar); Coors.Add(new VertexPositionNormalTexture(frontCoordinates.BottomRight, Vector3.Zero, center)); //was texPos[2] Coors.Add(new VertexPositionNormalTexture(backCoordinates.BottomRight, Vector3.Zero, texPos[1])); Coors.Add(new VertexPositionNormalTexture(backCoordinates.BottomLeft, Vector3.Zero, texPos[0])); center = GetCenterPosition(ref texPos[3], ref texPos[0], middleSlopeScalar); Coors.Add(new VertexPositionNormalTexture(middleCoordinates.BottomLeft, Vector3.Zero, center)); int startIndex = Coors.Count - 4; IndexBufferCollection.Add(startIndex); IndexBufferCollection.Add(startIndex + 1); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 0); IndexBufferCollection.Add(startIndex + 2); IndexBufferCollection.Add(startIndex + 3); } //ToDo Left face (but probably not supported in GTA2 anyway) //Right face Vector2[] texture = textures.GetNormalTexture((UInt32)Right.TileNumber, Right.Rotation, Right.Flip); CreateRightVertices(frontCoordinates, backCoordinates, texture); }