libgdx's btRaycastVehicle not following chassis and wheels correctly - libgdx

I setup a btRaycastVehicle as shown by xoppa in bullet tests of libGdx. When vehicle is at low speed, then it works correctly. But as speed of vehicle goes on increasing, chassis and wheels tend to separate from each other. Distance between wheel to wheel and wheel to chassis increases and after that vehicle behaves in incorrect way. Then the whole vehicle sometimes rotates around an axis.

I recently had the same problem. The issue seems to be that the MotionState's callbacks are being called on a different thread to the render function. In Xoppa's sample app (here, for anybody else reading along), the wheel transforms are being updated in the render thread. The fix was to do the wheel transform in the MotionState's callback as well:
#Override
public void setWorldTransform (final Matrix4 worldTrans) {
transform.set(worldTrans);
for (int i = 0; i < 4; i++) {
vehicle.getWheelInfo(i).getWorldTransform().getOpenGLMatrix(wheels[i].transform.val);
}
}
Now all the transforms get updated at the same time, and the wheels stick to the chassis.

Related

Collision Detection - How to?

I am currently working on a flash game and am rather new to AS 3 or flash. Need some advice in how to implement one of the core elements of my game.
The idea is 2 player competitive snake style game, only the players do not try to kill each other, but try to reach their opponents spawnpoint.
1 of the key parts of the game would be a grid which is created over the stage where either player may use to "Create walls" by passing through points on the grid. I have no idea how to implement this. Currently I have the basics down where there are 2 players with a starting spot, and if either one reaches the other's starting zone, they score a point.
I need some advice in how to go about implementing this feature:
Each point in the grid will start off in a certain state, and when a player passes through that point, it will be "activated". Then the player may move through any adjacent points to the "activated" point, which will generate a wall between both active points, and thats how they will create mazes to protect their starting area.
Should I generate each point individually or create a grid with a simple function:
//function to create grids on the map
public function createGrid()
{
var rows:int = 6;
var cols:int = 11;
for (var py:int = 0; py < rows; py++) {
for (var px:int = 0; px < cols; px++) {
this.grid = new griDot(player1,player2, this);
grid.x = 50 + grid.width + 100 * px +10;
grid.y = 50 + grid.height +100 * py + 10;
this.addChild(grid);
}
}
}
and they are detected with this function(don't laugh i'm pretty noob):
public function checkDotCollision(player)
{
if(player1.hitTestObject(grid) == true)
{
trace("player dot collision detected");
}
if(player2.hitTestObject(grid) == true)
{
trace("player dot collision detected");
}
}
currently only the left most bottom square of the grid is detecting the player. Any help / advice on how to implement this feature would be greatly appreciated.
I'm not going to provide you with code, just with an idea.
In your Player class (if you don't have one, you can get away with the dynamic properties of a movieclip but it's not very clean), add a lastTouchedGriDot of type griDot.
In checkDotCollision, check for each tile. You can't do this at the moment; looks like you'll have to maintain a collection for griDots somewhere. So alter createGrid() to store the created objects in a collection of sorts. Then we can check for each tile. So do so. If you've found a hit, do the following:
If there is no last touched grid point, set the last touched grid point to the one you're touching now.
If the grid point that was last touched is the same as the one you're touching now, do nothing.
If the grid point that was last touched is different than the one you're touching now, check if it's adjacent. If so, build a wall. If not, set the last touched grid point to the one you're touching now.
This should provide you with a solid start. You'll have to add wall collisions and checking if there already IS a wall yourself.

libGDX - How to clip

I have one SpriteBatch in my game, between whose batch.begin() and batch.end() I draw...
a large static background image
several game sprites
I want to clip the area in which the sprites are seen, which I've read is done using ScissorStack.
The problem is that ScissorStack appears to clip the entire SpriteBatch that's sent to the GPU. The result is that it clips my game sprites and the background image.
Question:
Must I have two separate batch.begin() and batch.end() cycles, one without clipping for the background, and another with clipping for the sprites? Or is there a way of clipping just the sprites without using ScissorStack?
If the former, then isn't it rather expensive flushing the SpriteBatch twice as many times simply in order to clip a few sprites, or is it really nothing to worry about in terms of performance?
Related question:
The calculateScissors() method in the latest source code has more parameters than I've seen documented anywhere...
calculateScissors(camera, viewportX, viewportY, viewportWidth, viewportHeight, batchTransform, area, scissor)
What is the purpose of the viewportX, viewportY, viewportWidth, viewportHeight when they appear to be duplicating the camera's viewport and area information, and are not mentioned in any docs?
Basically, I'm really confused... even after (or especially after!) testing the behaviour of different values for each of these parameters.
Any advice sought.
Instead of using a ScissorStack I resorted to using using glScissor to get the results I needed.
#Override
public void render(float delta) {
GameStage.INSTANCE.act(Gdx.graphics.getDeltaTime());
GameStage.INSTANCE.setViewport(GameGeometry.width, GameGeometry.height,
true);
GameStage.INSTANCE.getCamera().translate(
-GameStage.INSTANCE.getGutterWidth(),
-GameStage.INSTANCE.getGutterHeight(), 0);
Gdx.gl.glScissor(
(int) GameStage.INSTANCE.getGutterWidth() * 2,
(int) GameStage.INSTANCE.getGutterHeight(),
(int) Gdx.graphics.getWidth()
- (int) (GameStage.INSTANCE.getGutterWidth() * 4),
(int) Gdx.graphics.getHeight());
Gdx.gl.glDisable(GL10.GL_SCISSOR_TEST);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Gdx.gl.glEnable(GL10.GL_SCISSOR_TEST);
GameStage.INSTANCE.draw();
}
Hope this helps.

libGDX zoom implementation isn't working right

I would like to achieve a zoom effect that is similar to "Clash of Clans". I'm currently implementing zoom in a way that pretty much all the tutorials online do. There are of course a my camera specific constants to make it zoom at good speeds for my camera.The code DOES WORK.
#Override
public boolean zoom(float initialDistance, float distance) {
float zoomAmount = -1*(distance - initialDistance)/10000;
cameraHelper.addZoom(zoomAmount);
return true;
}
The camera helper class does this simple stuff:
public void addZoom(float amount) {
setZoom(zoom + amount);
}
public void apply(OrthographicCamera camera) {
camera.zoom = zoom;
camera.update();
}
So this does work. When I fling two fingers in one continuous motion and then stop moving the fingers on the screen, let's say I zoom in with zoomAmount = x, zoom gets called once and the zoom is done.
Problem:
However, if I then wiggle one, or both, of the fingers just a tiny bit, zoom gets called again with that same value for zoomAmount = x. So by wiggling a finger, it will simply keep adding to zoom and keep zooming in or out (depending on the current state of zoomAmount).
Question:
How do I make libgdx or java remember my original camera.zoom much like initialDistance in the zoom() method. OR, is there any other trick that I can do to have a responsive and smooth zoom (without removing fingers from the screen) much like the game "Clash of Clans".
Extra info:
I have tried pinch, same effect. I have thought about having a base zoom value and then some kind of percentage multiplier, however because I have to update the camera by setting its zoom (camera.zoom = zoom;) I can't think of a clever trick with adding or subtracting any values that will not be effected by zoom() being constantly called. Any thoughts anyone?

Rotating a Model in Away3D

Here's what i want to do:
I want to load a model (most likely .3ds) into my .swf and be able to rotate it with the mouse.
This works fine at first glance, but there's problem, the rotations 'switch' over. Or to say it differently:
Imagine we have a model in the shape of a pipe.
If we drag the mouse to the right, the model rotates along its X-Axis to the left, mouse to the left, X-Axis rotation to the right, moving the mouse up, Y-Axis rotation downward, mouse down, Y-Axis rotation upward.
Now, lets say we turn the pipe to the right or left, until we face the (former) 'backside' of the pipe, and then we move the mouse down. The model will rotate downward instead of upward.
I hope you understand what i mean with this. I've been looking around for a good while now and never found a satisfying solution. There was talk about quaternions, but i can't grasp them.
Another suggestion i read somewhere is the following:
create a Matrix3D object, apply rotation on it, then multiply it with the desired Matrix3D of my 3d-Model.
I tried to do it, but the result stays the same, the directions of rotation switches depending on what side i'm facing.
private function update(e:Event):void
{
xCalc = (0.3*(stage.mouseX - lastMouseX));
yCalc = (0.3*(stage.mouseY - lastMouseY));
if(move)
{
var objTransform:Matrix3D = new Matrix3D();
objTransform.prependRotation(xCalc, Vector3D.Y_Axis, objC.pivotPoint);
objTransform.prependRotation(yCalc, Vector3D.X_Axis, objC.pivotPoint);
mesh.transform = multiply3DMatrices(mesh.transform, objTransform);
}
lastMouseX = stage.mouseX;
lastMouseY = stage.mouseY;
view.render();
}
multiply3DMatrices simply multiplies two 4x4 Matrices together.
objC is the ObjectContainer3D that holds my model. For some reason i cannot rotate it properly, unless i manipulate the rotationX/Y/Z properties.
mesh is the mesh inside of the Model (which is very simple, a single mesh).
Also, i'm aware that i could try another Framework for this (like papervision) but this project requires me to use Away3D.
Solved it by myself, the problem was that i created a new Matrix3D Object every time. The fixed code looks like this:
private function update(e:Event):void
{
...
if(move)
{
var objTransform:Matrix3D = mesh.transform;
objTransform.appendRotation(xCalc, Vector3D.Y_Axis, objC.pivotPoint);
objTransform.appendRotation(yCalc, Vector3D.X_Axis, objC.pivotPoint);
mesh.transform = objTransform;
}
...
}
And yes, the user bwroga was actually right, i should've used appendRotation instead of prependRotation, as well.

Displaying 100 Floating Cubes Using DirectX OR OpenGL

I'd like to display 100 floating cubes using DirectX or OpenGL.
I'm looking for either some sample source code, or a description of the technique. I have trouble getting more one cube to display correctly.
I've combed the net for a good series of tutorials and although they talk about how to do 3D primitives, what I can't find is information on how to do large numbers of 3D primitives - cubes, spheres, pyramids, and so forth.
You say you have enough trouble getting one cube to display... so I am not sure if you have got one to display or not.
Basically... put your code for writing a cube in one function, then just call that function 100 times.
void DrawCube()
{
//code to draw the cube
}
void DisplayCubes()
{
for(int i = 0; i < 10; ++i)
{
for(int j = 0; j < 10; ++j)
{
glPushMatrix();
//alter these values depending on the size of your cubes.
//This call makes sure that your cubes aren't drawn overtop of each other
glTranslatef(i*5.0, j*5.0, 0);
DrawCube();
glPopMatrix();
}
}
}
That is the basic outline for how you could go about doing this. If you want something more efficient take a look into Display Lists sometime once you have the basics figured out :)
Just use glTranslatef (or the DirectX equivalent) to draw a cube using the same code, but moving the relative point where you draw it. Maybe there's a better way to do it though, I'm fairly new to OpenGL. Be sure to set your viewpoint so you can see them all.
Yeah, if you were being efficient you'd throw everything into the same vertex buffer, but I don't think drawing 100 cubes will push any GPU produced in the past 5 years, so you should be fine following the suggestions above.
Write a basic pass through vertex shader, shade however you desire in the pixel shader. Either pass in a world matrix and do the translation in the vertex shader, or just compute the world space vertex positions on the CPU side (do this if your cubes are going to stay fixed).
You could get fancy and do geometry instancing etc, but just get the basics going first.
This answer isn't just for OP's question. It also answers a more general question - displaying many cubes in general.
Drawing many cube meshes
This is probably the most naive way of doing things. We draw the same cube mesh with many different transformation matrices:
prepare();
for (int i = 0; i < numCubes; i++) {
setTransformation(matrices[i]);
drawCube();
}
/* and so on... */
The nice thing is that this is SUPER easy to implement, and it's not too slow (at least for 100 cubes). I'd recommend this as a starter.
The problem
Ok, but let's say you want to make a Minecraft clone, or at least some sort of project that requires thousands, if not tens of thousands of cubes to be rendered. That's where the performance starts to go down. The problem is that each drawCube() sends a draw call to the GPU, and the time in each draw call adds up, so that eventually, it's unbearable.
However, we can fix this. The solution is batching, a way to do only one draw call for all of the cubes.
Batching
We join all the (transformed) cubes into one single mesh. This means that we will have to deal with only one draw call, instead of thousands. Here is some pseudocode for doing so:
vector<float> transformedVerts;
for (int i = 0; i < numCubes; i++) {
cubeData = cubes[i];
for (int j = 0; j < numVertsPerCube; j++) {
vert = verts[j];
/* We transform the position by the transformation matrix. */
vec3 vposition = matrices[i] * verts.position;
transformedVerts.push(vposition);
/* We don't need to transform the colors, so we just directly push them. */
transformedVerts.push(vert.color);
}
}
...
sendDataToBuffer(transformedVerts);
If the cubes are moving, or one of the cubes is added or deleted, you'll have to recalculate transformedVerts and then resend it to the buffer - but this is minor.
Then at the end we draw the entire lumped-together mesh in one draw call, instead of many.