diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/Rect.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/scape/Rect.java')
| -rw-r--r-- | NET/worlds/scape/Rect.java | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/NET/worlds/scape/Rect.java b/NET/worlds/scape/Rect.java new file mode 100644 index 0000000..9613dd3 --- /dev/null +++ b/NET/worlds/scape/Rect.java @@ -0,0 +1,421 @@ +package NET.worlds.scape; + +import NET.worlds.console.Console; +import NET.worlds.console.DefaultConsole; +import java.io.IOException; + +public class Rect extends Surface implements MouseDownHandler, FrameHandler, Prerenderable { + static BumpCalc standardPlaneBumpCalc = new PlaneBumpCalc(); + Billboard _billboardAttribute = null; + VideoTexture _videoAttribute = null; + boolean visible = false; + protected float u = 1.0F; + protected float v = 1.0F; + protected float uOff; + protected float vOff; + private static Object classCookie = new Object(); + + static { + standardPlaneBumpCalc.setName("defaultPlaneBumpCalc"); + } + + public Rect(float w, float h, Material material) { + super(material); + this.scale(w, h, h); + } + + public Rect(float x, float y, float z, Material material) { + super(material); + this.setFarCorner(Point3Temp.make(x, y, z)); + } + + public Rect(float llx, float lly, float llz, float urx, float ury, float urz, Material material) { + super(material); + this.moveBy(llx, lly, llz); + this.setFarCorner(Point3Temp.make(urx, ury, urz)); + } + + public Rect(Point3Temp llc, Point3Temp urc, Material material) { + this(llc.x, llc.y, llc.z, urc.x, urc.y, urc.z, material); + } + + Rect() { + } + + public static boolean setFarCornerHelper(Transform t, Point3Temp newCorner) { + t.scale(1.0F / t.getScaleX(), 1.0F / t.getScaleY(), 1.0F / t.getScaleZ()); + Point3Temp lookRight = Point3Temp.make(1.0F, 0.0F, 0.0F).vectorTimes(t); + Point3Temp lookOut = Point3Temp.make(0.0F, 1.0F, 0.0F).vectorTimes(t); + Point3Temp lookUp = Point3Temp.make(0.0F, 0.0F, 1.0F).vectorTimes(t); + Point3Temp newEndOffset = Point3Temp.make(newCorner).minus(t.getPosition()); + float x = newEndOffset.dot(lookRight); + float y = newEndOffset.dot(lookOut); + float z = newEndOffset.dot(lookUp); + if (!(z >= 0.0F)) { + return false; + } else { + if (x != 0.0F || y != 0.0F) { + t.spin(0.0F, 0.0F, 1.0F, (float)(Math.atan2(y, x) * 180.0 / Math.PI)); + } + + t.scale((float)Math.sqrt(x * x + y * y), z, z); + return true; + } + } + + public boolean setFarCorner(Point3Temp newCorner) { + Transform t = this.getTransform(); + if (setFarCornerHelper(t, newCorner)) { + this.setTransform(t); + t.recycle(); + return true; + } else { + t.recycle(); + Console.println(Console.message("cant-rot-rect")); + return false; + } + } + + public Point3Temp getFarCorner() { + Point3Temp ret = Point3Temp.make(1.0F, 0.0F, 1.0F); + if (this.hasClump()) { + Transform t = this.getObjectToWorldMatrix(); + ret.times(t); + t.recycle(); + } else { + ret.times(this); + } + + return ret; + } + + public Point3Temp getFarCornerLocal() { + Point3Temp ret = Point3Temp.make(1.0F, 0.0F, 1.0F); + if (this.hasClump()) { + Transform t = this.getTransform(); + ret.times(t); + t.recycle(); + } else { + ret.times(this); + } + + return ret; + } + + public void setNearCorner(Point3Temp from) { + Point3Temp oldEnd = this.getFarCornerLocal(); + Point3Temp oldStart = this.getPosition(); + this.moveTo(from); + if (!this.setFarCorner(oldEnd)) { + this.moveTo(oldStart); + } + } + + @Override + public Point3Temp getPlaneExtent() { + return Point3Temp.make(1.0F, 0.0F, 1.0F); + } + + @Override + public BumpCalc getBumpCalc(BumpEventTemp b) { + return this.bumpCalc == null ? standardPlaneBumpCalc : this.bumpCalc; + } + + public Point2 getTileSize() { + return new Point2(this.u != 1.0F ? this.getScaleX() / this.u : 0.0F, this.v != 1.0F ? this.getScaleZ() / this.v : 0.0F); + } + + void setUV(float u, float v) { + this.setTileSize(this.getScaleX() / u, this.getScaleZ() / v); + } + + public Rect setTileSize(float tx, float ty) { + this.u = tx == 0.0F ? 1.0F : this.getScaleX() / tx; + this.v = ty == 0.0F ? 1.0F : this.getScaleZ() / ty; + this.reclump(); + return this; + } + + public void setTileOffset(Point2 p) { + this.uOff = this.getScaleX() == 0.0F ? 0.0F : p.x / this.getScaleX(); + this.vOff = this.getScaleZ() == 0.0F ? 0.0F : p.y / this.getScaleZ(); + this.reclump(); + } + + public Point2 getTileOffset() { + return new Point2(this.uOff * this.getScaleX(), this.vOff * this.getScaleZ()); + } + + public static Rect floor(float x, float y, Material m) { + return (Rect)new Rect(x, y, m).setBumpable(false).postspin(1.0F, 0.0F, 0.0F, -90.0F); + } + + public static Rect floor(float llx, float lly, float z, float urx, float ury, Material m) { + return (Rect)floor(urx - llx, ury - lly, m).moveBy(llx, lly, z); + } + + public static Rect ceiling(float x, float y, Material m) { + return (Rect)new Rect(x, y, m).setBumpable(false).postspin(1.0F, 0.0F, 0.0F, 90.0F).moveBy(0.0F, y, 0.0F); + } + + public static Rect ceiling(float llx, float lly, float z, float urx, float ury, Material m) { + return (Rect)ceiling(urx - llx, ury - lly, m).moveBy(llx, lly, z); + } + + public Rect hang(float pllx, float pllz, float purx, float purz, Material pic) { + Rect r = (Rect)new Rect((purx - pllx) / this.getScaleX(), (purz - pllz) / this.getScaleZ(), pic) + .moveBy(pllx / this.getScaleX(), 0.0F, pllz / this.getScaleZ()) + .post(this); + return (Rect)r.premoveBy(0.0F, -1.0F / r.getScale().length(), 0.0F); + } + + public VideoTexture getVideoAttribute() { + return this._videoAttribute; + } + + public Billboard getBillboardAttribute() { + return this._billboardAttribute; + } + + @Override + public boolean handle(MouseDownEvent event) { + if (this._billboardAttribute != null && (event.key & 1) == 1) { + Point2 pt = this.deproject(); + this._billboardAttribute.billboardClicked(pt); + } + + return false; + } + + @Override + public boolean handle(FrameEvent f) { + if (this._billboardAttribute != null && this.getVisible() && this.visible) { + this._billboardAttribute.billboardFrame(f); + } + + if (this._videoAttribute != null && this.getVisible() && this.visible) { + this._videoAttribute.videoFrame(f); + } + + this.visible = false; + return false; + } + + @Override + public void prerender(Camera cam) { + if (this._billboardAttribute != null || this._videoAttribute != null) { + Point3Temp p = this.inCamSpace(cam); + boolean v = p != null && p.z > 1.0F && p.x < p.z && -p.x < p.z; + if (v) { + this.visible = true; + } + } + } + + protected Point2 deproject() { + Console c = Console.getActive(); + if (c instanceof DefaultConsole) { + DefaultConsole dc = (DefaultConsole)c; + Point3Temp worldClick = dc.getRender().getCamera().lastPickSpot(); + Point3Temp vWorld = Point3Temp.make(worldClick); + vWorld.minus(this.getObjectToWorldMatrix().getPosition()); + Transform inv = this.getObjectToWorldMatrix().invert(); + Point3Temp vObj = Point3Temp.make(vWorld).vectorTimes(inv); + inv.recycle(); + Point2 rectPt = new Point2(); + rectPt.set(vObj.x, vObj.z); + return rectPt; + } else { + return new Point2(-1.0F, -1.0F); + } + } + + @Override + protected void addRwChildren(WObject container) { + this.addNewRwChild(container); + float uo = this.uOff; + if (uo != 0.0F) { + uo *= this.u; + uo = (float)(uo - 2.0 * Math.floor(uo / 2.0F)); + } + + float vo = this.vOff; + if (vo != 0.0F) { + vo *= this.v; + vo = (float)(vo - 2.0 * Math.floor(vo / 2.0F)); + } + + this.addVertex(0.0F, 0.0F, 0.0F, uo, this.v + vo); + this.addVertex(1.0F, 0.0F, 0.0F, this.u + uo, this.v + vo); + this.addVertex(1.0F, 0.0F, 1.0F, this.u + uo, vo); + this.addVertex(0.0F, 0.0F, 1.0F, uo, vo); + this.doneWithEditing(); + if (!(this instanceof Portal)) { + this.getRoom().addPrerenderHandler(this); + } + } + + @Override + protected void markVoid() { + if (!(this instanceof Portal)) { + this.getRoom().removePrerenderHandler(this); + } + + super.markVoid(); + } + + @Override + public Object properties(int index, int offset, int mode, Object value) throws NoSuchPropertyException { + Object ret = null; + switch (index - offset) { + case 0: + if (mode == 0) { + ret = Point2PropertyEditor.make(new Property(this, index, "Tile Size")); + } else if (mode == 1) { + ret = this.getTileSize(); + } else if (mode == 2) { + Point2 p = (Point2)value; + if (!(p.x < 0.0F) && !(p.y < 0.0F)) { + this.setTileSize(p.x, p.y); + } else { + Console.println(Console.message("Tile-size")); + } + } + break; + case 1: + if (mode == 0) { + ret = Point2PropertyEditor.make(new Property(this, index, "Tile Origin")); + } else if (mode == 1) { + ret = this.getTileOffset(); + } else if (mode == 2) { + this.setTileOffset((Point2)value); + } + break; + case 2: + if (mode == 0) { + ret = Point3PropertyEditor.make(new Property(this, index, "From")); + } else if (mode == 1) { + ret = new Point3(this.getPosition()); + } else if (mode == 2) { + this.setNearCorner((Point3)value); + } + break; + case 3: + if (mode == 0) { + ret = Point3PropertyEditor.make(new Property(this, index, "To")); + } else if (mode == 1) { + ret = new Point3(this.getFarCornerLocal()); + } else if (mode == 2) { + this.setFarCorner((Point3)value); + } + break; + case 4: + if (mode == 0) { + ret = Point2PropertyEditor.make(new Property(this, index, "Extent")); + } else if (mode == 1) { + ret = new Point2(this.getScaleX(), this.getScaleZ()); + } else if (mode == 2) { + float zScale = ((Point2)value).y / this.getScaleZ(); + this.scale(((Point2)value).x / this.getScaleX(), zScale, zScale); + } + break; + case 5: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Flip Alternate U"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean(this.getUFlip()); + } else if (mode == 2) { + this.setUFlip((Boolean)value); + this.reclump(); + } + break; + case 6: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Flip Alternate V"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean(this.getVFlip()); + } else if (mode == 2) { + this.setVFlip((Boolean)value); + this.reclump(); + } + break; + case 7: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Unused"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean(this.getMouseOver()); + } else if (mode == 2) { + this.setMouseOver((Boolean)value); + } + break; + default: + ret = super.properties(index, offset + 8, mode, value); + } + + return ret; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(4, classCookie); + super.saveState(s); + s.saveFloat(this.u); + s.saveFloat(this.v); + s.saveFloat(this.uOff); + s.saveFloat(this.vOff); + s.saveBoolean(false); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + int vers = r.restoreVersion(classCookie); + switch (vers) { + case 0: + case 1: + super.restoreState(r); + float x = r.restoreFloat(); + float y = r.restoreFloat(); + float z = r.restoreFloat(); + r.restoreFloat(); + r.restoreFloat(); + r.restoreFloat(); + this.u = r.restoreFloat(); + this.v = r.restoreFloat(); + this.spin(0.0F, 0.0F, 1.0F, (float)(Math.atan2(y, x) * 180.0 / Math.PI)); + this.scale((float)Math.sqrt(x * x + y * y), z, z); + break; + case 2: + super.restoreState(r); + this.u = r.restoreFloat(); + this.v = r.restoreFloat(); + break; + case 3: + super.restoreState(r); + this.u = r.restoreFloat(); + this.v = r.restoreFloat(); + this.uOff = r.restoreFloat(); + this.vOff = r.restoreFloat(); + break; + case 4: + super.restoreState(r); + this.u = r.restoreFloat(); + this.v = r.restoreFloat(); + this.uOff = r.restoreFloat(); + this.vOff = r.restoreFloat(); + r.restoreBoolean(); + break; + default: + throw new TooNewException(); + } + } + + @Override + public String toString() { + return super.toString() + "[" + this.getPosition() + "->" + this.getFarCornerLocal() + "]"; + } + + @Override + public boolean acceptsLeftClicks() { + return this._billboardAttribute != null && this._billboardAttribute.getIsAdBanner() ? true : this.getMouseOver(); + } +} |