What does LibGDX's mesh.getVerticies output? - java

I am working on a 3D LibGDX project, and am trying to manipulate the vertices of a 3D model. I have the model loading, and I have this as my code:
Model plain = assets.get("plain.g3db", Model.class);
for(Mesh m : plain.meshes){
float[] t = m.getVertices(new float[m.getMaxVertices()]);
float[] newVerticies = new float[m.getMaxVertices()];
for(int i = 0; i < t.length-1; i++){
newVerticies[i] = t[i];
System.out.println("X: " + t[i] + " " + i);
newVerticies[i] = t[i];
System.out.println("Y: " + t[i++] + " " + i);
newVerticies[i] = random.nextInt(1-0) + 0;
System.out.println("Z: " + t[i++] + " " + i);
newVerticies[i] = t[i];
System.out.println("R: " + t[i++]);
newVerticies[i] = t[i];
System.out.println("G: " + t[i++]);
newVerticies[i] = t[i];
System.out.println("B: " + t[i++]);
newVerticies[i] = t[i];
System.out.println("A: " + t[i++]);
}
m.setVertices(newVerticies);
}
That does not work how I want it to, but I can at least see the model. If I comment out these lines:
newVerticies[i] = t[i];
System.out.println("R: " + t[i++]);
newVerticies[i] = t[i];
System.out.println("G: " + t[i++]);
newVerticies[i] = t[i];
System.out.println("B: " + t[i++]);
newVerticies[i] = t[i];
System.out.println("A: " + t[i++]);
I just get a black screen. Even if I move around, I see nothing. What I want to know, is what exactly float[] t = m.getVertices(new float[m.getMaxVertices()]); outputs. How does the output correspond to the model? How can I make the Y value random within a range?

Mesh data is organized into VertexAttributes. These always include position, but can also include color, texture coordinates, normals, etc. For example, a mesh with a texture might have the following:
A Position VertexAttribute of size 3 for X, Y, and Z (it's possible to have a 2D mesh where the position attribute has only 2)
A TextureCooridantes VertexAttribute of size 2 for U and V
A Normal VertexAttribute with size 3 for X, Y, and Z
So the float array you get with mesh.getVertices() would be this set of 8 floats for each vertex, one after the other.
If you loaded your Mesh from a model file rather than constructing it manually, you might not be sure of what VertexAttribute setup it has, so you need to inspect it to find out what the offset of the attribute you want is:
int positionOffset = mesh.getVertexAttributes().getOffset(Usage.Position);
int yOffset = positionOffset + 1; //skip X
int vertexSize = mesh.getVertexSize() / 4; //divide to convert bytes to floats
Now if you wanted to change Y, you would loop through the vertices something like this:
//this is how to get the properly sized mesh:
float[] vertices = new float[mesh.getNumVertices() * mesh.getVertexSize() / 4];
mesh.getVertices(vertices);
for (int i = yOffset; i < vertices.length; i += vertexSize){
vertices[i] += someValue;
}
mesh.setVertices(vertices);
The indices indicate groups of three vertices that make up the triangles of the mesh. If there are vertices on your mesh that are the same on multiple triangles, they might appear in the vertices list only once. This typically happens on soft-shaded vertices of a mesh, since the UV and normal will be the same for all the adjacent triangles touching that vertex.

Related

Trying to RayTrace in LWJGL, detecting an object

I am trying to write Ray Tracing in the LWJGL to go from the mouse position to the end of the display. I have written the code to find the mouse positions and to create the Vector3's for the start and end position of the rays, but how do I 'fire' the ray and detect an object?
I have tried using Camera's for the positioning, but my friend is the one who wrote the main Display system and its pretty gargled up and hard to read. Instead I opted for just firing the ray from the mouse position inside of the Display to the back Z of the display.
public class Picker {
static Vector3f startRay;
static Vector3f endRay;
public Picker() {
startRay = new Vector3f();
endRay = new Vector3f();
}
private static Vector2f getMouseCoords() {
float x = (2f* Mouse.getX()) / Display.getWidth() - 1;
float y = (2f * Mouse.getY()) / Display.getHeight() - 1f;
return new Vector2f(x, y);
}
public static String getRayStr() {
float x = (2f* Mouse.getX()) / Display.getWidth() - 1;
float y = (2f * Mouse.getY()) / Display.getHeight() - 1f;
String str = "Mouse X: " + x + " Mouse Y: " + y;
str += "\nStart X: " + startRay.x + " Start Y: " + startRay.y + " Start Z: " + startRay.z;
str += "\nEnd X: " + endRay.x + " End Y: " + endRay.y + " End Z: " + endRay.z;
return str;
}
public static void setStartRay() {
Vector2f mousePos = getMouseCoords();
Vector3f tempStartPos = new Vector3f();
tempStartPos.x = mousePos.x;
tempStartPos.y = mousePos.y;
tempStartPos.z = 0;
startRay = tempStartPos;
}
public static void setEndRay() {
Vector2f mousePos = getMouseCoords();
Vector3f tempEndPos = new Vector3f();
tempEndPos.x = mousePos.x;
tempEndPos.y = mousePos.y;
tempEndPos.z = -1;
endRay = tempEndPos;
}
}
I want to be able to detect an object directly inbetween startRay and endRay. The object I want to detect is a 3d model inside of the Display area.
Returning the startRay and endRay Vector3 positions has already confirmed to work, just needing to know about how to:
1) Cast the ray
2) Detect an object between the two points
Thank you very much for your assistance.

Classes in ArrayList updates each other properties

I am creating small firework simulation in LibGDX. I have ArrayList called particles and this is filling it:
for (int i = 0; i < 2; i++) {
Particle p = new Particle();
p.position = position;
p.velocity.x = MathUtils.random(-1f, 1f);
p.velocity.y = MathUtils.random(-1f, 1f);
particles.add(p);
}
And then in update loop:
for (int i = 0; i < particles.size(); i++) {
System.out.println(i + " " + particles.get(i).position.toString() + " + " + particles.get(i).velocity.toString() + " = ");
particles.get(i).update();
System.out.println(" " + particles.get(i).position.toString());
}
Particle update function:
velocity.add(acceleration);
position.add(velocity);
acceleration.set(0, 0);
Velocity is random and every particle have unique velocity but position is the same. Here is output:
0 (300.0,620.91364) + (-0.94489133,-0.45628428) =
(299.0551,620.45734)
1 (299.0551,620.45734) + (0.3956585,0.5208683) =
(299.45078,620.9782)
0 (299.45078,620.9782) + (-0.94489133,-0.45628428) =
(298.5059,620.5219)
1 (298.5059,620.5219) + (0.3956585,0.5208683) =
(298.90155,621.0428)
0 (298.90155,621.0428) + (-0.94489133,-0.45628428) =
(297.95667,620.5865)
1 (297.95667,620.5865) + (0.3956585,0.5208683) =
(298.35233,621.10736)
First is particle index, position, velocity and then output position.
Why is it using position from another particle? I am trying to figure it out but I can't.
In your for loop where you fill the ArrayList you have the line:
p.position = position;
I don't know where position comes from but here all Particles point to the same.
You must create a new Position for every Particle
p.position = new Position(x, y);
If position is the start point for your Particles you can write:
p.position = new Position(position.x, position.y);

vtkImageViewer2 - changing volume data slice spacing value

I want to change the slice thickness of my dicom volume data. I'm using
vtkImageViewer2.
For example, the original data spacing is 2 and there are 200 slices, when I
change the slice thickness value to 4 I have to see 100 slices.
Original: 1,2,3,4,5...
Modified: 1, 2, 3...
My code:
if ((modif & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
etat = 1;
int nb0 = imageViewer.GetSlice() + 1;
int nb1 = imageViewer.GetSlice() - 1;
int totSlice = imageViewer.GetSliceMax() + 1;
if (p1.y > p2.y) {
String Newligne=System.getProperty("line.separator");
cornerAnnotation.SetText(0,"Slice:" + (nb0 + 1) + "/" + totSlice+Newligne+"Zoom: "+(int)(100)+"%"+Newligne+ "C:" + windowhight + " / W:" +windowlevel+ Newligne+"Pixel:("+xs+":"+ys+")"+Newligne+reader.GetModality()+"("+reader.GetOutput().GetDimensions()[0]+"*"+reader.GetOutput().GetDimensions()[1]+")"+"-Axial"+Newligne);
imageViewer.SetSlice(nb0);
scrollBar.setValue(imageViewer.GetSlice());
} else {
String Newligne=System.getProperty("line.separator");
cornerAnnotation.SetText(0,"Slice:" + (nb1 + 1) + "/" + totSlice+Newligne+"Zoom: "+(int)(100)+"%"+Newligne+ "C:" + windowhight + " / W:" +windowlevel+ Newligne+"Pixel:("+xs+":"+ys+")"+Newligne+reader.GetModality()+"("+reader.GetOutput().GetDimensions()[0]+"*"+reader.GetOutput().GetDimensions()[1]+")"+"-Axial"+Newligne);
imageViewer.SetSlice(nb1);
scrollBar.setValue(imageViewer.GetSlice());
}
}
If you actually change the slice thickness in the DICOM attributes, you likely will have to change the image position (patient) and slice location DICOM attributes as well in order to keep the image volume consistent.
If you are just trying to move slices based on a certain distance (e.g. one click = 4 mm instead of 2 mm), then keep track of the position of the slice instead of the slice number. When the position changes, then compute the new slice for the new position and update to that slice. This will allow more flexibility as well.
If you really just want to step every other slice, then why not just use nb0 = getSlice() + 2 and nb1 = getSlice() -2?

Inverted y axis and nasted foor loop

I am writing a program that generates a fractal of a polynomial functions. To print out the result, I am using the given loop:
double xmin = xcenter - sizex/2;
double ymin = ycenter - sizey/2;
double width = sizex;
double height = sizey;
for(int i=0; i < M; i++){
for(int j=0; j < N; j++){
double a = xmin + i * width/M;
double b = ymin + j * height/N;
Complex z = new Complex(a, b);
// Call of the method that return me a color c
pic.set(i, j, c);
}
}
The pic object is a object of a class Picture and the method set sets the color of the pixel i, j to be c (everything is correct with this class).
I want the top right to have coordinates (xcenter + sizex/2 , ycenter + sizey/2)
Calling this function to a complex functions with roots in 0,0 and 3,3, this is what I get when xcenter=ycenter=0 and sizex = sizey = 6
you can check that the center point it darker (it is 0,0) and the other darker point should be at top right ( it should be 3,3) but it is on (3, -3). Calling this method to the root (-3, -3), I can check that the y axes is also inverted.
This is the last points calculated by my function and the root to where it converges is bellow it (as you can see, the method is correct)
2.991428571428571 + 2.9485714285714284i:
3.0 + 3.0i
2.991428571428571 + 2.9571428571428573i: 5
3.0 + 3.0i
2.991428571428571 + 2.9657142857142853i: 4
3.0 + 3.0i
2.991428571428571 + 2.974285714285714i: 4
3.0 + 3.0i
2.991428571428571 + 2.982857142857143i: 4
3.0 + 3.0i
2.991428571428571 + 2.991428571428571i: 4
What is wrong with this loop?
Computer screens and images have the top right point as (0,0) location, this is from the times of text screens, where first line first character is at the top-left position.
Thus use
double a = xmin + i * width/M;
double b = ymax - j * height/N;
for screen / picture location (i,j)

How to get the size of the intersecting part in a circle in Java

I need the size of the black part of this image:
I've done some research about how to find it in normal math, and I was pointed to this website: Website
The final answer on getting it was
(from MathWorld - A Wolfram Web Resource: wolfram.com)
where r is the radius of the first circle, R the radius of the second circle, and d the distance between the two centers.
The code I tried to use to get the size of this was the following:
float r = getRadius1();
float R = e.getRadius1();
float deltaX = Math.abs((getX() + getRadius()) - (e.getX() + e.getRadius()));
float deltaY = Math.abs((getY() + getRadius()) - (e.getY() + e.getRadius()));
float d = (float) Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
float part, part2, part3;
//Chopping it in parts, because it's easier.
part = (float) (Math.pow(r,2) * Math.acos(
Math.toRadians((Math.pow(d, 2) + Math.pow(r, 2) - Math.pow(R, 2))/(2*d*r))));
part2 = (float) (Math.pow(R,2) * Math.acos(
Math.toRadians((Math.pow(d, 2) + Math.pow(R, 2) - Math.pow(r, 2))/(2*d*R))));
part3 = (float) (0.5 * Math.sqrt((-d + r + R) * (d+r-R) * (d-r+R) * (d+r+R)));
float res = part + part2 - part3;
Main.log(res + " " + part + " " + part2 + " " + part3+ " "
+ r + " " + R + " " + d);
//logs the data and System.out's it
I did some testing, and the output was this:
1345.9663 621.6233 971.1231 246.78008 20.0 25.0 43.528286
So that indicates that the size of the overlapping part was bigger than the circle itself (which is r^2 * PI).
What did I do wrong?
Just a guess (as stated in my comment): try removing the Math.toRadians(...) conversion.
Since there are no degrees involved in the formula but rather radii, I assume the parameter to cos-1(...) is already a value in radians.
If I remove the conversion and run your code, I get the following overlap area size: 11.163887023925781 which seems plausible since the length of the overlap segment on the line between the two centers is 20 + 25 - 43.5 = 1.5 (approximated)
Edit:
If I set the distance to 5 (the smaller circle is completely contained in the bigger one but touches its edge) I get the overlap area size 1256.63 which is exactly the area of the smaller circle (202 * Π). The calculation doesn't seem to work if the distance is smaller than the difference of the radii (i.e. in your case smaller than 5), but that might just be a problem of numerical representation (the normal datatypes might not be able to represent some of the intermediate results).

Categories