/// <summary> /// Returns ready to display render information for a sidepart of this wall. /// Note: Z component is the height. /// </summary> /// <param name="PartType">Which part (upper, middle, lower)</param> /// <param name="IsLeftSide">Left or Right side</param> /// <param name="TexWidth">Texture width</param> /// <param name="TexHeight">Texture height</param> /// <param name="TexShrink">Texture shrink</param> /// <param name="Scale">Additional scale for vertices</param> /// <returns></returns> public VertexData GetVertexData(WallPartType PartType, bool IsLeftSide, int TexWidth, int TexHeight, int TexShrink, Real Scale = 1.0f) { VertexData RI = new VertexData(); bool drawTopDown = true; RooSideDefFlags flags; int xoffset = 0; int yoffset = 0; // fill vars based on left or right side if (!IsLeftSide) { RI.P0.X = P1.X; RI.P3.X = P2.X; RI.P1.X = P1.X; RI.P2.X = P2.X; RI.P0.Y = P1.Y; RI.P3.Y = P2.Y; RI.P1.Y = P1.Y; RI.P2.Y = P2.Y; flags = RightSide.Flags; xoffset = RightXOffset; yoffset = RightYOffset; switch (PartType) { case WallPartType.Upper: RI.P0.Z = z3; RI.P3.Z = zz3; RI.P1.Z = z2; RI.P2.Z = zz2; drawTopDown = !RightSide.Flags.IsAboveBottomUp; break; case WallPartType.Middle: RI.P0.Z = z2; RI.P3.Z = zz2; RI.P1.Z = z1; RI.P2.Z = zz1; drawTopDown = RightSide.Flags.IsNormalTopDown; break; case WallPartType.Lower: if (BowtieFlags.IsBelowPos || BowtieFlags.IsBelowNeg) { RI.P0.Z = z1Neg; RI.P3.Z = zz1Neg; } else { RI.P0.Z = z1; RI.P3.Z = zz1; } RI.P1.Z = z0; RI.P2.Z = zz0; drawTopDown = RightSide.Flags.IsBelowTopDown; break; } } else { RI.P0.X = P2.X; RI.P3.X = P1.X; RI.P1.X = P2.X; RI.P2.X = P1.X; RI.P0.Y = P2.Y; RI.P3.Y = P1.Y; RI.P1.Y = P2.Y; RI.P2.Y = P1.Y; flags = LeftSide.Flags; xoffset = LeftXOffset; yoffset = LeftYOffset; switch (PartType) { case WallPartType.Upper: RI.P0.Z = zz3; RI.P3.Z = z3; RI.P1.Z = zz2; RI.P2.Z = z2; drawTopDown = !LeftSide.Flags.IsAboveBottomUp; break; case WallPartType.Middle: RI.P0.Z = zz2; RI.P3.Z = z2; RI.P1.Z = zz1; RI.P2.Z = z1; drawTopDown = LeftSide.Flags.IsNormalTopDown; break; case WallPartType.Lower: RI.P0.Z = zz1; RI.P3.Z = z1; RI.P1.Z = zz0; RI.P2.Z = z0; drawTopDown = LeftSide.Flags.IsBelowTopDown; break; } } // scales Real invWidth = 1.0f / (Real)TexWidth; Real invHeight = 1.0f / (Real)TexHeight; Real invWidthFudge = 1.0f / (Real)(TexWidth << 4); Real invHeightFudge = 1.0f / (Real)(TexHeight << 4); // Start with UV calculation, see d3drender.c --- Real u1 = (Real)xoffset * (Real)TexShrink * invHeight; Real u2 = u1 + (ClientLength * (Real)TexShrink * invHeight); // set U RI.UV0.X = u1; RI.UV1.X = u1; RI.UV3.X = u2; RI.UV2.X = u2; // calculate V int bottom, top; if (!drawTopDown) { if (RI.P1.Z == RI.P2.Z) bottom = (int)RI.P1.Z; else { bottom = (int)MathUtil.Min(RI.P1.Z, RI.P2.Z); bottom = bottom & ~(GeometryConstants.FINENESS - 1); } if (RI.P0.Z == RI.P3.Z) top = (int)RI.P0.Z; else { top = (int)MathUtil.Max(RI.P0.Z, RI.P3.Z); top = (top + GeometryConstants.FINENESS - 1) & ~(GeometryConstants.FINENESS - 1); } if (RI.P1.Z == RI.P2.Z) { RI.UV1.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV2.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); } else { RI.UV1.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV2.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV1.Y -= ((Real)RI.P1.Z - bottom) * (Real)TexShrink * invWidthFudge; RI.UV2.Y -= ((Real)RI.P2.Z - bottom) * (Real)TexShrink * invWidthFudge; } RI.UV0.Y = RI.UV1.Y - ((Real)(RI.P0.Z - RI.P1.Z) * (Real)TexShrink * invWidthFudge); RI.UV3.Y = RI.UV2.Y - ((Real)(RI.P3.Z - RI.P2.Z) * (Real)TexShrink * invWidthFudge); } // else, need to place tex origin at top left else { if (RI.P0.Z == RI.P3.Z) top = (int)RI.P0.Z; else { top = (int)MathUtil.Max(RI.P0.Z, RI.P3.Z); top = (top + GeometryConstants.FINENESS - 1) & ~(GeometryConstants.FINENESS - 1); } if (RI.P1.Z == RI.P2.Z) bottom = (int)RI.P1.Z; else { bottom = (int)MathUtil.Min(RI.P1.Z, RI.P2.Z); bottom = bottom & ~(GeometryConstants.FINENESS - 1); } if (RI.P0.Z == RI.P3.Z) { RI.UV0.Y = 0.0f; RI.UV3.Y = 0.0f; } else { RI.UV0.Y = ((Real)top - RI.P0.Z) * (Real)TexShrink * invWidthFudge; RI.UV3.Y = ((Real)top - RI.P3.Z) * (Real)TexShrink * invWidthFudge; } RI.UV0.Y -= ((Real)(yoffset * TexShrink) * invWidth); RI.UV3.Y -= ((Real)(yoffset * TexShrink) * invWidth); RI.UV1.Y = RI.UV0.Y + ((RI.P0.Z - RI.P1.Z) * (Real)TexShrink * invWidthFudge); RI.UV2.Y = RI.UV3.Y + ((RI.P3.Z - RI.P2.Z) * (Real)TexShrink * invWidthFudge); } // backwards if (flags.IsBackwards) { Real temp; temp = RI.UV3.X; RI.UV3.X = RI.UV0.X; RI.UV0.X = temp; temp = RI.UV2.X; RI.UV2.X = RI.UV1.X; RI.UV1.X = temp; } // no vtile // seems to apply only to middle parts, at least for bottom it creates strange holes if (flags.IsNoVTile && PartType == WallPartType.Middle) { if (RI.UV0.Y < 0.0f) { Real tex, wall, ratio, temp; tex = RI.UV1.Y - RI.UV0.Y; if (tex == 0) tex = 1.0f; temp = -RI.UV0.Y; ratio = temp / tex; wall = RI.P0.Z - RI.P1.Z; temp = wall * ratio; RI.P0.Z -= temp; RI.UV0.Y = 0.0f; } if (RI.UV3.Y < 0.0f) { Real tex, wall, ratio, temp; tex = RI.UV2.Y - RI.UV3.Y; if (tex == 0) tex = 1.0f; temp = -RI.UV3.Y; ratio = temp / tex; wall = RI.P3.Z - RI.P2.Z; temp = wall * ratio; RI.P3.Z -= temp; RI.UV3.Y = 0.0f; } RI.P1.Z -= 16.0f; RI.P2.Z -= 16.0f; } RI.UV0.Y += 1.0f / TexWidth; RI.UV3.Y += 1.0f / TexWidth; RI.UV1.Y -= 1.0f / TexWidth; RI.UV2.Y -= 1.0f / TexWidth; // scale by user scale RI.P0 *= Scale; RI.P3 *= Scale; RI.P1 *= Scale; RI.P2 *= Scale; // calculate the normal V3 P0P1 = (RI.P1 - RI.P0); V3 P0P2 = (RI.P2 - RI.P0); RI.Normal = P0P1.CrossProduct(P0P2); RI.Normal.Normalize(); RI.Normal = -RI.Normal; return RI; }
/// <summary> /// Returns ready to display render information for a sidepart of this wall. /// Note: Z component is the height. /// </summary> /// <param name="PartType">Which part (upper, middle, lower)</param> /// <param name="IsLeftSide">Left or Right side</param> /// <param name="TexWidth">Texture width</param> /// <param name="TexHeight">Texture height</param> /// <param name="TexShrink">Texture shrink</param> /// <param name="Scale">Additional scale for vertices</param> /// <returns></returns> public RenderInfo GetRenderInfo(WallPartType PartType, bool IsLeftSide, int TexWidth, int TexHeight, int TexShrink, Real Scale = 1.0f) { RenderInfo RI = new RenderInfo(); bool drawTopDown = true; RooSideDefFlags flags; int xoffset = 0; int yoffset = 0; // fill vars based on left or right side if (!IsLeftSide) { RI.P0.X = X1; RI.P3.X = X2; RI.P1.X = X1; RI.P2.X = X2; RI.P0.Y = Y1; RI.P3.Y = Y2; RI.P1.Y = Y1; RI.P2.Y = Y2; flags = RightSide.Flags; xoffset = RightXOffset; yoffset = RightYOffset; switch (PartType) { case WallPartType.Upper: RI.P0.Z = Z3; RI.P3.Z = ZZ3; RI.P1.Z = Z2; RI.P2.Z = ZZ2; drawTopDown = !RightSide.Flags.IsAboveBottomUp; break; case WallPartType.Middle: RI.P0.Z = Z2; RI.P3.Z = ZZ2; RI.P1.Z = Z1; RI.P2.Z = ZZ1; drawTopDown = RightSide.Flags.IsNormalTopDown; break; case WallPartType.Lower: RI.P0.Z = Z1; RI.P3.Z = ZZ1; RI.P1.Z = Z0; RI.P2.Z = ZZ0; drawTopDown = RightSide.Flags.IsBelowTopDown; break; } } else { RI.P0.X = X2; RI.P3.X = X1; RI.P1.X = X2; RI.P2.X = X1; RI.P0.Y = Y2; RI.P3.Y = Y1; RI.P1.Y = Y2; RI.P2.Y = Y1; flags = LeftSide.Flags; xoffset = LeftXOffset; yoffset = LeftYOffset; switch (PartType) { case WallPartType.Upper: RI.P0.Z = ZZ3; RI.P3.Z = Z3; RI.P1.Z = ZZ2; RI.P2.Z = Z2; drawTopDown = !LeftSide.Flags.IsAboveBottomUp; break; case WallPartType.Middle: RI.P0.Z = ZZ2; RI.P3.Z = Z2; RI.P1.Z = ZZ1; RI.P2.Z = Z1; drawTopDown = LeftSide.Flags.IsNormalTopDown; break; case WallPartType.Lower: RI.P0.Z = ZZ1; RI.P3.Z = Z1; RI.P1.Z = ZZ0; RI.P2.Z = Z0; drawTopDown = LeftSide.Flags.IsBelowTopDown; break; } } // scales Real invWidth = 1.0f / (Real)TexWidth; Real invHeight = 1.0f / (Real)TexHeight; Real invWidthFudge = 1.0f / (Real)(TexWidth << 4); Real invHeightFudge = 1.0f / (Real)(TexHeight << 4); // Start with UV calculation, see d3drender.c --- Real u1 = (Real)xoffset * (Real)TexShrink * invHeight; Real u2 = u1 + ((Real)ClientLength * (Real)TexShrink * invHeight); // set U RI.UV0.X = u1; RI.UV1.X = u1; RI.UV3.X = u2; RI.UV2.X = u2; // calculate V int bottom, top; if (!drawTopDown) { if (RI.P1.Z == RI.P2.Z) { bottom = (int)RI.P1.Z; } else { bottom = (int)MathUtil.Min(RI.P1.Z, RI.P2.Z); bottom = bottom & ~(GeometryConstants.FINENESS - 1); } if (RI.P0.Z == RI.P3.Z) { top = (int)RI.P0.Z; } else { top = (int)MathUtil.Max(RI.P0.Z, RI.P3.Z); top = (top + GeometryConstants.FINENESS - 1) & ~(GeometryConstants.FINENESS - 1); } if (RI.P1.Z == RI.P2.Z) { RI.UV1.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV2.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); } else { RI.UV1.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV2.Y = 1.0f - ((Real)yoffset * (Real)TexShrink * invWidth); RI.UV1.Y -= ((Real)RI.P1.Y - bottom) * (Real)TexShrink * invWidthFudge; RI.UV2.Y -= ((Real)RI.P2.Y - bottom) * (Real)TexShrink * invWidthFudge; } RI.UV0.Y = RI.UV1.Y - ((Real)(RI.P0.Z - RI.P1.Z) * (Real)TexShrink * invWidthFudge); RI.UV3.Y = RI.UV2.Y - ((Real)(RI.P3.Z - RI.P2.Z) * (Real)TexShrink * invWidthFudge); } // else, need to place tex origin at top left else { if (RI.P0.Z == RI.P3.Z) { top = (int)RI.P0.Z; } else { top = (int)MathUtil.Max(RI.P0.Z, RI.P3.Z); top = (top + GeometryConstants.FINENESS - 1) & ~(GeometryConstants.FINENESS - 1); } if (RI.P1.Z == RI.P2.Z) { bottom = (int)RI.P1.Z; } else { bottom = (int)MathUtil.Min(RI.P1.Z, RI.P2.Z); bottom = bottom & ~(GeometryConstants.FINENESS - 1); } if (RI.P0.Z == RI.P3.Z) { RI.UV0.Y = 0.0f; RI.UV3.Y = 0.0f; } else { RI.UV0.Y = ((Real)top - RI.P0.Z) * (Real)TexShrink * invWidthFudge; RI.UV3.Y = ((Real)top - RI.P3.Z) * (Real)TexShrink * invWidthFudge; } RI.UV0.Y -= ((Real)(yoffset * TexShrink) * invWidth); RI.UV3.Y -= ((Real)(yoffset * TexShrink) * invWidth); RI.UV1.Y = RI.UV0.Y + ((RI.P0.Z - RI.P1.Z) * (Real)TexShrink * invWidthFudge); RI.UV2.Y = RI.UV3.Y + ((RI.P3.Z - RI.P2.Z) * (Real)TexShrink * invWidthFudge); } // backwards if (flags.IsBackwards) { Real temp; temp = RI.UV3.X; RI.UV3.X = RI.UV0.X; RI.UV0.X = temp; temp = RI.UV2.X; RI.UV2.X = RI.UV1.X; RI.UV1.X = temp; } // no vtile // seems to apply only to middle parts, at least for bottom it creates strange holes if (flags.IsNoVTile && PartType == WallPartType.Middle) { if (RI.UV0.Y < 0.0f) { Real tex, wall, ratio, temp; tex = RI.UV1.Y - RI.UV0.Y; if (tex == 0) { tex = 1.0f; } temp = -RI.UV0.Y; ratio = temp / tex; wall = RI.P0.Z - RI.P1.Z; temp = wall * ratio; RI.P0.Z -= temp; RI.UV0.Y = 0.0f; } if (RI.UV3.Y < 0.0f) { Real tex, wall, ratio, temp; tex = RI.UV2.Y - RI.UV3.Y; if (tex == 0) { tex = 1.0f; } temp = -RI.UV3.Y; ratio = temp / tex; wall = RI.P3.Z - RI.P2.Z; temp = wall * ratio; RI.P3.Z -= temp; RI.UV3.Y = 0.0f; } RI.P1.Z -= 16.0f; RI.P2.Z -= 16.0f; } RI.UV0.Y += 1.0f / TexWidth; RI.UV3.Y += 1.0f / TexWidth; RI.UV1.Y -= 1.0f / TexWidth; RI.UV2.Y -= 1.0f / TexWidth; // scale by user scale RI.P0 *= Scale; RI.P3 *= Scale; RI.P1 *= Scale; RI.P2 *= Scale; // calculate the normal V3 P0P1 = (RI.P1 - RI.P0); V3 P0P2 = (RI.P2 - RI.P0); RI.Normal = P0P1.CrossProduct(P0P2); RI.Normal.Normalize(); RI.Normal = -RI.Normal; return(RI); }
public WallTextureChangedEventArgs(RooSideDef ChangedSide, WallPartType WallPartType) { this.ChangedSide = ChangedSide; this.WallPartType = WallPartType; }
public WallTextureChangedEventArgs(RooSideDef ChangedSide, WallPartType WallPartType, string OldMaterialName) { this.ChangedSide = ChangedSide; this.WallPartType = WallPartType; this.OldMaterialName = OldMaterialName; }