public byte GetY(OrdinalDirections dir) { switch (dir) { case OrdinalDirections.Up: return(UpY); case OrdinalDirections.Down: return(DownY); case OrdinalDirections.North: return(NorthY); case OrdinalDirections.East: return(EastY); case OrdinalDirections.South: return(SouthY); case OrdinalDirections.West: return(WestY); default: return(0); } }
public byte GetSubMesh(OrdinalDirections dir) { switch (dir) { case OrdinalDirections.Up: return(UpSubMesh); case OrdinalDirections.Down: return(DownSubMesh); case OrdinalDirections.North: return(NorthSubMesh); case OrdinalDirections.East: return(EastSubMesh); case OrdinalDirections.South: return(SouthSubMesh); case OrdinalDirections.West: return(WestSubMesh); default: return(0); } }
/// <summary> /// Add uv data for the last four vertices in the mesh data from a rectangle /// </summary> /// <param name="uv">The uv rect information</param> /// <param name="dir">The direction to add the uvs</param> public void AddQuadUVs(Rect uv, OrdinalDirections dir) { // TODO: Consider simplifying this method switch (dir) { case OrdinalDirections.Up: uvs.Add(uv.position + new Vector2(0, uv.height)); uvs.Add(uv.position + uv.size); uvs.Add(uv.position + new Vector2(uv.width, 0)); uvs.Add(uv.position); break; case OrdinalDirections.Down: uvs.Add(uv.position + new Vector2(uv.width, 0)); uvs.Add(uv.position); uvs.Add(uv.position + new Vector2(0, uv.height)); uvs.Add(uv.position + uv.size); break; case OrdinalDirections.North: case OrdinalDirections.East: case OrdinalDirections.South: case OrdinalDirections.West: uvs.Add(uv.position); uvs.Add(uv.position + new Vector2(0, uv.height)); uvs.Add(uv.position + uv.size); uvs.Add(uv.position + new Vector2(uv.width, 0)); break; default: break; } }
/// <summary> /// Convert the given current up axis and amount rotated around it to a Quaternion rotation /// </summary> /// <param name="currUp">The current up axis</param> /// <param name="rotAmount">The amount rotated around the up axis</param> /// /// <returns></returns> public static Quaternion DirectionToEulerRotation(OrdinalDirections currUp, int rotAmount) { int a = (rotAmount == 0) ? 1 : (rotAmount == 180) ? -1 : 0, b = (rotAmount == 90) ? 1 : (rotAmount == 270) ? -1 : 0; switch (currUp) { case OrdinalDirections.Up: return(Quaternion.LookRotation(new Vector3(b, 0, a), Vector3.up)); case OrdinalDirections.Down: return(Quaternion.LookRotation(new Vector3(-b, 0, a), Vector3.down)); case OrdinalDirections.North: return(Quaternion.LookRotation(new Vector3(b, a, 0), Vector3.forward)); case OrdinalDirections.East: return(Quaternion.LookRotation(new Vector3(0, a, -b), Vector3.right)); case OrdinalDirections.South: return(Quaternion.LookRotation(new Vector3(-b, a, 0), Vector3.back)); case OrdinalDirections.West: return(Quaternion.LookRotation(new Vector3(0, a, b), Vector3.left)); default: throw new System.Exception("Unknown Direction"); } }
/// <summary> /// Get the boolean value for the given direction /// </summary> /// <param name="dir">The direction to get the boolean for</param> /// <returns></returns> public bool GetBoolForDir(OrdinalDirections dir) { switch (dir) { case OrdinalDirections.Up: return(IsUp); case OrdinalDirections.Down: return(IsDown); case OrdinalDirections.North: return(IsNorth); case OrdinalDirections.East: return(IsEast); case OrdinalDirections.South: return(IsSouth); case OrdinalDirections.West: return(IsWest); default: return(false); } }
/// <summary> /// Add a quad to the mesh data using a position, size and normal direction /// </summary> /// <param name="position">The position to add the quad (offset for face is added automatically)</param> /// <param name="dir">The direction of the face</param> /// <param name="size">The size of the face (half the width)</param> /// <param name="subMesh">The submesh to add the quad to</param> public void AddQuad(Vector3 position, OrdinalDirections dir, float size, int submesh) { var ps = +size; var ns = -size; switch (dir) { case OrdinalDirections.Up: vertices.Add(position + new Vector3(ns, ps, ps)); vertices.Add(position + new Vector3(ps, ps, ps)); vertices.Add(position + new Vector3(ps, ps, ns)); vertices.Add(position + new Vector3(ns, ps, ns)); break; case OrdinalDirections.Down: vertices.Add(position + new Vector3(ns, ns, ns)); vertices.Add(position + new Vector3(ps, ns, ns)); vertices.Add(position + new Vector3(ps, ns, ps)); vertices.Add(position + new Vector3(ns, ns, ps)); break; case OrdinalDirections.North: vertices.Add(position + new Vector3(ps, ns, ps)); vertices.Add(position + new Vector3(ps, ps, ps)); vertices.Add(position + new Vector3(ns, ps, ps)); vertices.Add(position + new Vector3(ns, ns, ps)); break; case OrdinalDirections.East: vertices.Add(position + new Vector3(ps, ns, ns)); vertices.Add(position + new Vector3(ps, ps, ns)); vertices.Add(position + new Vector3(ps, ps, ps)); vertices.Add(position + new Vector3(ps, ns, ps)); break; case OrdinalDirections.South: vertices.Add(position + new Vector3(ns, ns, ns)); vertices.Add(position + new Vector3(ns, ps, ns)); vertices.Add(position + new Vector3(ps, ps, ns)); vertices.Add(position + new Vector3(ps, ns, ns)); break; case OrdinalDirections.West: vertices.Add(position + new Vector3(ns, ns, ps)); vertices.Add(position + new Vector3(ns, ps, ps)); vertices.Add(position + new Vector3(ns, ps, ns)); vertices.Add(position + new Vector3(ns, ns, ns)); break; default: break; } AddQuadTriangles(submesh); }
/// <summary> /// Returns true if the face of the voxel at the given position is solid /// </summary> /// <param name="lX">The local x coordinate</param> /// <param name="lY">The local y coordinate</param> /// <param name="lY">The local z coordinate</param> /// <param name="dir">The direction of the face</param> /// <returns></returns> public bool IsSolid(int lX, int lY, int lZ, OrdinalDirections dir) { if (IsInChunk(lX, lY, lZ)) { return(voxels[lX, lY, lZ].IsSolid(dir)); } else { return(VoxelObject.IsSolid(VoxelObject.PosHelper.ChunkToObjectPosition(ChunkPosition) + new IntVector3(lX, lY, lZ), dir)); } }
/// <summary> /// Returns true if the face of the voxel at the given position is solid /// </summary> /// <param name="localPos">The local position of the voxel</param> /// <param name="dir">The direction of the face</param> /// <returns></returns> public bool IsSolid(IntVector3 localPos, OrdinalDirections dir) { if (IsInChunk(localPos.X, localPos.Y, localPos.Z)) { return(voxels[localPos.X, localPos.Y, localPos.Z].IsSolid(dir)); } else { return(VoxelObject.IsSolid(VoxelObject.PosHelper.ChunkToObjectPosition(ChunkPosition) + localPos, dir)); } }
/// <summary> /// Add a quad to the collider data using a position, size and normal direction /// </summary> /// <param name="position">The position to add the quad (offset for face is added automatically)</param> /// <param name="dir">The direction of the face</param> /// <param name="size">The size of the face (half the width)</param> public void AddQuadToCollider(Vector3 position, OrdinalDirections dir, float size) { switch (dir) { case OrdinalDirections.North: colliderVertices.Add(position + new Vector3(+size, -size, +size)); colliderVertices.Add(position + new Vector3(+size, +size, +size)); colliderVertices.Add(position + new Vector3(-size, +size, +size)); colliderVertices.Add(position + new Vector3(-size, -size, +size)); break; case OrdinalDirections.South: colliderVertices.Add(position + new Vector3(-size, -size, -size)); colliderVertices.Add(position + new Vector3(-size, +size, -size)); colliderVertices.Add(position + new Vector3(+size, +size, -size)); colliderVertices.Add(position + new Vector3(+size, -size, -size)); break; case OrdinalDirections.East: colliderVertices.Add(position + new Vector3(+size, -size, -size)); colliderVertices.Add(position + new Vector3(+size, +size, -size)); colliderVertices.Add(position + new Vector3(+size, +size, +size)); colliderVertices.Add(position + new Vector3(+size, -size, +size)); break; case OrdinalDirections.West: colliderVertices.Add(position + new Vector3(-size, -size, +size)); colliderVertices.Add(position + new Vector3(-size, +size, +size)); colliderVertices.Add(position + new Vector3(-size, +size, -size)); colliderVertices.Add(position + new Vector3(-size, -size, -size)); break; case OrdinalDirections.Up: colliderVertices.Add(position + new Vector3(-size, +size, +size)); colliderVertices.Add(position + new Vector3(+size, +size, +size)); colliderVertices.Add(position + new Vector3(+size, +size, -size)); colliderVertices.Add(position + new Vector3(-size, +size, -size)); break; case OrdinalDirections.Down: colliderVertices.Add(position + new Vector3(-size, -size, -size)); colliderVertices.Add(position + new Vector3(+size, -size, -size)); colliderVertices.Add(position + new Vector3(+size, -size, +size)); colliderVertices.Add(position + new Vector3(-size, -size, +size)); break; default: break; } AddQuadTrianglesToCollider(); }
/// <summary> /// Set the orientation and rotation of the voxel /// </summary> /// <param name="orientation">The orientation of the voxel</param> /// <param name="rotAmount">The rotation around the orientation axis (0, 90, 180, 270)</param> public void OrientRotateVoxel(OrdinalDirections orientation, int rotAmount) { if (rotAmount % 90 != 0) { throw new System.Exception("Voxels don't bend that way honey!"); } if (rotAmount > 270) { rotAmount = ((rotAmount / 90) % 4) * 90; } Orientation = orientation; Rotation = rotAmount; }
/// <summary> /// Returns true if the given face of the voxel at the given position is solid /// </summary> /// <param name="objPos">The position to check</param> /// <param name="dir">The face to check</param> /// <returns></returns> public bool IsSolid(IntVector3 objPos, OrdinalDirections dir) { if (!IsInObjectBoundary(objPos)) { return(false); } IntVector3 chunkPos = PosHelper.ObjectToChunkPosition(objPos); if (!IsChunkLoaded(chunkPos)) { return(false); } else { return(loadedChunks[chunkPos].IsSolid(PosHelper.ObjectToLocalPosition(objPos), dir)); } }
/// <summary> /// Returns true if the face in the given direction is solid /// </summary> /// <param name="dir">The direction of the face</param> /// <returns></returns> public override bool IsSolid(OrdinalDirections dir) { OrdinalDirections dirLoc = OrdinalDirectionsHelper.GlobalToLocalDirection(dir, Orientation, Rotation); switch (Style) { case VoxelStyle.Wedge: if (dirLoc != OrdinalDirections.South && dirLoc != OrdinalDirections.Down) { return(false); } return(base.IsSolid(dirLoc)); case VoxelStyle.Corner: // TODO: Implement Corner solidity case VoxelStyle.InverseCorner: // TODO: Implement Anti Corner solidity case VoxelStyle.Block: default: return(base.IsSolid(dirLoc)); } }
/// <summary> /// Create a complex wedge with orientation and rotation /// </summary> /// <param name="addToMeshData">The mesh data to add the block to</param> /// <param name="position">The position of the block</param> /// <param name="orientation">The voxel's orientation</param> /// <param name="rotAmount">The voxel's rotation around the orientation axis (0, 90, 180, 270)</param> /// <param name="visibility">Which sides of the block are visible</param> /// <param name="voxelData">The type of voxel to render</param> /// <param name="voxelSize">The size of the voxel</param> public static void CreateComplexWedgeMeshData(MeshData addToMeshData, Vector3 position, OrdinalDirections orientation, int rotAmount, OrdinalBoolean visibility, VoxelData voxelData, float voxelSize) { // Vertices int[] comps; Vector3 v1, v2, v3, v4; // UVs Vector2 uvC; Vector2[] uvs = new Vector2[4]; float rot; // General bool slopeDone = false; OrdinalDirections dirGlob; OrdinalDirections dirLoc; for (int i = 0; i < 6; i++) { dirGlob = (OrdinalDirections)i; if (visibility.GetBoolForDir(dirGlob) && voxelData.Faces.GetBoolForDir(dirLoc = OrdinalDirectionsHelper.GlobalToLocalDirection(dirGlob, orientation, rotAmount))) { // Slope if (!slopeDone && (dirLoc == OrdinalDirections.Up || dirLoc == OrdinalDirections.North || dirLoc == OrdinalDirections.East || dirLoc == OrdinalDirections.West)) { comps = WEDGE_MESH_MAP[(int)orientation, rotAmount / 90, (int)orientation]; // UVs rot = OrdinalDirectionsHelper.DirectionToRotation(OrdinalDirections.Up, orientation, rotAmount); uvs[0] = new Vector2(voxelData.Textures.GetX(OrdinalDirections.Up), voxelData.Textures.GetY(OrdinalDirections.Up)) * VoxelDataTextures.UV_SIZE_WITH_PADDING + VoxelDataTextures.TEXTURE_PADDING_OFFSET; uvs[1] = uvs[0] + new Vector2(0, VoxelDataTextures.TEXTURE_DIMENSION); uvs[2] = uvs[0] + new Vector2(VoxelDataTextures.TEXTURE_DIMENSION, VoxelDataTextures.TEXTURE_DIMENSION); uvs[3] = uvs[0] + new Vector2(VoxelDataTextures.TEXTURE_DIMENSION, 0); // Average UV Pos uvC = new Vector2((uvs[0].x + uvs[1].x + uvs[2].x + uvs[3].x) / 4, (uvs[0].y + uvs[1].y + uvs[2].y + uvs[3].y) / 4); // UV Rotation uvs[0] = (uvs[0] - uvC).Rotate(rot) + uvC; uvs[1] = (uvs[1] - uvC).Rotate(rot) + uvC; uvs[2] = (uvs[2] - uvC).Rotate(rot) + uvC; uvs[3] = (uvs[3] - uvC).Rotate(rot) + uvC; v1 = new Vector3(comps[0], comps[1], comps[2]) * voxelSize + position; v2 = new Vector3(comps[3], comps[4], comps[5]) * voxelSize + position; v3 = new Vector3(comps[6], comps[7], comps[8]) * voxelSize + position; v4 = new Vector3(comps[9], comps[10], comps[11]) * voxelSize + position; // Mesh Data addToMeshData.AddQuad(v1, v2, v3, v4, 0); // Collider Data addToMeshData.AddQuadToCollider(v1, v2, v3, v4); // UVs addToMeshData.AddUV(uvs[comps[12]]); addToMeshData.AddUV(uvs[comps[13]]); addToMeshData.AddUV(uvs[comps[14]]); addToMeshData.AddUV(uvs[comps[15]]); // Only render the top once slopeDone = true; } // Quad Faces if (dirLoc == OrdinalDirections.South || dirLoc == OrdinalDirections.Down) { comps = WEDGE_MESH_MAP[(int)orientation, rotAmount / 90, (int)dirGlob]; // UVs rot = OrdinalDirectionsHelper.DirectionToRotation(dirGlob, orientation, rotAmount); uvs[0] = new Vector2(voxelData.Textures.GetX(dirLoc), voxelData.Textures.GetY(dirLoc)) * VoxelDataTextures.UV_SIZE_WITH_PADDING + VoxelDataTextures.TEXTURE_PADDING_OFFSET; uvs[1] = uvs[0] + new Vector2(0, VoxelDataTextures.TEXTURE_DIMENSION); uvs[2] = uvs[0] + new Vector2(VoxelDataTextures.TEXTURE_DIMENSION, VoxelDataTextures.TEXTURE_DIMENSION); uvs[3] = uvs[0] + new Vector2(VoxelDataTextures.TEXTURE_DIMENSION, 0); // Average UV Pos uvC = new Vector2((uvs[0].x + uvs[1].x + uvs[2].x + uvs[3].x) / 4, (uvs[0].y + uvs[1].y + uvs[2].y + uvs[3].y) / 4); // UV Rotation uvs[0] = (uvs[0] - uvC).Rotate(rot) + uvC; uvs[1] = (uvs[1] - uvC).Rotate(rot) + uvC; uvs[2] = (uvs[2] - uvC).Rotate(rot) + uvC; uvs[3] = (uvs[3] - uvC).Rotate(rot) + uvC; v1 = new Vector3(comps[0], comps[1], comps[2]) * voxelSize + position; v2 = new Vector3(comps[3], comps[4], comps[5]) * voxelSize + position; v3 = new Vector3(comps[6], comps[7], comps[8]) * voxelSize + position; v4 = new Vector3(comps[9], comps[10], comps[11]) * voxelSize + position; // Mesh Data addToMeshData.AddQuad(v1, v2, v3, v4, 0); // Collider Data addToMeshData.AddQuadToCollider(v1, v2, v3, v4); // UVs addToMeshData.AddUV(uvs[comps[12]]); addToMeshData.AddUV(uvs[comps[13]]); addToMeshData.AddUV(uvs[comps[14]]); addToMeshData.AddUV(uvs[comps[15]]); } // Triangle Faces else if (dirLoc == OrdinalDirections.East || dirLoc == OrdinalDirections.West) { comps = WEDGE_MESH_MAP[(int)orientation, rotAmount / 90, (int)dirGlob]; // UVs rot = OrdinalDirectionsHelper.DirectionToRotation(dirGlob, orientation, rotAmount); uvs[0] = new Vector2(voxelData.Textures.GetX(dirLoc), voxelData.Textures.GetY(dirLoc)) * VoxelDataTextures.UV_SIZE_WITH_PADDING + VoxelDataTextures.TEXTURE_PADDING_OFFSET; uvs[1] = uvs[0] + new Vector2(0, VoxelDataTextures.TEXTURE_DIMENSION); uvs[2] = uvs[0] + new Vector2(VoxelDataTextures.TEXTURE_DIMENSION, VoxelDataTextures.TEXTURE_DIMENSION); uvs[3] = uvs[0] + new Vector2(VoxelDataTextures.TEXTURE_DIMENSION, 0); // Average UV Pos uvC = new Vector2((uvs[0].x + uvs[1].x + uvs[2].x + uvs[3].x) / 4, (uvs[0].y + uvs[1].y + uvs[2].y + uvs[3].y) / 4); // UV Rotation uvs[0] = (uvs[0] - uvC).Rotate(rot) + uvC; uvs[1] = (uvs[1] - uvC).Rotate(rot) + uvC; uvs[2] = (uvs[2] - uvC).Rotate(rot) + uvC; uvs[3] = (uvs[3] - uvC).Rotate(rot) + uvC; v1 = new Vector3(comps[0], comps[1], comps[2]) * voxelSize + position; v2 = new Vector3(comps[3], comps[4], comps[5]) * voxelSize + position; v3 = new Vector3(comps[6], comps[7], comps[8]) * voxelSize + position; // Mesh Data addToMeshData.AddTriangle(v1, v2, v3, 0); // Collider Data addToMeshData.AddTriangleToCollider(v1, v2, v3); // UVs addToMeshData.AddUV(uvs[comps[9]]); addToMeshData.AddUV(uvs[comps[10]]); addToMeshData.AddUV(uvs[comps[11]]); } } } }
/// <summary> /// Returns true if the given direction's face is solid /// </summary> /// <param name="dir">The direction to check</param> /// <returns></returns> public bool IsSolid(OrdinalDirections dir) { return(Solidity.GetBoolForDir(dir)); }
/// <summary> /// Returns true if the given direction has a face /// </summary> /// <param name="dir">The direction to check</param> /// <returns></returns> public bool HasFace(OrdinalDirections dir) { return(Faces.GetBoolForDir(dir)); }
/// <summary> /// Convert from a direction to a UV rotation, given the current up axis and amount rotated around it /// </summary> /// <param name="dir">The direction to convert</param> /// <param name="currUp">The current up axis</param> /// <param name="rotAmount">The amount rotated around the up axis</param> /// <returns></returns> public static float DirectionToRotation(OrdinalDirections dir, OrdinalDirections currUp, int rotAmount) { return(ROT_MAP[(int)currUp][rotAmount / 90][(int)dir]); }
/// <summary> /// Returns true if the face in the given direction is solid /// </summary> /// <param name="dir">The direction of the face</param> /// <returns></returns> public virtual bool IsSolid(OrdinalDirections dir) { return(VoxelData.IsSolid(dir)); }
/// <summary> /// Create a complex inverse corner with orientation and rotation /// </summary> /// <param name="addToMeshData">The mesh data to add the block to</param> /// <param name="position">The position of the block</param> /// <param name="orientation">The voxel's orientation</param> /// <param name="rotAmount">The voxel's rotation around the orientation axis (0, 90, 180, 270)</param> /// <param name="visibility">Which sides of the block are visible</param> /// <param name="voxelData">The type of voxel to render</param> /// <param name="voxelSize">The size of the voxel</param> public static void CreateComplexInverseCornerMeshData(MeshData addToMeshData, Vector3 position, OrdinalDirections orientation, int rotAmount, OrdinalBoolean visibility, VoxelData voxelData, float voxelSize) { // TODO: Implement this method }
/// <summary> /// Create a complex block with orientation and rotation /// </summary> /// <param name="addToMeshData">The mesh data to add the block to</param> /// <param name="position">The position of the block</param> /// <param name="orientation">The voxel's orientation</param> /// <param name="rotAmount">The voxel's rotation around the orientation axis (0, 90, 180, 270)</param> /// <param name="visibility">Which sides of the block are visible</param> /// <param name="voxelData">The type of voxel to render</param> /// <param name="voxelSize">The size of the voxel</param> public static void CreateComplexBlockMeshData(MeshData addToMeshData, Vector3 position, OrdinalDirections orientation, int rotAmount, OrdinalBoolean visibility, VoxelData voxelData, float voxelSize) { float rot; Vector2 uvC, uv1, uv2, uv3, uv4; OrdinalDirections dirGlob; OrdinalDirections dirLoc; for (int i = 0; i < 6; i++) { dirGlob = (OrdinalDirections)i; // Check if the side is visible and the localized face is actually a face if (visibility.GetBoolForDir(dirGlob) && voxelData.Faces.GetBoolForDir(dirLoc = OrdinalDirectionsHelper.GlobalToLocalDirection(dirGlob, orientation, rotAmount))) { rot = OrdinalDirectionsHelper.DirectionToRotation(dirGlob, orientation, rotAmount); // Mesh Data addToMeshData.AddQuad(position, dirGlob, voxelSize, 0); // Collider Data addToMeshData.AddQuadToCollider(position, dirGlob, voxelSize); // UVs uv1 = new Vector2(voxelData.Textures.GetX(dirLoc), voxelData.Textures.GetY(dirLoc)) * VoxelDataTextures.UV_SIZE_WITH_PADDING + VoxelDataTextures.TEXTURE_PADDING_OFFSET; uv2 = uv1 + new Vector2(0, VoxelDataTextures.TEXTURE_DIMENSION); uv3 = uv1 + new Vector2(VoxelDataTextures.TEXTURE_DIMENSION, VoxelDataTextures.TEXTURE_DIMENSION); uv4 = uv1 + new Vector2(VoxelDataTextures.TEXTURE_DIMENSION, 0); // Average UV Pos uvC = new Vector2((uv1.x + uv2.x + uv3.x + uv4.x) / 4, (uv1.y + uv2.y + uv3.y + uv4.y) / 4); // UV Rotation uv1 = (uv1 - uvC).Rotate(rot) + uvC; uv2 = (uv2 - uvC).Rotate(rot) + uvC; uv3 = (uv3 - uvC).Rotate(rot) + uvC; uv4 = (uv4 - uvC).Rotate(rot) + uvC; // UVs addToMeshData.AddUV(uv1); addToMeshData.AddUV(uv2); addToMeshData.AddUV(uv3); addToMeshData.AddUV(uv4); } } }
/// <summary> /// Convert from a global direction to a localized rotation, given the current up axis and amount rotated around it /// </summary> /// <param name="dir">The direction to convert</param> /// <param name="currUp">The current up axis</param> /// <param name="rotAmount">The amount rotated around the up axis</param> /// <returns></returns> public static OrdinalDirections GlobalToLocalDirection(OrdinalDirections dir, OrdinalDirections currUp, int rotAmount) { return(DIR_MAP[(int)currUp][rotAmount / 90][(int)dir]); }