Flag rush - lesson 7 problem

the tutorial suggests using JmeBinaryReader, which is evidently no longer supported. I tried switching it to BinaryImporter as shown in

http://www.jmonkeyengine.com/wiki/doku.php?id=model_loading and suggested in some other threads, but… problems cropped up



I'm new (obviously…) and am not sure what the problem is. I did notice that JmeBinaryReader was used to set the bounding to a box, which BinaryImporter doesn't do (if it does, I couldn't find it).



The actual problem crops up in the buildChaseCamera method

    private void buildChaseCamera()
    {
        Vector3f targetOffset = new Vector3f();
        targetOffset.y = ((BoundingBox)player.getWorldBound()).yExtent * 1.5f;
        HashMap<String, Object> props = new HashMap<String, Object>();
        props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "6");
        props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "3");
        props.put(ThirdPersonMouseLook.PROP_MAXASCENT, "" + 45 * FastMath.DEG_TO_RAD);
        props.put(ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(5, 0, 30 * FastMath.DEG_TO_RAD));
        props.put(ChaseCamera.PROP_TARGETOFFSET, targetOffset);
        chaser = new ChaseCamera(cam, player, props);
        chaser.setMaxDistance(8);
        chaser.setMinDistance(2);
    }



specifically this line:

        targetOffset.y = ((BoundingBox)player.getWorldBound()).yExtent * 1.5f;



it throws a null pointer error...

you can create a new BoundingBox after the model has been imported :


player.setModelBound(new BoundingBox());
player.updateModelBound();

you can create a new BoundingBox after the model has been imported


I agree. I had the same problem initially. But once you create a new BoundingBox and update the modelbound it will solve the problem. However if it does not, then you are importing the model incorrectly. Just post that part of the code and I'll have a look.  :)

hmmm…yes, I fixed that as you suggested, but it still doesn't work. I threw it in the debugger and tracked the problem down to a URL not loading.


        URL url = FlagRush.class.getClassLoader().getResource("resources/models/bike.3ds");



Not sure whats wrong with it though  :? it looks almost identical to the loader for textures (which works fine)

        FlagRush.class.getClassLoader().getResource("resources/textures/highest.jpg")



so, now I'm just plain confused  :D nothing unusual in that though

hehe ah, so the player was null, not the BoundingBox.



Try to make use of the ResourceLocator, i can't point you to a good example right away, but there are a few tests utilizing it.

Nice ninja duck thaspius. :slight_smile:

there is a pirate duck too :smiley:





@Core-Dump: i’ll take a look at that class, thanks

Quargh!  :stuck_out_tongue:



Is there a list of these? They're pretty funny. :slight_smile:

hehe, i’ve just found them here and there and saved them



















<— lol

Have you tried using the default directory containing the bike.3ds file as in the flagrush e.g. "jmetest/data/model/bike.3ds"? Why not use it from there? The only other thing I can think of is that either you have not put the bike.3ds in the resources/models/bike.3ds or either this directory is not in the build??

the bike.3ds is in the file, and i use my resources folder for the textures. All folders under the resources folder are in the build

Try to use the ResourceLocator and that will definitely solve the problem.

hmmm…i fixed it the specific error, but not the general one… after I post this, I'll try using ResourceLocator



i changed the file extension from .3ds to .jpg…and the URL error went away, but it is still causing a null pointer error when getting the world bound. I've debugged it a bit and the world bound is null, so

(BoundingBox)player.getWorldBound()


gets a null pointer error.

i called these methods when setting the player up


        player.setModelBound(new BoundingBox());
        player.updateModelBound();
        ...
        player.updateWorldBound();


is there something else that must be done so that the world bound is not null?

Alright could you post the whole code of the method where you are importing the .3ds file/creating your player? I think you are making a mistake there and thats why the chase camera is giving you null at:


targetOffset.y = ((BoundingBox)player.getWorldBound()).yExtent * 1.5f;



I had a similar problem and have solved it just need to see your code to pinpoint the problem.

still doesn't make sense that the system can find a .jpg file and not a .3ds

After I changed the extension to .jpg and changed the url to match, it did load the model.



player.getWorldBound() returns null

(null).yExtent causes null pointer error



here is the code:


        Node model = null;
        MaxToJme C1 = new MaxToJme();
        ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(); //For loading the raw file

        // File Path for the model
        URL url = FlagRush.class.getClassLoader().getResource("resources/bike.jpg");

        InputStream is = null;
        try
        {
            is = url.openStream();
        }
        catch (Exception err)
        {
            System.out.println("Could not open Model file: " + err);
        }
        try
        {
            // Converts the file into a jme usable file
            C1.convert(is, bytearrayoutputstream);

            // Used to convert the jme usable file to a TriMesh
            BinaryImporter binaryImporter = new BinaryImporter();
            ByteArrayInputStream in = new ByteArrayInputStream(bytearrayoutputstream.toByteArray());

            //importer returns a Loadable, cast to Node
            model = (Node)binaryImporter.load(in);
        }
        catch (Exception err)
        {
            System.out.println("Error loading md3 model:" + err);
        }

        //set the vehicles attributes (these numbers can be thought of as Unit/Second).
        player = new Vehicle("Player Node", model);
        player.setModelBound(new BoundingBox());
        player.updateModelBound();
        player.setAcceleration(15f);
        player.setBraking(25f);
        player.setTurnSpeed(2.5f);
        player.setWeight(25f);
        player.setMaxSpeed(25f);
        player.setMinSpeed(15f);

        player.setLocalTranslation(new Vector3f(100, 0, 100));
        scene.attachChild(player);
        player.updateWorldBound();

        player.setRenderQueueMode(Renderer.QUEUE_OPAQUE);


try to use the ResourceLocator like the following:

First set the path and later search the file just with the filename.



try {
    ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_TEXTURE,
            new SimpleResourceLocator(Main.class.getClassLoader().getResource("resources/")));
    ResourceLocatorTool.addResourceLocator(ResourceLocatorTool.TYPE_MODEL,
            new SimpleResourceLocator(Main.class.getClassLoader().getResource("resources/")));
} catch (URISyntaxException e1) {
    System.exit(-1);
}

...
...
...

Texture tex = TextureManager.loadTexture(
                        ResourceLocatorTool.locateResource(ResourceLocatorTool.TYPE_TEXTURE,"floor.png"),
                        Texture.MM_LINEAR, Texture.FM_LINEAR, Image.GUESS_FORMAT_NO_S3TC, 0.0f, true);

To be honest I cannot see anything wrong with your code - may be I am missing the same thing as you and more senior members could shed some light… In the mean time try out this, it worked perfectly for me when I used to practice the examples, should do the same for you if it doesnt we can rule this possibility out…





    private void createPlayer()
    {
        Node model = null;
        try
        {
            MaxToJme C1 = new MaxToJme();
            ByteArrayOutputStream BO = new ByteArrayOutputStream();
            URL maxFile = Ares.class.getClassLoader().getResource("jmetest/data/model/robot.3ds");
            C1.convert(new BufferedInputStream(maxFile.openStream()),BO);
            model = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
           
            //scale it to be MUCH smaller than it is originally
            model.setLocalScale(1.5f);       
         
                       
            player = new Vehicle("Player Node", model);
            player.setLocalTranslation(new Vector3f(138, 55, 112));
            //Creating the CameraNode and attaching it to the player for the first person view as in FPS games
            camNode = new CameraNode("camera Node", cam);
            player.attachChild(camNode);
            scene.attachChild(player1);
            scene.updateGeometricState(0, true);

        }
     
        catch (IOException e)
        {   // Just in case anything happens
            System.out.println("Exception: !" + e);
            e.printStackTrace();
            System.exit(0);
        }
    }


ResourceLocator also will not open / find bike.3ds, it will find bike.jpg. both of those files are in the exact same location and are actually the same file, just the extension is altered.



I'm going to see if updating my jME libraries will help. I don't have a cvs client on this computer and don't have rights to install one. I'll just have to get them on my home pc and transfer to this one…



I'll go ahead and test the code on a couple other pc's and see if it is just this computer. I am currently running the build from oracle jdeveloper. I'll use eclipse at home and see if it helps. It would be unfortunate if jdeveloper was the problem though…it is the only ide I have at my disposal on this computer.

Try setting the resource locator type to MODEL and not TEXTURE… this way there will be no confusion in the locator.

I did have it as MODEL, i gave up on the tutorial and just started on a project. I get the gist of how it should work. It was probably something unrelated to the code itself that I wasn't noticing.