TriangleMesh - Backside faces are visible - java

Good Day! I have the following issue. The graphic model is not displayed correctly: some backside faces of the model that should be hidden by the frontside remain visible. Here are some exmples to clarify: (isometry)
(issue)
This issue comes out especially notable when applying light and material. So the the question is how this can be solved for JavaFX?
UPD:
public class VertexTest extends Application {
PerspectiveCamera camera;
Cam cam = new Cam();
double mouseOldX, mouseOldY, mousePosX, mousePosY, mouseDeltaX, mouseDeltaY;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
TriangleMesh mesh = new Shape3DRectangle(100, 100, 100);
MeshView view = new MeshView(mesh);
view.setDrawMode(DrawMode.LINE);
view.setMaterial(new PhongMaterial(Color.RED));
cam.getChildren().add(view);
Scene scene = new Scene(cam, 1000, 1000, true);
addEvents(view, scene);
camera = new PerspectiveCamera();
camera.setTranslateX(-500);
camera.setTranslateY(-500);
camera.setTranslateZ(1000);
scene.setCamera(camera);
primaryStage.setScene(scene);
primaryStage.show();
}
private void addEvents(MeshView view, Scene s) {
s.setOnMouseDragged(new EventHandler<MouseEvent>() {
public void handle(MouseEvent me) {
mouseOldX = mousePosX;
mouseOldY = mousePosY;
mousePosX = me.getX();
mousePosY = me.getY();
mouseDeltaX = mousePosX - mouseOldX;
mouseDeltaY = mousePosY - mouseOldY;
cam.ry.setAngle(cam.ry.getAngle() - mouseDeltaX);
cam.rx.setAngle(cam.rx.getAngle() + mouseDeltaY);
}
});
}
class Cam extends Group {
Translate t = new Translate();
Translate p = new Translate();
Translate ip = new Translate();
Rotate rx = new Rotate();
{
rx.setAxis(Rotate.X_AXIS);
}
Rotate ry = new Rotate();
{
ry.setAxis(Rotate.Y_AXIS);
}
Rotate rz = new Rotate();
{
rz.setAxis(Rotate.Z_AXIS);
}
Scale s = new Scale();
public Cam() {
super();
getTransforms().addAll(t, p, rx, rz, ry, s, ip);
}
}
public class Shape3DRectangle extends TriangleMesh {
public Shape3DRectangle(float Width, float Height, float deep) {
this.getPoints().setAll(-Width / 2, Height / 2, deep / 2, // idx p0
Width / 2, Height / 2, deep / 2, // idx p1
-Width / 2, -Height / 2, deep / 2, // idx p2
Width / 2, -Height / 2, deep / 2, // idx p3
-Width / 2, Height / 2, -deep / 2, // idx p4
Width / 2, Height / 2, -deep / 2, // idx p5
-Width / 2, -Height / 2, -deep / 2, // idx p6
Width, -Height / 2, -deep / 2 // idx p7
);
this.getTexCoords().addAll(0.0f, 0.0f);
this.getFaces().addAll(5, 0, 4, 0, 0, 0 // P5,T1 ,P4,T0 ,P0,T3
, 5, 0, 0, 0, 1, 0 // P5,T1 ,P0,T3 ,P1,T4
, 0, 0, 4, 0, 6, 0 // P0,T3 ,P4,T2 ,P6,T7
, 0, 0, 6, 0, 2, 0 // P0,T3 ,P6,T7 ,P2,T8
, 1, 0, 0, 0, 2, 0 // P1,T4 ,P0,T3 ,P2,T8
, 1, 0, 2, 0, 3, 0 // P1,T4 ,P2,T8 ,P3,T9
, 5, 0, 1, 0, 3, 0 // P5,T5 ,P1,T4 ,P3,T9
, 5, 0, 3, 0, 7, 0 // P5,T5 ,P3,T9 ,P7,T10
, 4, 0, 5, 0, 7, 0 // P4,T6 ,P5,T5 ,P7,T10
, 4, 0, 7, 0, 6, 0 // P4,T6 ,P7,T10 ,P6,T11
, 3, 0, 2, 0, 6, 0 // P3,T9 ,P2,T8 ,P6,T12
, 3, 0, 6, 0, 7, 0 // P3,T9 ,P6,T12 ,P7,T13
);
}
}
}

I've been playing around with your sample, and I think I've found out the reason of your issues.
First, I checked the winding of the faces. All of them are counter-clockwise, so all their normals go outwards, as they should be.
Then I modified other vertices instead of the last one. In some cases there were no issues, in others, the issue was still there.
Basically, the issue happens when there are "concave" surfaces, meaning that two faces have normals that will cross. And it doesn't happen when all the surfaces are "convex", meaning that their normals point outwards and won't cross.
This is a clear image of both type of meshes taken from here:
Back to your sample, you are defining a concave mesh:
But if instead of modifying vertex #7, we make the #5 larger, we have a convex mesh, with no rendering issues:
Obviously, while this fix the rendering problem, it changes your initial shape.
If you want to keep your initial geometry, the other possible solution is changing the faces, so you don't have any concave areas.
Let's have a look at the faces 5-1-3 and 5-3-7, and let's say we want to move now the vertex #1.
If we keep your triangles, face 5-1-3 and 5-3-7 will define a concave surface to be render (their normals will cross), while if we change those triangles to 5-1-7 and 1-3-7, then the surface will be convex (their normals won't cross):
Back to your initial shape, this change in those two faces will solve the rendering issues.
While the vertices are the same, the geometry is a little bit difference. So it requires some refinement (more elements). Adding those elements should be done keeping in mind this convex concept. The problem is not trivial, though, as you can see here.

Nice analysis by Jose but it looks to me as if the OP has just forgotten to divide the Width by 2 in this line of his code.
Width, -Height / 2, -deep / 2 // idx p7
should be
Width / 2, -Height / 2, -deep / 2 // idx p7
The class is called Shape3DRectangle but with this mistake
the geometry is not rectangular anymore.

You can set the cullFaceProperty for every Shape3D. I guess that is what you need but I am not sure whether I understood your question precisely.
Shape3D#cullFaceProperty

Related

How to animate a spinning top?

It's Hanukkah and I'm trying to animate a spinning top (dreidel):
I can get it to spin on its own axis. Here is my code:
import static javafx.scene.paint.Color.*;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class DreidelAnim extends Application {
private double bodyBase = 30;
private double bodyHeight = bodyBase * 3 / 2;
private double baseRadius = bodyBase / 2;
#Override
public void start(Stage stage) throws Exception {
DoubleProperty spinAngle = new SimpleDoubleProperty();
Rotate spin = new Rotate(0, Rotate.Z_AXIS);
spin.angleProperty().bind(spinAngle);
Timeline spinAnim = new Timeline(new KeyFrame(Duration.seconds(2), new KeyValue(spinAngle, 360)));
spinAnim.setCycleCount(Timeline.INDEFINITE);
spinAnim.play();
Group dreidel = createDreidel();
Translate zTrans = new Translate(0, 0, -(bodyHeight/2 + baseRadius));
dreidel.getTransforms().addAll(spin, zTrans);
Scene scene = new Scene(dreidel, 200, 200, true, SceneAntialiasing.BALANCED);
scene.setFill(SKYBLUE);
scene.setCamera(createCamera());
stage.setScene(scene);
stage.show();
}
private Group createDreidel() {
double handleHeight = bodyBase * 3/4;
Cylinder handle = new Cylinder(bodyBase / 6, handleHeight);
handle.setTranslateZ(-(bodyHeight + handleHeight) / 2);
handle.setRotationAxis(Rotate.X_AXIS);
handle.setRotate(90);
handle.setMaterial(new PhongMaterial(RED));
Box body = new Box(bodyBase, bodyBase, bodyHeight);
body.setMaterial(new PhongMaterial(BLUE));
Sphere base = new Sphere(baseRadius);
base.setTranslateZ(bodyHeight / 2);
base.setMaterial(new PhongMaterial(GREEN));
return new Group(handle, body, base);
}
private Camera createCamera() {
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setFarClip(1000);
int xy = 150;
Translate trans = new Translate(-xy, xy, -120);
Rotate rotXY = new Rotate(70, new Point3D(1, 1, 0));
Rotate rotZ = new Rotate(45, new Point3D(0, 0, 1));
camera.getTransforms().addAll(trans, rotXY, rotZ);
return camera;
}
public static void main(String[] args) {
launch();
}
}
I created a simple model, spinning it around its axis, and translated it so that its tip is on (0, 0, 0). Here is the result:
How can I achieve something similar to the picture on the top where it's also spinning around a rotating axis?
The rotation of the axis around which the object spins is called a Precession. The spinning top motion requires 2 rotations:
Rotation of the object around its internal axis (parallel to the red handle).
Rotation one of the internal axis around a static axis (z in this case).
On the face of it, you'd need 2 Animation instances. However, both rotations are actually the same. The pivot point for both is (0, 0, 0) (after the zTrans) and they are both around the z axis, only one of them is tilted at an angle.
Here is the modified code:
import static javafx.scene.paint.Color.*;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FinalDreidelSpin extends Application {
private double bodyBase = 30;
private double bodyHeight = bodyBase * 3 / 2;
private double baseRadius = bodyBase / 2;
#Override
public void start(Stage stage) throws Exception {
double tiltAngle = 40;
DoubleProperty spinAngle = new SimpleDoubleProperty();
Rotate spin = new Rotate(0, Rotate.Z_AXIS);
Rotate tilt = new Rotate(tiltAngle, Rotate.X_AXIS);
spin.angleProperty().bind(spinAngle);
Timeline spinAnim = new Timeline();
spinAnim.getKeyFrames().add(new KeyFrame(Duration.seconds(2), new KeyValue(spinAngle, 360)));
spinAnim.setCycleCount(Timeline.INDEFINITE);
spinAnim.play();
Group dreidel = createDreidel();
Translate zTrans = new Translate(0, 0, -(bodyHeight/2 + baseRadius));
dreidel.getTransforms().addAll(spin, tilt, spin, zTrans);
Scene scene = new Scene(new Group(dreidel, createAxes()), 200, 200, true, SceneAntialiasing.BALANCED);
scene.setFill(SKYBLUE);
scene.setCamera(createCamera());
stage.setScene(scene);
stage.show();
}
private Group createDreidel() {
double handleHeight = bodyBase * 3/4;
Cylinder handle = new Cylinder(bodyBase / 6, handleHeight);
handle.setTranslateZ(-(bodyHeight + handleHeight) / 2);
handle.setRotationAxis(Rotate.X_AXIS);
handle.setRotate(90);
handle.setMaterial(new PhongMaterial(RED));
Box body = new Box(bodyBase, bodyBase, bodyHeight);
body.setMaterial(new PhongMaterial(BLUE));
Sphere base = new Sphere(baseRadius);
base.setTranslateZ(bodyHeight / 2);
base.setMaterial(new PhongMaterial(GREEN));
return new Group(handle, body, base);
}
private Camera createCamera() {
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setFarClip(1000);
int xy = 150;
Translate trans = new Translate(-xy, xy, -100);
Rotate rotXY = new Rotate(70, new Point3D(1, 1, 0));
Rotate rotZ = new Rotate(45, new Point3D(0, 0, 1));
camera.getTransforms().addAll(trans, rotXY, rotZ);
return camera;
}
private Group createAxes() {
int axisWidth = 1;
int axisLength = 400;
Cylinder xAxis = new Cylinder(axisWidth, axisLength);
xAxis.setMaterial(new PhongMaterial(CYAN));
Cylinder yAxis = new Cylinder(axisWidth, axisLength);
yAxis.setRotationAxis(Rotate.Z_AXIS);
yAxis.setRotate(90);
yAxis.setMaterial(new PhongMaterial(MAGENTA));
Cylinder zAxis = new Cylinder(axisWidth, axisLength);
zAxis.setRotationAxis(Rotate.X_AXIS);
zAxis.setRotate(90);
zAxis.setMaterial(new PhongMaterial(YELLOW));
return new Group(xAxis, yAxis, zAxis);
}
public static void main(String[] args) {
launch();
}
}
Where I added axes representations for viewing convenience. Note that the getTransforms() list does not require its objects to be unique (unlike getChildren()), which allows us to reuse the same animation. The order of the animations is also important as noted below.
The tilting is a simple rotation around the x or y axis.
If we tilt and then spin, getTransforms().addAll(tilt, spin, zTrans), we would get the internal rotation (listed 1 above), only tilted:
If we spin and then tilt, getTransforms().addAll(spin, tilt, zTrans), we would get the precession (listed 2 above):
Combining the 2 as in the complete code would give the desired result:
This is another possible answer, very much based in #user1803551 approach, but using a 3D mesh that can use a texture image, and a different precession period.
This is how it looks like:
In order to apply a texture, I'll use the net concept for the body of the dreidel, and this image:
that is based on this image.
Finally I'll add a regular cylinder for the handle.
I won't go into details on how to create the TriangleMesh for the body, but we define 9 vertices (3D coordinates), 16 texture coordinates (2D), and 14 triangle faces including the vertex indices and the texture indices. The cube is defined by its side width, and the pyramid by its height. The net dimensions are L = 4 * width, H = 2 * width + height.
For instance, face 0 has vertices 0 - 2 - 1, and texture indices 8 - 3 - 7, where vertex 0 has coordinates {width / 2, width / 2, width / 2}, and texture index 8 has coordinates {width, 2 * width}, which are normalized between [0, 1]: {width / L, 2 * width / H}.
In this case, and for the sake of the sample, the values are hardcoded:
float width = 375f;
float height = 351f;
This is the 3D shape class:
class DreidelMesh extends Group {
float width = 375f;
float height = 351f;
public DreidelMesh(){
MeshView bodyMesh = new MeshView(createBodyMesh());
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image(getClass().getResourceAsStream("3dreidel3d.png")));
bodyMesh.setMaterial(material);
Cylinder handle = new Cylinder(45, 260);
handle.setTranslateY(-(handle.getHeight() + width) / 2);
material = new PhongMaterial(Color.web("#daaf6d"));
handle.setMaterial(material);
getTransforms().add(new Rotate(90, Rotate.X_AXIS));
getChildren().addAll(bodyMesh, handle);
}
private TriangleMesh createBodyMesh() {
TriangleMesh m = new TriangleMesh();
float L = 4f * width;
float H = 2f * width + height;
float w2 = width / 2f;
// POINTS
m.getPoints().addAll(
w2, w2, w2,
w2, w2, -w2,
w2, -w2, w2,
w2, -w2, -w2,
-w2, w2, w2,
-w2, w2, -w2,
-w2, -w2, w2,
-w2, -w2, -w2,
0f, w2 + height, 0f
);
// TEXTURES
m.getTexCoords().addAll(
width / L, 0f,
2f * width/ L, 0f,
0f, width / H,
width / L, width / H,
2f * width/ L, width / H,
3f * width/ L, width / H,
1f, width / H,
0f, 2f * width / H,
width / L, 2f * width / H,
2f * width/ L, 2f * width / H,
3f * width/ L, 2f * width / H,
1f, 2f * width / H,
width / 2f / L, 1f,
3f * width / 2f / L, 1f,
5f * width / 2f / L, 1f,
7f * width / 2f / L, 1f
);
// FACES
m.getFaces().addAll(
0, 8, 2, 3, 1, 7,
2, 3, 3, 2, 1, 7,
4, 9, 5, 10, 6, 4,
6, 4, 5, 10, 7, 5,
0, 8, 1, 7, 8, 12,
4, 9, 0, 8, 8, 13,
5, 10, 4, 9, 8, 14,
1, 11, 5, 10, 8, 15,
2, 3, 6, 4, 3, 0,
3, 0, 6, 4, 7, 1,
0, 8, 4, 9, 2, 3,
2, 3, 4, 9, 6, 4,
1, 11, 3, 6, 5, 10,
5, 10, 3, 6, 7, 5
);
return m;
}
}
Finally, this shape is added to the scene, and I'll provide two animations (instead of one), one for the spin, and one slower for the precession:
#Override
public void start(Stage stage) {
double tiltAngle = 15;
DoubleProperty spinAngle = new SimpleDoubleProperty();
DoubleProperty precessionAngle = new SimpleDoubleProperty();
Rotate spin = new Rotate(0, Rotate.Z_AXIS);
Rotate precession = new Rotate(0, Rotate.Z_AXIS);
Rotate tilt = new Rotate(tiltAngle, Rotate.X_AXIS);
spin.angleProperty().bind(spinAngle);
precession.angleProperty().bind(precessionAngle);
Timeline spinAnim = new Timeline();
spinAnim.getKeyFrames().add(new KeyFrame(Duration.seconds(1.5), new KeyValue(spinAngle, 360)));
spinAnim.setCycleCount(Timeline.INDEFINITE);
spinAnim.play();
Timeline precessionAnim = new Timeline();
precessionAnim.getKeyFrames().add(new KeyFrame(Duration.seconds(4), new KeyValue(precessionAngle, 360)));
precessionAnim.setCycleCount(Timeline.INDEFINITE);
precessionAnim.play();
Group dreidel = new Group(new DreidelMesh());
Translate zTrans = new Translate(0, 0, - dreidel.getBoundsInLocal().getMaxZ());
dreidel.getTransforms().addAll(precession, tilt, spin, zTrans);
Scene scene = new Scene(new Group(dreidel), 300, 300, true, SceneAntialiasing.BALANCED);
scene.setFill(SKYBLUE);
scene.setCamera(createCamera());
stage.setScene(scene);
stage.setTitle("JavaFX 3D - Dreidel");
stage.show();
}
Running the application will show the animation displayed above.

Implementing Kalman filter in OpenCV Java

I'm trying to implement a Kalman filter in my OpenCV program in Java. I'm new to both OpenCV and Kalman Filter. I've found some examples in C++ (not many in Java) and this is what I have so far:
Initialization:
//create kalman filter
KalmanFilter kalman = new KalmanFilter(4,2,0,CvType.CV_32F);
//set transition matrix
float[] tM = { 1, 0, 1, 0,
0, 1, 0, 1,
0, 0, 1, 0,
0, 0, 0, 1 } ;
Mat transitionMatrix=new Mat(4,4,CvType.CV_32F,new Scalar(0));
transitionMatrix.put(0,0,tM);
kalman.set_transitionMatrix(transitionMatrix);
//set init measurement
Mat measurementMatrix = new Mat (2,1, CvType.CV_32F);
measurementMatrix.setTo(new Scalar(0));
kalman.set_measurementMatrix(measurementMatrix);
//Set state matrix
Mat statePre = new Mat(4,1, CvType.CV_32F);
statePre.put(1, 1, 300);
statePre.put(2, 1, 200);
statePre.put(3, 1, 0);
statePre.put(4, 1, 0);
kalman.set_statePre(statePre);
//Process noise Covariance matrix
Mat processNoiseCov=Mat.eye(4,4,CvType.CV_32F);
processNoiseCov=processNoiseCov.mul(processNoiseCov,1e-1);
kalman.set_processNoiseCov(processNoiseCov);
//Measurement noise Covariance matrix: reliability on our first measurement
Mat measurementNoiseCov=Mat.eye(4,4,CvType.CV_32F);
measurementNoiseCov=measurementNoiseCov.mul(measurementNoiseCov,1e-1);
kalman.set_measurementNoiseCov(measurementNoiseCov);
Mat id2=Mat.eye(4,4,CvType.CV_32F);
id2=id2.mul(id2,0.1);
kalman.set_errorCovPost(id2);
For each video frame:
prediction= kalman.predict();
predictPt.x = prediction.get(1,1)[0];
predictPt.y = prediction.get(2,1)[0];
...new measurement..
measurementMatrix.put(1, 1, center.x);
measurementMatrix.put(2, 1, center.y);
measPt.x=center.x;
measPt.y=center.y;
Mat estimated = kalman.correct(measurementMatrix);
statePt.x=estimated.get(1, 1)[1];
statePt.y= estimated.get(2, 1)[1];
The problem is that I get a null prediction, and I don't see the reason for getting it. Does somebody know what's wrong with my code? I really appreciate any help!
Thank you!
You get a null prediction because you are neither inserting nor accessing the correct elements.
First:
statePre.put(0, 1, 300); //statePre.put(1, 1, 300);
statePre.put(1, 1, 200); //statePre.put(2, 1, 200);
statePre.put(2, 1, 0); //statePre.put(3, 1, 0);
statePre.put(3, 1, 0); // statePre.put(4, 1, 0);
Predict:
prediction= kalman.predict();
predictPt.x = prediction.get(0,0)[0]; //predictPt.x = prediction.get(1,1)[0];
predictPt.y = prediction.get(1,0)[0]; //predictPt.y = prediction.get(2,1)[0];
And finally:
measurementMatrix.put(0, 0, center.x); // measurementMatrix.put(1, 1, center.x);
measurementMatrix.put(1, 0, center.y); //measurementMatrix.put(2, 1, center.y);
measPt.x=center.x;
measPt.y=center.y;
Mat estimated = kalman.correct(measurementMatrix);
statePt.x=estimated.get(0,0)[0];
statePt.y= estimated.get(1,0)[0];
Also, your measurementMatrix should be like this
Mat measurementMatrix = Mat.eye(2,4, CvType.CV_32F);

Vertex coloring not working with dynamically created meshes when using lighting

I have created a Mesh object containing position, normal, and color information using the following code:
final Vector3[] vertexVectors = this.getVertexVectors();
final short[] indices = this.getIndices();
final Vector3[] vertexNormals = this.getNormals(vertexVectors, indices);
final float[] vertices = new float[vertexVectors.length * 7];
for (int index = 0; index < vertexVectors.length; index++)
{
vertices[(index * 7) + 0] = vertexVectors[index].x;
vertices[(index * 7) + 1] = vertexVectors[index].y;
vertices[(index * 7) + 2] = vertexVectors[index].z;
vertices[(index * 7) + 3] = vertexNormals[index].x;
vertices[(index * 7) + 4] = vertexNormals[index].y;
vertices[(index * 7) + 5] = vertexNormals[index].z;
vertices[(index * 7) + 6] = Color.toFloatBits(0, 255, 0, 255);
}
final Mesh mesh = new Mesh(true, vertices.length / 3, indices.length, new VertexAttribute(Usage.Position, 3, "a_position"), new VertexAttribute(Usage.Normal, 3, "a_normal"), new VertexAttribute(Usage.ColorPacked, 4, "a_color"));
mesh.setVertices(vertices);
mesh.setIndices(indices);
return mesh;
I then create a Model object and a ModelInstance object from the mesh with this code:
private Model model;
private ModelInstance instance;
final ModelBuilder modelBuilder = new ModelBuilder();
modelBuilder.begin();
modelBuilder.part("0", this.getCustomMesh(), GL10.GL_TRIANGLES, new Material());
this.model = modelBuilder.end();
this.instance = new ModelInstance(this.model);
I render the ModelInstance using this code:
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
this.modelBatch.begin(this.cam);
this.modelBatch.render(this.instance, this.lights);
this.modelBatch.end();
My problem is that the model has no color. The model should be green per the vertex colors but as long as I use lighting, the model appears white. If i remove the lighting, the model appears green as expected (but without the pretty shading). I have tried adding Gdx.gl.glEnable(GL10.GL_COLOR_MATERIAL); to my constructor per this question, but this only makes the model appear brighter but still white. What other settings are needed for my model to render the vertex colors with lighting?
It seems adding ColorAttribute.createDiffuse to the model's material fixes the issue. This means changing this line:
modelBuilder.part("0", this.getCustomMesh(), GL10.GL_TRIANGLES, new Material());
with this:
modelBuilder.part("0", this.getCustomMesh(), GL10.GL_TRIANGLES, new Material(ColorAttribute.createDiffuse(0, 0, 0, 0)));
I do not fully understand why and as an added curiosity, the values passed to the createDiffuse method seem to have no noticeable affect on the model.

Detecting Hough circles android

I am trying to detect circles using android. I succeeded to implement the detect lines algorithm but nothing gets displayed when trying the draw hough circles algoritm.
Here is my code:
Mat thresholdImage = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
mYuv.put(0, 0, data);
Imgproc.cvtColor(mYuv, destination, Imgproc.COLOR_YUV420sp2RGB, 4);
Imgproc.cvtColor(destination, thresholdImage, Imgproc.COLOR_RGB2GRAY, 4);
Imgproc.GaussianBlur(thresholdImage, thresholdImage, new Size(9, 9), 2, 2 );
Mat circles = new Mat();
Imgproc.HoughCircles(thresholdImage, circles, Imgproc.CV_HOUGH_GRADIENT, 1d, (double)thresholdImage.height()/70, 200d, 100d);
Log.w("circles", circles.cols()+"");
for (int x = 0; x < circles.cols(); x++)
{
double vCircle[]=circles.get(0,x);
Point center=new Point(Math.round(vCircle[0]), Math.round(vCircle[1]));
int radius = (int)Math.round(vCircle[2]);
// draw the circle center
Core.circle(destination, center, 3,new Scalar(0,255,0), -1, 8, 0 );
// draw the circle outline
Core.circle( destination, center, radius, new Scalar(0,0,255), 3, 8, 0 );
}
You may have got this sorted by now, but a few things. I'd check your circles mat actually has some results; sometimes vCircle seems to come back null; try one of the other versions of HoughCircles:
iCannyUpperThreshold = 100;
iMinRadius = 20;
iMaxRadius = 400;
iAccumulator = 300;
Imgproc.HoughCircles(thresholdImage, circles, Imgproc.CV_HOUGH_GRADIENT,
2.0, thresholdImage.rows() / 8, iCannyUpperThreshold, iAccumulator,
iMinRadius, iMaxRadius);
if (circles.cols() > 0)
for (int x = 0; x < circles.cols(); x++)
{
double vCircle[] = circles.get(0,x);
if (vCircle == null)
break;
Point pt = new Point(Math.round(vCircle[0]), Math.round(vCircle[1]));
int radius = (int)Math.round(vCircle[2]);
// draw the found circle
Core.circle(destination, pt, radius, new Scalar(0,255,0), iLineThickness);
Core.circle(destination, pt, 3, new Scalar(0,0,255), iLineThickness);
}
(I swapped your code into mine, renamed some stuff and swapped it back, I think I've got it back so it works...)
B.

BlackBerry drawTexturedPath Rotate Move Anchor to Center of Image

I know how to rotate a BlackBerry Bitmap image an arbitrary angle with drawTexturePath. But, The Rotation Anchor is at the top-top left of the image. How do I move the Anchor to the center of the image?
This code uses Graphics.drawTexturedPath to rotate around top-left corner:
int[] x = new int[] {0, width, width, 0};
int[] y = new int[] {0, 0, height, height};
int angle32 = Fixed32.toFP(angleDegrees);
int dux = Fixed32.cosd(angle32);
int dvx = -Fixed32.sind(angle32);
int duy = Fixed32.sind(angle32);
int dvy = Fixed32.cosd(angle32);
graphics.drawTexturedPath(x, y, null, null, 0, 0, dvx, dux, dvy, duy, bitmapImage);
How do I modify this code to rotate around the center of the image with drawTexturedPath (http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/ui/Graphics.html#drawTexturedPath)?
FYI, a similar post describes other 2D afine transformations with drawTexturedPath including skew and some 3D effects here: "BlackBerry - image 3D transform" (BlackBerry - image 3D transform).
-Thanks in advance, David Pixelmonks.com
To rotate around the center, you need to displace your bitmap before the rotation:
instead of
int[] x = new int[] {0, width, width, 0};
int[] y = new int[] {0, 0, height, height};
you should use
int[] x = new int[] {-width / 2, width / 2, width / 2, -width / 2};
int[] y = new int[] {-height / 2, -height / 2, height / 2, height / 2};
then apply the transformation, and add again width / 2 to all your x-values, and height / 2 to your y-values.

Categories