Gary_Oak Posted November 23, 2016 Posted November 23, 2016 (edited) Hey everyone I found an interesting tutorial about how to create a 3D object with an awt graphics object and I adapted this code into a script. The result is an interesting paint overlay. Here is a proof of concept: The sphere perfectly loops but the gif doesn't My Source code: package osbot; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import org.osbot.rs07.api.filter.Filter; import org.osbot.rs07.api.map.Position; import org.osbot.rs07.api.map.constants.Banks; import org.osbot.rs07.api.model.Item; import org.osbot.rs07.api.model.Player; import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; @ScriptManifest(name = "3D Paint", author = "Gary_Oak", version = 1.0, info = "", logo = "") public class Main extends Script { private int width = 400; private int height = 400; private double rotate = -180; private int xOffset = 10; private int yOffset = 10; @[member='Override'] public void onStart() { } @[member='Override'] public void onExit() { // Code here will execute after the script ends } @[member='Override'] public int onLoop() { if (rotate >= 180) { rotate = -180; } this.rotate = this.rotate + 1; return 100; // The amount of time in milliseconds before the loop starts // over } @[member='Override'] public void onPaint(Graphics2D g) { Graphics2D g2 = (Graphics2D) g; g2.setColor(new Color(0, 0, 0, 0)); g2.fillRect(0, 0, this.width, this.height); List<Triangle> tris = new ArrayList<>(); tris.add(new Triangle(new Vertex(100, 100, 100), new Vertex(-100, -100, 100), new Vertex(-100, 100, -100), Color.WHITE)); tris.add(new Triangle(new Vertex(100, 100, 100), new Vertex(-100, -100, 100), new Vertex(100, -100, -100), Color.RED)); tris.add(new Triangle(new Vertex(-100, 100, -100), new Vertex(100, -100, -100), new Vertex(100, 100, 100), Color.GREEN)); tris.add(new Triangle(new Vertex(-100, 100, -100), new Vertex(100, -100, -100), new Vertex(-100, -100, 100), Color.BLUE)); for (int i = 0; i < 4; i++) { tris = inflate(tris); } double heading = Math.toRadians(this.rotate); Matrix3 headingTransform = new Matrix3(new double[] { Math.cos(heading), 0, -Math.sin(heading), 0, 1, 0, Math.sin(heading), 0, Math.cos(heading) }); double pitch = Math.toRadians(this.rotate); Matrix3 pitchTransform = new Matrix3( new double[] { 1, 0, 0, 0, Math.cos(pitch), Math.sin(pitch), 0, -Math.sin(pitch), Math.cos(pitch) }); Matrix3 transform = headingTransform.multiply(pitchTransform); BufferedImage img = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_ARGB); double[] zBuffer = new double[img.getWidth() * img.getHeight()]; // initialize array with extremely far away depths for (int q = 0; q < zBuffer.length; q++) { zBuffer[q] = Double.NEGATIVE_INFINITY; } for (Triangle t : tris) { Vertex v1 = transform.transform(t.v1); v1.x += this.width / 2; v1.y += this.height / 2; Vertex v2 = transform.transform(t.v2); v2.x += this.width / 2; v2.y += this.height / 2; Vertex v3 = transform.transform(t.v3); v3.x += this.width / 2; v3.y += this.height / 2; Vertex ab = new Vertex(v2.x - v1.x, v2.y - v1.y, v2.z - v1.z); Vertex ac = new Vertex(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z); Vertex norm = new Vertex(ab.y * ac.z - ab.z * ac.y, ab.z * ac.x - ab.x * ac.z, ab.x * ac.y - ab.y * ac.x); double normalLength = Math.sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z); norm.x /= normalLength; norm.y /= normalLength; norm.z /= normalLength; double angleCos = Math.abs(norm.z); int minX = (int) Math.max(0, Math.ceil(Math.min(v1.x, Math.min(v2.x, v3.x)))); int maxX = (int) Math.min(img.getWidth() - 1, Math.floor(Math.max(v1.x, Math.max(v2.x, v3.x)))); int minY = (int) Math.max(0, Math.ceil(Math.min(v1.y, Math.min(v2.y, v3.y)))); int maxY = (int) Math.min(img.getHeight() - 1, Math.floor(Math.max(v1.y, Math.max(v2.y, v3.y)))); double triangleArea = (v1.y - v3.y) * (v2.x - v3.x) + (v2.y - v3.y) * (v3.x - v1.x); for (int y = minY; y <= maxY; y++) { for (int x = minX; x <= maxX; x++) { double b1 = ((y - v3.y) * (v2.x - v3.x) + (v2.y - v3.y) * (v3.x - x)) / triangleArea; double b2 = ((y - v1.y) * (v3.x - v1.x) + (v3.y - v1.y) * (v1.x - x)) / triangleArea; double b3 = ((y - v2.y) * (v1.x - v2.x) + (v1.y - v2.y) * (v2.x - x)) / triangleArea; if (b1 >= 0 && b1 <= 1 && b2 >= 0 && b2 <= 1 && b3 >= 0 && b3 <= 1) { double depth = b1 * v1.z + b2 * v2.z + b3 * v3.z; int zIndex = y * img.getWidth() + x; if (zBuffer[zIndex] < depth) { img.setRGB(x, y, getShade(t.color, angleCos).getRGB()); zBuffer[zIndex] = depth; } } } } } g2.drawImage(img, 0, 0, null); } public static Color getShade(Color color, double shade) { double redLinear = Math.pow(color.getRed(), 2.4) * shade; double greenLinear = Math.pow(color.getGreen(), 2.4) * shade; double blueLinear = Math.pow(color.getBlue(), 2.4) * shade; int red = (int) Math.pow(redLinear, 1 / 2.4); int green = (int) Math.pow(greenLinear, 1 / 2.4); int blue = (int) Math.pow(blueLinear, 1 / 2.4); return new Color(red, green, blue); } public static List<Triangle> inflate(List<Triangle> tris) { List<Triangle> result = new ArrayList<>(); for (Triangle t : tris) { Vertex m1 = new Vertex((t.v1.x + t.v2.x) / 2, (t.v1.y + t.v2.y) / 2, (t.v1.z + t.v2.z) / 2); Vertex m2 = new Vertex((t.v2.x + t.v3.x) / 2, (t.v2.y + t.v3.y) / 2, (t.v2.z + t.v3.z) / 2); Vertex m3 = new Vertex((t.v1.x + t.v3.x) / 2, (t.v1.y + t.v3.y) / 2, (t.v1.z + t.v3.z) / 2); result.add(new Triangle(t.v1, m1, m3, t.color)); result.add(new Triangle(t.v2, m1, m2, t.color)); result.add(new Triangle(t.v3, m2, m3, t.color)); result.add(new Triangle(m1, m2, m3, t.color)); } for (Triangle t : result) { for (Vertex v : new Vertex[] { t.v1, t.v2, t.v3 }) { double l = Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) / Math.sqrt(30000); v.x /= l; v.y /= l; v.z /= l; } } return result; } } package osbot; public class Matrix3 { double[] values; Matrix3(double[] values) { this.values = values; } Matrix3 multiply(Matrix3 other) { double[] result = new double[9]; for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { for (int i = 0; i < 3; i++) { result[row * 3 + col] += this.values[row * 3 + i] * other.values[i * 3 + col]; } } } return new Matrix3(result); } Vertex transform(Vertex in) { return new Vertex(in.x * values[0] + in.y * values[3] + in.z * values[6], in.x * values[1] + in.y * values[4] + in.z * values[7], in.x * values[2] + in.y * values[5] + in.z * values[8]); } } package osbot; import java.awt.Color; public class Triangle { Vertex v1; Vertex v2; Vertex v3; Color color; Triangle(Vertex v1, Vertex v2, Vertex v3, Color color) { this.v1 = v1; this.v2 = v2; this.v3 = v3; this.color = color; } } package osbot; public class Vertex { double x; double y; double z; Vertex(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } } Original code and article: http://blog.rogach.org/2015/08/how-to-create-your-own-simple-3d-render.html https://gist.github.com/Rogach/f3dfd457d7ddb5fcfd99 Edited November 23, 2016 by Gary_Oak 5
Prolax Posted April 26, 2017 Posted April 26, 2017 On 23/11/2016 at 7:24 AM, Botre said: lolololololololol Fur Sure