www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: AGP on February 07, 2017, 06:52:55 am

Title: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 07, 2017, 06:52:55 am
I'm trying to paint an area of my 3d plane as a cursor is moved (think area selection for building in a strategy game). The furthest (farthest?) I got was:
Code: [Select]
VisList visList = theWorld.getVisibilityList();
int polyID = Interact2D.getPolygonID(Interact2D.pickPolygon(visList, Interact2D.reproject2D3D(theCamera, buffer, x, y)));
I assume that camera-space is all I need here, since the docs suggest reproject2D3D and not reproject2D3DWS. Even if this is right, how can I now get something useful out of it (like, say, the vertices of the returned polygon)?
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: EgonOlsen on February 07, 2017, 08:35:59 am
You can get the (transformed) vertices from the PolygonManager by the polygon's ID. Not sure if that really helps here though. If you need the actual raw data for manipulating the polygons in a VertexController or something like that, you have create a kind of mapping between them. However, once they are compiled, your options to fiddle around with the polygons/vertices are limited anyway.
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 07, 2017, 04:28:45 pm
I'm using the software renderer, so I can use the vertices. What about the surrounding triangles?
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: EgonOlsen on February 08, 2017, 08:25:10 am
You could guess them by matching coordinates and such....not sure if that's a great approach though.
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 08, 2017, 07:36:59 pm
What would you suggest instead?
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: EgonOlsen on February 08, 2017, 08:53:18 pm
Not sure...what exactly do you want to achieve? Is that supposed to be a marker that moves or a permanent selection?
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 09, 2017, 02:45:46 am
I'm trying to do this: https://www.dropbox.com/s/wprxc3w7mw8mry3/Dune2.png?dl=0 (https://www.dropbox.com/s/wprxc3w7mw8mry3/Dune2.png?dl=0)
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: EgonOlsen on February 09, 2017, 08:37:58 am
In that case, you might have a know order in which the terrain has been build. I would rather rely on that instead of extracting the lost information from the mesh again. If you have to do it that way, then you could find a polygon's adjacent polygons by comparing the vertices.
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 09, 2017, 05:08:12 pm
In this particular case, I created the plane with the Primitives class. Is that no good or is there some kind of loop I could undergo to map the triangles?
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: EgonOlsen on February 09, 2017, 07:11:31 pm
Yes, you could use a combination of a vertex controller and the PolygonManager to map your polygons. I can't find an example for this ATM, but I'm pretty sure that I did similar things in the past.
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 09, 2017, 08:22:01 pm
I wrote this:
Code: [Select]
import com.threed.jpct.Object3D;

public class Ground {
     protected IntelligentPlane[][] planes;

     public Ground(int sizeX, int sizeY) {
planes = new IntelligentPlane[sizeX][sizeY];
for (int y = 0; y < sizeY; y++)
     for (int x = 0; x < sizeX; x++)
planes[x][y] = new IntelligentPlane(x, y);
     }
     public void setName(String name) {
for (int y = 0; y < sizeY; y++)
     for (int x = 0; x < sizeX; x++)
planes[x][y].setName(name +" ("+x+", "+y +")");
     }
}
class IntelligentPlane extends Object3D {
     public int x, y;
     public IntelligentPlane(int x, int y) {
super(Primitives.getPlane(1, 1f));
this.x = x;
this.y = y;
plane.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
     }
}

Now, how could I map chunks of the map into their appropriate triangles?
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: EgonOlsen on February 10, 2017, 08:49:22 am
By getting all polygons (or to be more precise: their vertices) from the PolygonManager and grouping them based on shared vertices and/or position in 3d space.
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 10, 2017, 03:02:42 pm
Sorry, I meant, "how do I break up the texture map into tiny maps for each plane?"
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 10, 2017, 04:14:28 pm
This is what I have for Ground.setTexture(String):

Code: [Select]
     public void setTexture(String name) {

Texture tex = com.threed.jpct.TextureManager.getInstance().getTexture(name);
Texture[][] subTextures = new Texture[planes.length][planes[0].length];

int sizeX = planes.length, sizeY = planes[0].length;
int width = tex.getWidth()/sizeX, height = tex.getHeight()/sizeY;
for (int y = 0; y < sizeY; y++)
     for (int x = 0; x < sizeX; x++) {
subTextures[x][y] = new Texture(width, height);
//NOW HOW TO PAINT A TEXTURE CHUNK INTO THIS SUB TEXTURE?
     }
}
     }
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 10, 2017, 04:54:27 pm
I made an AWT hack (as seen in the bottom). But now the line that's keeping me is this (level being an instance of Ground):         SimpleVector pV = Interact2D.project3D2D(theCamera, buffer, level.getPolygonManager().getTransformedVertex(constructionPolyID, 0));
How do I do this with the Ground class?

Code: [Select]
     public void setTexture(Image tex) {
BufferedImage bImage = new BufferedImage(tex.getWidth(null), tex.getHeight(null));
bImage.getGraphics().drawImage(tex, 0, 0, null);
Texture[][] subTextures = new Texture[planes.length][planes[0].length];
int sizeX = planes.length, sizeY = planes[0].length;
int width = tex.getWidth()/sizeX, height = tex.getHeight()/sizeY;
for (int y = 0; y < sizeY; y++) {
     for (int x = 0; x < sizeX; x++) {
subTextures[x][y] = new Texture(bImage.getSubImage(sizeX*x, sizeY*y, width, height));
TextureManager.getInstance().addTexture("Ground "+"("+x+", "+y+")");
planes[x][y].setTexture("Ground "+"("+x+", "+y+")");
     }
}
     }
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 10, 2017, 06:00:40 pm
My best attempt. Chunk isn't null but Interact2D.project3D2D's product is.

Code: [Select]
     IntelligentPlane chunk = level.get(level.selectedX, level.selectedY);
     SimpleVector pV = Interact2D.project3D2D(theCamera, buffer, chunk.getPolygonManager().getTransformedVertex(constructionPolyID, 0));
System.out.println("Is chunk null? "+(chunk==null) +" Is pV? "+(pV==null));
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: EgonOlsen on February 10, 2017, 06:58:24 pm
I'm confused now, so I took a step back and created a simple prototype of what I think this is supposed to do.

This works for software rendering or uncompiled objects only. If it should be applied to compiled objects, one would have to switch from individual textures to a texture atlas and changing uv-coordinates instead. Anyway, I hope this helps. It draws red squares on a green surface (or yellow ones if you press the button and drag the mouse). It uses it's own method to create the plane but it should work with planes from Primitives as well. But this way, the texturing can be handled more flexible.

Code: [Select]
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

import com.threed.jpct.Camera;
import com.threed.jpct.CollisionEvent;
import com.threed.jpct.CollisionListener;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Interact2D;
import com.threed.jpct.Lights;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureInfo;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;

public class DuneReloaded extends JFrame implements MouseMotionListener, CollisionListener {

private static final long serialVersionUID = 1L;
private int x, y;
private Graphics g;
private World world;
private FrameBuffer fb;
private Object3D plane;
private boolean yellow=false;

public static void main(String args[]) {
new DuneReloaded().run();
}

private void run() {
init();

while (true) {
follow();
fb.clear();
world.renderScene(fb);
world.draw(fb);
fb.update();
fb.display(g);
}
}

private void follow() {
SimpleVector ray = Interact2D.reproject2D3DWS(world.getCamera(), fb, x, y);
if (ray != null) {
ray = ray.normalize();
plane.calcMinDistance(world.getCamera().getPosition(), ray, 1000);
}
}

private void init() {
TextureManager.getInstance().addTexture("texture", new Texture(512, 512, Color.GREEN));
TextureManager.getInstance().addTexture("marker", new Texture(32, 32, Color.RED));
TextureManager.getInstance().addTexture("yellow", new Texture(32, 32, Color.YELLOW));

plane = createPlane();
world = new World();
world.addObject(plane);

fb = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);

Camera cam = world.getCamera();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 100);
cam.moveCamera(Camera.CAMERA_MOVEUP, 160);
cam.lookAt(plane.getTransformedCenter());

world.getLights().setOverbrightLighting(Lights.OVERBRIGHT_LIGHTING_DISABLED);
}

private Object3D createPlane() {
int x, z, id = TextureManager.getInstance().getTextureID("texture");
float xSizeF = 129, zSizeF = 129, scale = 3, deelx = 1;
TextureInfo ti;
int size = (int) ((xSizeF - 1) * (zSizeF - 1) * 2);
Object3D plane = new Object3D(size);
Config.maxPolysVisible = size;
for (z = 0; z < zSizeF - 1; z++) {
for (x = 0; x < xSizeF - 1; x++) {
float xx = x;
ti = new TextureInfo(id, (xx / xSizeF / deelx), (z / zSizeF), ((xx + 1) / xSizeF / deelx), (z / zSizeF), (xx / xSizeF / deelx), ((z + 1) / zSizeF));
plane.addTriangle(new SimpleVector(x * scale, 1, z * scale), new SimpleVector((x + 1) * scale, 1, z * scale), new SimpleVector(x * scale, 1, (z + 1) * scale), ti);
ti = new TextureInfo(id, (xx / xSizeF / deelx), ((z + 1) / zSizeF), ((xx + 1) / xSizeF / deelx), (z / zSizeF), ((xx + 1) / xSizeF / deelx), ((z + 1) / zSizeF));
plane.addTriangle(new SimpleVector(x * scale, 1, (z + 1) * scale), new SimpleVector((x + 1) * scale, 1, z * scale), new SimpleVector((x + 1) * scale, 1, (z + 1)
* scale), ti);
}
}

plane.calcNormals();
plane.build();
plane.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
plane.addCollisionListener(this);
return plane;
}

public DuneReloaded() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setSize(800, 600);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
this.addMouseMotionListener(this);
g = getGraphics();
}

@Override
public void mouseMoved(MouseEvent m) {
x = m.getX();
y = m.getY();
yellow=false;
}

@Override
public void mouseDragged(MouseEvent m) {
x = m.getX();
y = m.getY();
yellow=true;
}

@Override
public void collision(CollisionEvent colEvent) {
int polyId = (colEvent.getPolygonIDs()[0]) & 0xfffffffe;
int tid=yellow?TextureManager.getInstance().getTextureID("yellow"):TextureManager.getInstance().getTextureID("marker");
plane.getPolygonManager().setPolygonTexture(polyId, tid);
plane.getPolygonManager().setPolygonTexture(polyId + 1, tid);
}

@Override
public boolean requiresPolygonIDs() {
return true;
}

}

Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on February 14, 2017, 03:07:39 pm
Sorry for taking this long. I was writing a long update when your version came through. So I implemented it your way. It worked, thanks very much.
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: AGP on April 11, 2017, 07:47:16 pm
The game is coming along nicely, but now I'm just abusing the CPU. From what I gather of what you wrote, I'm not going to have a problem with the mouse (the "if it should be applied to compiled objects, one would have to switch from individual textures..." comment was only about the painting of the polygon) in hardware. Right?
Title: Re: Painting a Mouse Cursor-Selected Polygon
Post by: EgonOlsen on April 11, 2017, 08:15:06 pm
Yes, that was only about the painting.