[Solved]Arrow.setLineWidth(10) not to scale when camera moves out ? jme3 r7237

Solved: Lines have no width, therefore they tend to show the same 1 pixel size from whatever distance (anyway this isn't jme3 related)<br /> =========<br /> In other words, the thickness of the arrows grows as the camera moves away from the arrow to a point where the thickness is bigger than the arrow head<br /> I hope it's not my drivers again O_o<br /> zoomed in:<br /> <img src='http://i.imgur.com/yiI1I.png'>http://i.imgur.com/yiI1I.png</img><br /> =====<br /> zooming out:<br /> <img src='http://i.imgur.com/V1OjE.png'>http://i.imgur.com/V1OjE.png</img><br /> ======<br /> zooming out even more:<br /> <img src='http://i.imgur.com/F2oiS.png'>http://i.imgur.com/F2oiS.png</img><br /> and the code that does this:<br /> pre type=“java”`
package org.jme3.tests;





import com.jme3.app.SimpleApplication;


import com.jme3.material.Material;


import com.jme3.math.ColorRGBA;


import com.jme3.math.FastMath;


import com.jme3.math.Spline;


import com.jme3.math.Vector3f;


import com.jme3.scene.Geometry;


import com.jme3.scene.Mesh;


import com.jme3.scene.Node;


import com.jme3.scene.Spatial.CullHint;


import com.jme3.scene.debug.Arrow;


import com.jme3.scene.shape.Box;


import com.jme3.scene.shape.Curve;


import com.jme3.system.AppSettings;





/**

  • Sample 2 - How to use nodes as handles to manipulate objects in the scene

  • graph. You can rotate, translate, and scale objects by manipulating their

  • parent nodes. The Root Node is special: Only what is attached to the Root

  • Node appears in the scene.


    /


    public class HelloNode5 extends SimpleApplication {





    private static final float lineWidth = 10f;





    private Vector3f cornerPos;





    private Geometry geoCurve;





    private Geometry geoBox;





    private final Spline spline = new Spline();


    private Node coord;


    Box box;





    public static void main(String[] args) {


    HelloNode5 app = new HelloNode5();


    AppSettings aSet = new AppSettings(true);


    aSet.setVSync(true);


    app.setSettings(aSet);


    app.setShowSettings(false);


    app.start();


    }





    /


    • (non-Javadoc)



    • @see com.jme3.app.SimpleApplication#simpleUpdate(float)


      */


      @Override


      public void simpleUpdate(float tpf) {


      // calculating by how much to rotate now(relative to previous position),


      // not the exact rotation position(as it was in


      // prev. revision)


      float yaw = (FastMath.DEG_TO_RAD * 4 * tpf) % (FastMath.PI * 2);


      float roll = (FastMath.DEG_TO_RAD * 7 * tpf) % (FastMath.PI * 2);


      float pitch = (FastMath.DEG_TO_RAD * 11 * tpf) % (FastMath.PI * 2);


      // rotating the box by this much


      geoBox.rotate(yaw, roll, pitch);


      // move box “forward” too, that is, forward relative to itself ie.


      // spaceship moving forward


      geoBox.move(geoBox.getLocalRotation().getRotationColumn(2).mult(tpf));





      Vector3f clonedCornerPos = cornerPos.clone();


      // now applying the same transform (pos/rot/scale) to the corner as the


      // box has


      geoBox.getLocalTransform().transformVector(clonedCornerPos,// in,


      clonedCornerPos// store


      );


      Vector3f f = box.getCenter().clone();


      geoBox.getLocalTransform().transformVector(f, f);


      coord.setLocalTransform(geoBox.getLocalTransform());


      coord.setLocalTranslation(f);


      // coord.setLocalTransform( geoBox.getLocalTransform() );





      // we have the corner’s exact pos now, relative to the Node the geoBox &


      // geoCurve are both in


      // we add that pos to the curve


      spline.addControlPoint(clonedCornerPos);// must be cloned!


      // we must create new Curve object because we can’t add/update the


      // spline in existing one (?!)


      geoCurve.setMesh(new Curve(spline, 1));


      }





      @Override


      public void simpleInitApp() {


      flyCam.setMoveSpeed(20f);





      Node subNode = new Node();


      subNode.setLocalTranslation(new Vector3f(2, 0.5f, 1));


      subNode.rotate(1f, -2f, 4f);


      // a box with non 0,0,0 center which means a position of x,y,z relative


      // to it’s parent geoBox(below)


      box = new Box(new Vector3f(2, 3, 4), 0.5f, 0.9f, 1.3f);


      geoBox = new Geometry(“Box”, box);


      geoBox.setLocalTranslation(1f, 2f, 3f);


      geoBox.scale(1.3f, 1.2f, 1.1f);// always ok


      geoBox.rotate(2f, -4f, 0.4f);


      Material mat2 = new Material(assetManager,


      “Common/MatDefs/Misc/WireColor.j3md”);


      mat2.setColor(“Color”, ColorRGBA.Red);


      geoBox.setMaterial(mat2);





      Material curveMat = new Material(assetManager,


      “Common/MatDefs/Misc/WireColor.j3md”);


      curveMat.setColor(“Color”, ColorRGBA.Green);


      geoCurve = new Geometry(“trails”);


      geoCurve.setMaterial(curveMat);


      subNode.attachChild(geoCurve);


      subNode.attachChild(geoBox);





      rootNode.setLocalTranslation(-1, -2, -4);


      rootNode.rotate(-1f, 2f, -4f);





      rootNode.attachChild(subNode);


      rootNode.scale(1.5f);// this is always ok


      subNode.scale(0.4f);// this is always ok too


      // subNode.scale(1.3f, 0.7f, 0.4f);// XXX: bug when uncommented


      // rootNode.scale(0.4f, 1.4f, 1.1f);// XXX: or/and this





      // doing this here only once


      cornerPos = new Vector3f();


      // calculating position of corner, first getting corner as it were if


      // box were at 0,0,0 and no rotation/scale


      cornerPos.set(





      box.getXExtent(), box.getYExtent(), box.getZExtent());


      // now considering box may have a different than 0,0,0 center


      cornerPos.addLocal(box.getCenter());


      coord = new Node();


      coord.setCullHint(CullHint.Never);


      attachCoordinateAxes(Vector3f.ZERO, coord);


      subNode.attachChild(coord);


      // coord.setLocalTranslation( geoBox.getLocalTranslation() );//


      // box.getCenter() );


      }





      private void attachCoordinateAxes(Vector3f pos, Node toNode) {


      Arrow arrow = new Arrow(Vector3f.UNIT_X);


      // make arrow thicker,


      arrow.setLineWidth(lineWidth);


      putShape(arrow, ColorRGBA.Red, toNode).setLocalTranslation(pos);





      arrow = new Arrow(Vector3f.UNIT_Y);


      arrow.setLineWidth(lineWidth); // make arrow thicker


      putShape(arrow, ColorRGBA.Green, toNode).setLocalTranslation(pos);





      arrow = new Arrow(Vector3f.UNIT_Z);


      arrow.setLineWidth(lineWidth); // make arrow thicker


      putShape(arrow, ColorRGBA.Blue, toNode).setLocalTranslation(pos);


      }





      private Geometry putShape(Mesh shape, ColorRGBA color, Node onNode) {


      Geometry g = new Geometry(“coordinate axis”, shape);


      Material mat = new Material(assetManager,


      “Common/MatDefs/Misc/Unshaded.j3md”);


      mat.getAdditionalRenderState().setWireframe(true);


      mat.setColor(“Color”, color);


      g.setMaterial(mat);


      onNode.attachChild(g);


      g.setCullHint(CullHint.Inherit);


      return g;


      }


      }



      /pre

A line has no width, thus you can set it globally. Use a lengthy tube.

1 Like
normen said:
A line has no width, thus you can set it globally. Use a lengthy tube.


Too many assumptions :) I mean, I don't understand what you mean by "you can set it globally"
I'm guessing around here, that the Arrow's width is formed of X lines where X is the width of the Arrow, therefore that explains why they don't scale down 'cause a line is always visible as at least 1 pixel no matter at what distance from camera (well maybe if too far it will be 0 pixels obviously)

By tube you mean com.jme3.scene.shape.Cylinder.Cylinder() I'm guessing, if so, maybe Arrow could also use cylinder when width is above 1 ? or maybe that is for me to subclass xD

I guess I understand the big picture of what you said, thank you! ;)

Its a line, it has no width: http://en.wikipedia.org/wiki/Line_(geometry)

So you set some width just so they can be painted at all, if they were really 0 pixels wide you would not see them.

If you want it to be three-dimensional then use a three-dimensional object.

1 Like

The line width is given in pixels, it is not effected by the projection. This is OpenGL behavior and is not related to jME3.

Like normen said, using a cylinder, which is an actual 3D object, is probably better for your needs.

1 Like

roger that, many thanks, too kind xD