summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/Rect.java
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-12 22:33:32 -0800
committerFuwn <[email protected]>2026-02-12 22:33:32 -0800
commitc7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch)
treedf9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/scape/Rect.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/Rect.java')
-rw-r--r--NET/worlds/scape/Rect.java421
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();
+ }
+}