When I place objects too much too the left or right, or above or below, they are not shown. Maybe they fall outside the simple universe. How do I make bigger the simple universe?
|
Hi there,
Objects are unlikely to be outside a SimpleUniverse scope, or more accurately a Locale's scope ( a Locale is the node below Universe to which Shapes are attached), as the allowed placement is basically the resolution of a float, which in 32 bits is -3.4E+38 to +3.4E+38, or 38 zeros in a row. https://en.wikipedia.org/wiki/Single-precision_floating-point_format However resolution gets poor at higher numbers so any number with 6 to 9 significant digits is perfectly accurate, so placing things up to 1 million units (meters for example) will be fine. However there are many, many ways for objects to not be shown on the screen, in particular relating to the camera and field of view. Could you post the code you've got that isn't showing what'd you'd like? Thanks. |
Part of my code below, now Sphere 6 is not shown.
public class MyC extends Applet implements ActionListener, KeyListener { public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(); objRoot.setCapability(Group.ALLOW_CHILDREN_EXTEND); //Sphere 6 TransformGroup sphere6TransGroup = translate(sphere6, new Vector3f(0.6f,0.93f,0.0f)); objTransYour6Sph = new TransformGroup(); objTransYour6Sph.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objRoot.addChild(objTransYour6Sph); objTransYour6Sph.addChild(sphere6TransGroup); } public MyC() { setLayout(new BorderLayout()); GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); Canvas3D c = new Canvas3D(config); add("Center", c); c.addKeyListener(this); timer = new Timer(100,this); //timer.start(); Panel p =new Panel(); p.add(go); add("North",p); go.addActionListener(this); go.addKeyListener(this); // Create a simple scene and attach it to the virtual universe BranchGroup scene = createSceneGraph(); SimpleUniverse u = new SimpleUniverse(c); u.getViewingPlatform().setNominalViewingTransform(); u.addBranchGraph(scene); //u.getViewer().getView().setFieldOfView(Math.toRadians(90.0)); OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ROTATE); orbit.setSchedulingBounds(new BoundingSphere()); u.getViewingPlatform().setViewPlatformBehavior(orbit); } public static void main(String[] args) { System.out.println("Program Started"); System.setProperty("sun.awt.noerasebackground", "true"); MyC bb = new MyC(); bb.addKeyListener(bb); MainFrame mf = new MainFrame(bb, 1056, 1056); } } |
Administrator
|
Your sphere has to be in the view frustum. I advise you to read this:
https://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/java3d/forDevelopers/j3dguide/AppendixView.doc.html
Julien Gouesse | Personal blog | Website
|
I had to make up a few parts, but replacing your sphere with a simple color cube from teh utils I can see it on screen farily readily. The orbit behavior allows me to rotat it around and see it even better. For reference I've put 4 small cube on at the origin and 1 meter in each positive axis.
This test program looks good, so I suspect the geometry or appearance of your sphere6 which you don't include might not be valid or visible, can you include a bit more code? Thanks package _testcase; import java.applet.Applet; import java.awt.BorderLayout; import java.awt.GraphicsConfiguration; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.Group; import javax.media.j3d.Transform3D; import javax.media.j3d.TransformGroup; import javax.swing.Timer; import javax.vecmath.Quat4f; import javax.vecmath.Vector3f; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.behaviors.vp.OrbitBehavior; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.universe.SimpleUniverse; public class TestForSphere extends Applet implements ActionListener, KeyListener { TransformGroup objTransYour6Sph; Timer timer; ColorCube sphere6 = new ColorCube(0.1f); public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(); objRoot.setCapability(Group.ALLOW_CHILDREN_EXTEND); //Sphere 6 TransformGroup sphere6TransGroup = translate(sphere6, new Vector3f(0.6f, 0.93f, 0.0f)); objTransYour6Sph = new TransformGroup(); objTransYour6Sph.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objRoot.addChild(objTransYour6Sph); objTransYour6Sph.addChild(sphere6TransGroup); objRoot.addChild(translate(new ColorCube(0.02), new Vector3f(0.0f, 0.0f, 0.0f))); objRoot.addChild(translate(new ColorCube(0.02), new Vector3f(0.5f, 0.0f, 0.0f))); objRoot.addChild(translate(new ColorCube(0.02), new Vector3f(0.0f, 0.5f, 0.0f))); objRoot.addChild(translate(new ColorCube(0.02), new Vector3f(0.0f, 0.0f, 0.5f))); return objRoot; } private TransformGroup translate(ColorCube sphere62, Vector3f vector3f) { TransformGroup tg = new TransformGroup(); tg.setTransform(new Transform3D(new Quat4f(0, 0, 0, 1), vector3f, 1)); tg.addChild(sphere62); return tg; } public TestForSphere() { setLayout(new BorderLayout()); GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); Canvas3D c = new Canvas3D(config); add("Center", c); c.addKeyListener(this); timer = new Timer(100, this); //timer.start(); Panel p = new Panel(); // p.add(go); add("North", p); // go.addActionListener(this); // go.addKeyListener(this); // Create a simple scene and attach it to the virtual universe BranchGroup scene = createSceneGraph(); SimpleUniverse u = new SimpleUniverse(c); u.getViewingPlatform().setNominalViewingTransform(); u.addBranchGraph(scene); //u.getViewer().getView().setFieldOfView(Math.toRadians(90.0)); OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ROTATE); orbit.setSchedulingBounds(new BoundingSphere()); u.getViewingPlatform().setViewPlatformBehavior(orbit); } public static void main(String[] args) { System.out.println("Program Started"); System.setProperty("sun.awt.noerasebackground", "true"); TestForSphere bb = new TestForSphere(); bb.addKeyListener(bb); MainFrame mf = new MainFrame(bb, 1056, 1056); } @Override public void actionPerformed(ActionEvent e) { } @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } } |
I forgot to give you this code:
TransformGroup translate(Node node, Vector3f vector){ Transform3D transform3D = new Transform3D(); transform3D.setTranslation(vector); TransformGroup transformGroup = new TransformGroup(); transformGroup.setTransform(transform3D); transformGroup.addChild(node); return transformGroup; } It does not use Quaternions. I guess I have to make my frustum larger, but I cannot figure out how to do it. How to do that? |
In reply to this post by gouessej
How do I make the frustum larger? Please give me some lines of code to do this.
|
If you add this line:
u.getViewer().getView().setFieldOfView(Math.PI/2); below this line: u.getViewingPlatform().setNominalViewingTransform(); You will set the field of view to 90 degrees, 90 degrees is exactly PI/2 radians which is the units accepted by setFieldOfView If you look at the source here: https://github.com/hharrison/java3d-core/blob/master/src/javax/media/j3d/View.java#L851 you'll see the default field of view is set to 45 degrees (with the maths to make that a radian figure) This is a bit low for most applications and 60-70 is probably a better default value. You could also get your object on screen by moving the virtual "camera" backwards, this is done by setting the TransformGroup of the view platform like this: //move viewer platform back a bit ViewingPlatform viewingPlatform = u.getViewingPlatform(); // View model from top TransformGroup viewPlatformTransform = viewingPlatform.getViewPlatformTransform(); Transform3D transform = new Transform3D(); transform.setTranslation(new Vector3f(0, 0, 10)); viewPlatformTransform.setTransform(transform); Notice that positive Z is "out of the screen", and this is an absolute move, so we are not altering the position by an amount but setting it to that exact figure. The setNominalViewingTransform call that's in your code now is attempts to get the sphere on screen by moving the platform back. If you put this code ViewingPlatform viewingPlatform = u.getViewingPlatform(); // View model from top TransformGroup viewPlatformTransform = viewingPlatform.getViewPlatformTransform(); Transform3D transform = new Transform3D(); viewPlatformTransform.getTransform(transform); System.out.println("" + transform ); after the line: u.getViewingPlatform().setNominalViewingTransform(); on my system this shows the platform to be at 0,0,2.414 (for matrices just read the right hand column for the x,y,z figures) which on my system makes the test color cube visible. Can you confirm that when you use color cubes instead of your sphere Shape3D that you can see the objects? Can you see the 3 grid reference cubes I put in the demo code? Can you orbit with the mouse and see everything rotating? Thansk. |
The code you gave only place the camera back, but the sphere6 is still not visible.
When I compile your colorcubes, ColorCube6 is showing, but if I make it into a sphere, it is not showing. What do I have to do to get sphere6 visible in the frustum? |
Ok so we are making progress.
In your example code there wasn't any code that would create a sphere, only a TransformGroup to place the sphere. If you have that code you could send it through. If you don't have any code then the SphereGenerator from the utils project can be used to create a Sphere in a few lines of code. Which I could knock up an example of the usage if you need. |
I have this code to create a sphere:
Sphere sphere6 = new Sphere(0.05f); I am sure it is creating and placing the sphere, but it is outside the frustum. Because when another sphere is placed within the frustum, it is visible. |
A-ha!
I have finally seen the light. The problem is that the default Sphere constructor creates a Shape3D that has an Appearance that has lighting turned on (the obvious default case). So you must have some light in your scene in order to see the sphere. Adding just the sphere I get a black shape that is nearly impossible to see, however adding this code PointLight pl = new PointLight(); pl.setInfluencingBounds(new BoundingSphere(new Point3d(0,0,0),Double.POSITIVE_INFINITY)); objRoot.addChild(pl); somewhere is createSceneGraph() gives me this image |
Free forum by Nabble | Edit this page |