Bow String and Cyberkilla's Skeletal

Started by AGP, March 21, 2008, 08:59:39 PM

Previous topic - Next topic

AGP

I'm making a bow and arrow minigame for which I "modelled" a cylinder with a bone structure on 3dsmax 9 and exported to OgreXML for reading into Cyberkilla's Skeletal API. The cylinder is meant to represent the distorting string of the bow. I tried drawing a 2-D string on the bow, but try as I might I can't get the VertexController to be up-to-date on the bow's coordinates. If I could, that would be an obvious solution. Anyway, in the absence of the 2D string I'm using the boned cylinder. Problem is when I load the string into JPCT it looks completely distorted. If anyone can tell me why I'd appreciate it.

And if someone would kinder stil and make me the scene for exporting I'd be that much the more grateful!

EgonOlsen

I don't know much (or should i say nothing?) about Cyber's skeletal API, but what exactly is the problem with the vertex controller based approach?

AGP

I can't get the mesh updated as I turn the bow.

Actually I just re-wrote my code and it's not even working the first time now. I do call VertexController.updateMesh() and have even renewed my instance of VertexController. The following is what I'm doing. I think I know one of the things you'll say: VertexController gives me vertices in object space and I want them in world space. But how do I get that?


SimpleVector[] vertices = getSourceMesh();
SimpleVector lowest = vertices[0], highest = vertices[0];
for (int i = 1; i < vertices.length; i++) {
    if (vertices[i].z < lowest.z)
lowest = vertices[i];
    if (vertices[i].z > highest.z)
highest = vertices[i];
}
SimpleVector[] extremes = new SimpleVector[2];
extremes[0] = lowest;
extremes[1] = highest;
...
Then, after buffer.display(Graphics):
SimpleVector point1 = Interact2D.project3D2D(mainCamera, buffer, uppermost);
SimpleVector point2 = Interact2D.project3D2D(mainCamera, buffer, lowermost);
g.setColor(Color.white);
g.drawLine((int)point1.x, (int)point1.y, (int)point2.x, (int)point2.y);



AGP

Egon, I would love your help on the VertexController thing, which is the more appropriate solution in this case.

But if anyone who knows the answer to my Skeletal API problem reads this, I'd still really like to know for future reference, because this is as far as I have come to succesfully using the API and I have a lot of character stuff I want to do. For the record, this is where I got the 3dsmax 9 exporter: http://www.walkerfamily.name/lexiexport.php

EgonOlsen

To get them in world space, you can get a world transformation from the bow object and apply that to the vertices in the controller. That should do the trick. Another idea would be to place some dummy objects at the string's ends, attach them to the bow as childs and call getTransformedCenter() on them to get their position in world space...if that's sufficient.

AGP

How would I do that? Matrix transformations = Object3D.getWorldTransformation(); vertex.x*transformations.getXAxis(), then repeat for y and z?

Sorry if it sounds stupid. I did take this math (and even wrote a very simple 3d "engine" of my own), but it's been many years. I appreciate your help, pal.

EgonOlsen

SimpleVector has a matMul()-method. Just call this with the transformation matrix on the vertex in question and you should get that vertex transformed into world space.

AGP

Thanks a lot, pal, it worked. Now, I'm occasionally getting an array index out of bounds exception with the visibilty lst (and so every occasional frame doesn't get drawn). At the beginning of the program, I'm using Config.maxPolysVsible *= 4; Does that have anything to do with it? Also, I'm only using the software renderer.

And if anybody can solve the skeletal thing for me I'll be very grateful.

EgonOlsen

Sounds like you manipulating jPCT objects from another thread then the rendering thread...

AGP

I don't have a rendering thread. Should I? As it is right now, two different threads call draw(), but as far as I can tell, never at the same time. Is there a problem I don't know?

EgonOlsen

I didn't meant to create a specific rendering thread but simply the thread that calls renderScene/draw/... You may call them from inside different threads but you have to absolutly sure that they don't interfere. Another common mistake is to manipulate objects in the AWT event dispatch thread, i.e. from inside a key- or mouse listener.

AGP

Well, the bow turns as you move the mouse. So, other than rotating it in mouseMoved(MouseEvent), how would you do it?

EgonOlsen

Either queue the rotation events or the rotation result indepently from the actual object and apply it right before doing the rendering.

AGP

Okay, but I still have to update the screen afterwards. So if I call draw() from mouseMoved(MouseEvent), how does that make it a separate thread? Or maybe I do need an independent thread just for draw(), after all.

EgonOlsen

Yes, put draw in a thread of its own, i.e. make a game loop thread (it doesn't have to be explicitly started...the thread that runs the main()-method will do). It's not good practice anyway to put complex operations like draw in the awt event thread because you are blocking the whole event dispatching with this, i.e. no keyboard and/or mouse events will be processed during the draw and no GUI elements (if there are any) will be updated.
Or, if that doesn't matter, put all jPCT related logic in the awt event thread...just don't mix.