Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - stownshend

#1
Support / Flipping Phone causes Weird Translation
October 12, 2011, 10:49:34 AM
Hi there,

I have a level of tiles, and a main character. The camera and main character move to a tile when the user touches it. Here is the code I am using to implement this (which is inside my onDrawFrame() method):


/**
* CAMERA MOVEMENT
*
* This first section of code is part of the algorithm which handles
* camera movement. When a touch event occurs, the origin of the tile which
* was selected is saved as the destinationX and destinationZ
* properties. The following code animates moving the camera from its
* existing position to this destination. */

// To animate smoothly (frame rate independent) we're going to keep
// track of how much time elapses between frames. We need a calendar
// object to do this.
Calendar now = Calendar.getInstance();

// Calculate how much time has passed since the previously rendered frame.
long millisecondsPassed = now.getTimeInMillis() - previousFrameTime;

// If the camera isn't already approximately at the destination...
if ( cameraX < destinationX-1 || cameraX > destinationX+1)
{
// The xModifier is a variable which is +1 if the destination is down
// the positive x axis and -1 if it is down the negative.
Float xModifier = 1f;

// If the destination is down the -x axis, change the xModifier accordingly.
if ( cameraX > destinationX )
{
xModifier = -1f;
}

// Set the camera's new position. The xModifier determines if it
// will be down the +x or -x direction, and the millisecondsPassed
// makes this frame rate independent - so on a slow device the
// animation will be blocky but fast, and on a fast device the
// animation will be smooth and fast.
cameraX = cameraX + (0.01f * xModifier * millisecondsPassed);

// Translate the AntQueen object
antQueen.translate((0.01f * xModifier * millisecondsPassed), 0, 0);
}

// This block of code does exactly the same as the x-direction code
// above but for the z-direction.
if ( cameraZ < destinationZ-1 || cameraZ > destinationZ+1)
{
Float zModifier = 1f;

if ( cameraZ > destinationZ )
{
zModifier = -1f;
}

cameraZ = cameraZ + (0.01f * zModifier * millisecondsPassed);

// Translate the AntQueen object
antQueen.translate(0, 0, (0.01f * zModifier * millisecondsPassed));
}

// Record the current time for the next call to this method (the next
// frame).
previousFrameTime = now.getTimeInMillis();

// Move the camera to its new position. The -10 is a constant offset
// on the z axis.
camera.setPosition(cameraX,cameraY,cameraZ-10);


My problem is that if the camera and queen are moving when I flip the camera over (and it re-adjusts for landscape or portrait) the queen will often teleport out of sync with the camera. Normally she is meant to sit in the centre of the camera, so the camera is essentially locked on to the top of her head.

I'm trying to work out why. All of my creation code is in my onSurfaceCreated() method, and the only thing inside onSurfaceChanged() is:


public void onSurfaceChanged(GL10 gl, int w, int h)
{
// Checks if there is an existing FrameBuffer and disposes it if required.
if (frameBuffer != null)
{
frameBuffer.dispose();
}

frameBuffer = new FrameBuffer(gl, w, h);
}


I know I haven't provided a lot of information and I'm finding it hard to describe my problem, but in-case someone recognizes the issue and has dealt with it before I thought it was worth a shot posting this.

I will try and post some better information as I work through it myself.
#2
Support / Re: object pivot
October 11, 2011, 10:01:37 AM
Looks like OBJ doesn't have any concept of a "pivot" like .3ds files do.

The file just contains:

- vertices
- texture co-ordinates
- polygons
- vertex normals

Really interesting, I didn't know it was just plain text.

I don't know enough about modelling, geometry, and the OBJ file formats to study it further. If anyone else has the same requirement (to have an object pivot imported from a modelling program) but also wants to strip out transformation information I recommend exporting to OBJ, then importing and re-exporting to 3DS in the meantime.

http://people.sc.fsu.edu/~jburkardt/txt/obj_format.txt
#3
Support / Re: object pivot
October 11, 2011, 09:42:21 AM
Hi Egon,

Will have a look at the OBJ format and see if it has pivots and if so will provide you a test case.

We found a solution just now - he imported our OBJ files into Max, exported them as 3DS, and doing this has stripped out all the transformation information which was causing them to get messed up before.

So no urgency on the OBJ pivots!

Thanks for your patience.
#4
Support / Re: object pivot
October 11, 2011, 08:52:17 AM
Does the pivot reading work for .OBJ files too or just .3DS?

I tried it with OBJ files and it didn't throw any error but they appear to have calculated object origins as before. The line of code I changed was:


// Configure JPCT to import object origins from model files.
Config.useRotationPivotFrom3DS = true;


If not, is there any chance this could be included? OBJ is for us a much better format because of the exporting functions in Max which allow us to strip out all transformations and get just the mesh data.

Just in-case I'm doing my rotations wrong here is my code:


// Load models - each one has object origin/pivot set to world origin (0,0,0).
honeyTop = new Object3D(loadModel(HONEY_TOP_MODEL_FILE, HONEY_TOP_TEXTURE_NAME));
honeyWall = new Object3D(loadModel(HONEY_WALL_MODEL_FILE, HONEY_WALL_TEXTURE_NAME));
honeyTrap = new Object3D(loadModel(HONEY_TRAP_MODEL_FILE, HONEY_TRAP_TEXTURE_NAME));
honeyOutline1 = new Object3D(loadModel(HONEY_OUTLINE1_MODEL_FILE, HONEY_OUTLINE_TEXTURE_NAME));
honeyOutline2 = new Object3D(loadModel(HONEY_OUTLINE2_MODEL_FILE, HONEY_OUTLINE_TEXTURE_NAME));
honeyOutline3 = new Object3D(loadModel(HONEY_OUTLINE3_MODEL_FILE, HONEY_OUTLINE_TEXTURE_NAME));

// Rotate to accommodate for coordinate system
honeyTop.rotateX(PI / -2f);
honeyWall.rotateX(PI / -2f);
honeyTrap.rotateX(PI / -2f);
honeyOutline1.rotateX(PI / -2f);
honeyOutline2.rotateX(PI / -2f);
honeyOutline3.rotateX(PI / -2f);

// Add to world
world.addObject(honeyTop);
world.addObject(honeyWall);
world.addObject(honeyTrap);
world.addObject(honeyOutline1);
world.addObject(honeyOutline2);
world.addObject(honeyOutline3);
#5
Support / Re: Scale around a center point?
October 10, 2011, 10:37:03 PM
I've been following this thread and still don't understand what it means to scale around an arbitrary point? Are you talking about distorting the original model in any way? Or simple scaling it (around the centre) and translating it to accommodate this point?

By distortion I mean something like (see attached image)

[attachment deleted by admin]
#6
Support / Re: object pivot
October 09, 2011, 03:52:54 AM
Update: I tried using the Object3DsetOrigin() method because what I want is the pivot to be 0,0,0 in world space (so when I rotate all these objects they rotate around the same spot and keep their relative positions).

That didn't work. I thought perhaps it failed because I needed to do the rotation and set the origin after I added it to the world, but changing the order didn't have a noticeable impact.

The only solution I've found is to import all the objects - add them to an array of Object3D's, then create a new Object3D using the Object3D.mergeAll() method - and then rotate this new "super" object. However because it calculates the geometric centre of this new object I've lost track of its world position and when I go to place my active objects (tiles) they're no longer in the correct place.

I'm going to try my old approach (mergeAll) but then find the object centre, and then translate it to the world origin. Better approaches/ideas are most welcome.
#7
Support / Re: Problem with FOV value
October 09, 2011, 03:16:58 AM
I don't think you're after code examples - it sounds more like you want to understand how it works. However, just in case it is helpful here is how I implemented picking. I am using picking so that the player can select tiles within my game (laid out along the xz plane).


    public boolean onTouchEvent(MotionEvent event)
    {
    // Find the x and y positon of the touch event
    Integer xpos = new Float(event.getX()).intValue();
    Integer ypos = new Float(event.getY()).intValue();
   
    // Log the position
    Log.d("xpos", xpos.toString());
            Log.d("ypos", ypos.toString());
       
            // Find the direction vector that the camera is looking in and use that to find a vector
            // out from where the user has touched the screen.
SimpleVector dir=Interact2D.reproject2D3DWS(camera, frameBuffer, xpos, ypos).normalize();

    // Find the nearest object along that vector. res[0] is the distance, res[1] is the Object3D
    // which is null when there is no object.
    Object[] res=world.calcMinDistanceAndObject3D(camera.getPosition(), dir, 10000 /*or whatever*/);

    Log.d("distance", res[0].toString());

    if ( (Float) res[0] < 1000.0f )
    {
    Log.d("object", res[1].toString());

Object3D currentTile = (Object3D) res[1];

Log.d("Current Tile Centre X", new Float(currentTile.getTransformedCenter().x).toString());
Log.d("Current Tile Centre Y", new Float(currentTile.getTransformedCenter().y).toString());
Log.d("Current Tile Centre Z", new Float(currentTile.getTransformedCenter().z).toString());

// Save the x and z coordinates of the tile selected for future use.
destinationX = currentTile.getTransformedCenter().x;
destinationZ = currentTile.getTransformedCenter().z;

// TODO: Need to save the selected object in here if there is one?
    }

    touchEvent = true;

            return true;
    }


And of course any object you want to pick needs to have collision detection enabled:


// Sets the tile up so that collision events can occur so that it can be
// selected by the player.
honeyTile.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);


Like I said, I don't understand the intricacies of how it works, only that it does.
#8
Support / Re: object pivot
October 09, 2011, 03:08:33 AM
Hi Egon,

I want to use the pivot set in 3DS Max or Blender for some .3ds and .obj model files.

The reason being - my colleague has created a scene for me which contains 6 object files. I want to import them and have them stay in their relative positions to each other when I rotate them to accommodate for the change in coordinate system.

I've tried Config.useRotationPivotFrom3DS but this doesn't appear to be included in my version of jpct-ae.jar. Was this method/property made part of the main branch of code or was it a one off which can only be accessed by using that specific JAR file you created for Thomas?

Many thanks,

Stephen
#9
Support / Understanding Translations
October 04, 2011, 10:26:25 AM
Hi all,

I load, rotate, and translate a bunch of objects in my onSurfaceChanged() method (will change this to onSurfaceCreated()) and I'm trying to understand the effect that translations made in one place have on subsequent calls to translate().

For example, in the following code, will object2's initial position be impacted by the translation of object1?

(note the loadOBJModel method is a custom one I wrote as a shortcut to the model/texture loading process)


object1 = new Object3D(loadOBJModel(MODEL_1, TEXTURE_NAME_1));

object1.translate(-5.0f,0.0f,-5.0f);

object2 = new Object3D(loadOBJModel(MODEL_2, TEXTURE_NAME_2));

object2.translate(5.0f,.0f,5.0f);



Furthermore, when I am using rotations and translations, is there an order I should be doing these?

This feels like graphics programming 101. I've written Open GL / GLU / GLUT code in C++ before and not been so confused because I could use GL_START and GL_END tags to start and stop each transformation (I think that's what they were called).

IF the answer to the above questions are yes, translate() is impacted by the previously translated position... What is an easy way to translate an Object3D to a particular point in world space?
#10
Support / Re: 3DS Max & JPCT
October 04, 2011, 08:17:16 AM
Hi Egon, thanks for your help, and for your ongoing patience :)

For anyone else having the same issue:

We solved the problem by exporting in the .OBJ file format from 3DS Max instead of .3DS. When you export in this format you can define additional settings which allow you to strip out everything except the mesh data. I don't know the exact details but my colleague worked it out first attempt.

I found no difference handling OBJ models rather than 3DS ones so the impact to me was minimal.
#11
Support / Re: Y-Axis - Up-Vector - Confusion
October 03, 2011, 04:32:36 AM
I too found it a little frustrating at first - but the reality is that modelling programs like 3DS Max have the +z axis pointing up as Egon mentioned before, so translating between different co-ordinate systems is just part of the business.

If you do have objects which exist in the +y up co-ordinate system you can rotate every object by PI / -2.0 along the X axis (Object3D.rotateX()) as you import it then it adjust it correctly (that's what I've been doing). This, of course, relies on object origins being in the "centre" of each object and only really makes sense if you're importing model files.
#12
Support / 3DS Max & JPCT
October 03, 2011, 03:25:48 AM
Hi all,

I am coding in JPCT a game and I have a friend developing the models in 3DS Max, which we're exporting as the .3ds file format.

For the most part it works great, but sometimes when I import the models into JPCT they appear in unusual places.

From what I understand, whatever "world" position the models took up in 3DS Max, they should appear (although rotated to right hand notation) in the same world position in JPCT.

Most of the time this works fine. However (and I seem to remember it always happens when he has multiple objects in a single scene, and exports the objects separately) the objects will appear way off.

For example; One time we had a basic square tile model (5x5 plane) with a PNG texture image. In his project the tile was centred at 0,0,0 but when I imported it into JPCT it was at something bizarre like 278,-48,3. We never worked out why this happened, but he created a new project fresh and re-created it and it worked when he exported it as expected.

I'm 90% sure the problem is with his 3DS Max project/settings, but thought I'd post it here in the hope that someone else has had similar issues and might know if there is anything I can do at my end (or even any settings or hints for 3DS Max he could do) to stop this happening.

In the meantime we're looking at shifting to Blender. He's spent hours and hours on a level which contains 6 models all up, and when we import them they appear all over the place and are no longer aligned. Aligning them manually with translations myself would be painful, and from a theoretically point of view I need to know WHY these models are not importing in the same position as they are in their originating project.

Many thanks,

Stephen
#13
Support / Re: Displaying multiple boxes
September 09, 2011, 12:44:24 PM
I've been working with a 3D modeler on a project using JPCT-AE and one of the things he's told me is that you should never have 3D polygons up against each other. You should design the models so that only what is visible has a face - and even the opposite side of the visible sides are not rendered. It's for performance reasons and also because of the weird behaviour when two faces exist in the same space (jaggies etc).

If you want to make a wall, make one big polygon and use textures to give it a brick look. And if you never see the flip side of it, just make it a 2D plane.
#14
Support / Re: Keeping track of character direction
September 09, 2011, 06:31:43 AM
Hi Egon,

Thank you very much for the suggestion!

It took a little bit of fiddling but the code and algorithm is ridiculously simple compared to what I was trying to achieve before. It works like a charm, she is facing whatever tile I click without any hassle.

My problem was that I thought you had to do an Object3D.rotateMesh() after setting up a rotation matrix in order to make it do the rotation but it wasn't required. My code:

SimpleVector queenDesiredEyeline = new SimpleVector(
destinationX - antQueen.getTransformedCenter().x,
0,
destinationZ - antQueen.getTransformedCenter().z).normalize();

Matrix queenRotationMatrix = new Matrix(queenDesiredEyeline.getRotationMatrix());

Log.d("queenDesiredEyeline",queenRotationMatrix.toString());

antQueen.setRotationMatrix(queenRotationMatrix);
#15
Support / Keeping track of character direction
September 08, 2011, 02:18:07 AM
I have a character in my game who sits in the middle of a 5x5 grid of tiles. Aesthetically she has a front (where she is looking).

When I click on one of the tiles, I want my character to look at the centre of that tile.

I've currently spent 6 hours or more trying to work this out but I'm failing miserably. I will describe my approach below, but if there is an easier way or a way JPCT-AE can assist me in doing this, that would be great.

My approach:

My character is called the Queen. I've set up a property which is a SimpleVector which represents the direction the Queen is looking. At first she is looking away from the camera so this Vector is set to (0,0,1).


private SimpleVector queenDirection;


And the initialization of the initial direction:


public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// The Queen is originally facing to 0 degrees.
queenDirection = new SimpleVector(0f,0f,1f);
...


My algorithm is:

- Calculate a vector from the Queen's current position (0,0,0 for now in world space) to the centre of the tile selected. I use the formula vector = destinationX-currentX, destinationY-currentY, destinationZ-currentZ


SimpleVector eyeline = new SimpleVector(
destinationX - queen.getTransformedCenter().x,
0,
destinationZ - queen.getTransformedCenter().z).normalize();


- Then I calculate the angle (in radians) between the Queen's current viewing direction, and this new vector using the formula angle = acos((v1 DOT v2) / (v1.length * v2.length)):


float dotProduct = queenDirection.calcDot(eyeline);

Double temp = (double)  dotProduct / ( queenDirection.length() * eyeline.length());

double angle = Math.acos(temp)


... but already I run into problems because (perhaps due to the accuracy of float/double or something else) the dotProduct and therefore "temp" variable which is passed into the arc cosine function is sometimes either slightly higher than 1 (1.00000123) or it's negative - either way the acos function returns NaN because it only accepts parameters between 0 and 1.

The code which actually does the rotation is:


if ( angle > 0.5 )
{
queen.rotateY((float) angle);

queenDirection.x = eyeline.x;
queenDirection.z = eyeline.z;
}


I'm not great at mathematics, but I'll get stuck into if it I have to. My primary question is whether there is an easier way? If not, I'll keep working at this but I wanted to check before I spend another 6 hours at it.

This game is going to have a lot of models who need to turn and face each other often, so I need to have this down before I move on.