Bullet physics - sphere doesn't bounce - bulletphysics

I'm playing around with Bullet, I have a ground-floor and a ball, and I want the ball to fall and bounce on the ground. However this doesn't happen, even with very high values of m_restitution, which is supposed to regulate the bounciness.
Any clue why this is happening? This is torturing me for some hours now with no luck.
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0,+9.8,0)); // GLWidget - y axis points downwards !!!
/////////////////////////////////////////////////////////////////////////////
//// Ground ///////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)));
btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, groundShape, btVector3(0,0,0));
groundRigidBodyCI.m_restitution = 1.0f;
groundRigidBodyCI.m_friction = 3.0f;
groundRigidBodyCI.m_rollingFriction = 3.0f;
groundRigidBodyCI.m_mass = 0.0f;
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
dynamicsWorld->addRigidBody(groundRigidBody);
/////////////////////////////////////////////////////////////////////////////
//// Ball /////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
btDefaultMotionState* ballMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(0,-100,0)));
btScalar ballMass = 1;
btVector3 ballInertia;//(0,0,0);
ballShape->calculateLocalInertia(ballMass, ballInertia);
btRigidBody::btRigidBodyConstructionInfo ballRigidBodyCI(ballMass, ballMotionState, ballShape, ballInertia);
groundRigidBodyCI.m_restitution = 1.0f;
ballRigidBodyCI.m_friction = 1.0f;
ballRigidBodyCI.m_rollingFriction = 1.0f;
btRigidBody* ballRigidBody = new btRigidBody(ballRigidBodyCI);
dynamicsWorld->addRigidBody(ballRigidBody);
//Without the next it doesn't bounce at all
//With it, it bounces just a TINY little bit
dynamicsWorld->getSolverInfo().m_splitImpulse = false;

OK, the above code should work in theory, but I'm not sure why it doesn't work.
As said, the property that regulates bounciness is m_restitution. This can be set in two ways. The first way is noted in the question-post. The other way is the following:
groundRigidBody->setRestitution(1.0);
ballRigidBody->setRestitution(1.0);
...and it works. Based on what I read on the net (e.g. here), both ways should be fine, but in my case it works only with the second way. I'm using bullet-2.82-r2704 on Ubuntu.
This happens only with the m_restitution property, All the other properties are set fine in the way of my question-post.
Plus, the line dynamicsWorld->getSolverInfo().m_splitImpulse = false; is not needed any more.

Related

Moving Object to another Objects position

Hey everyone so I am having some trouble trying to get this to work correctly. I have a MC Object called character and another called "points". I have a container object called planetContainer I add the character to the planetContainer the character is rotating around the planets that are also added to the container. The main issue I am having is when the points power up is activated I want the points to move off the other planets and to the charactercenter position. It was working perfect but had to update some code and remove the Points out of the planetContainer and attach them to the planets instead. I know I might have to use localToGlobal but not too sure.
Here is how I setup the character:
private function newCounterClockWise():void
{
planetContainer.addChild(character);
character.rotation = (Math.atan2(character.y - planetHit.y, character.x - planetHit.x) * 180 / Math.PI);
}
How the points are added to the Planets:
private function addPoints():void
{
points = new mcPoints();
var planetPosition:Point = planetContainer.parent.localToGlobal(new Point(0, 0));
points.x = planetPosition.x;
points.y = planetPosition.y;
outerPlanets.addChild(points);
aPointsArray.push(points);
}
Now this is the main function that handles the points to move to the character but it is not working correctly. The points move but they move off the screen or cause the game to kinda tweak out and do different things. Also the "magnetHandler(); is in my EnterFRame Event:
private function magnetHandler():void
{
for (var i:int = 0; i < aPointsArray.length; i++)
{
var currentPoints:mcPoints = aPointsArray[i];
var characterPosition:Point = planetContainer.parent.globalToLocal(new Point(character.x, character.y));
if (currentPoints.hitTestObject(playScreen.mcPointsHit))
{
trace("POINTS MID STAGE");
currentPoints.x -= (currentPoints.x - characterPosition.x);
currentPoints.y -= (currentPoints.y - characterPosition.y);
//currentPoints.x = character.x;
//currentPoints.y = character.y;
//TweenMax.to(currentPoints, 0.5, {x:characterGlobalPosition.x, y:characterGlobalPosition.y , ease:Power1.easeInOut } );
}
}
}
Can anyone see what I am doing wrong?
It's a hard to understand your question fully (or to understand why you're putting things that relate to each other in separate containers), but likely this line is where it's falling down:
var characterPosition:Point = planetContainer.parent.globalToLocal(new Point(character.x, character.y));
What you want to do, is get the characters x/y coordinates in the currentPoints parent space. To do that, you would do something like this:
//first, find the global position of character:
var globalCharacterPoint:Point = character.localToGlobal(new Point());
//then, convert that to the currentPoints parent local space:
var localCharacterPoint:Point = currentPoints.parent.globalToLocal(globalCharacterPoint);
Also, in this code of yours:
points = new mcPoints();
var planetPosition:Point = planetContainer.parent.localToGlobal(new Point(0, 0));
points.x = planetPosition.x;
points.y = planetPosition.y;
You are getting the global space of the planetContainer's parent, which is probably NOT what you want. You likely want:
planetContainer.localToGlobal(new Point()); //this gives you the global location of the planet container's top left corner
And, since you're adding the points object to outerPlanets, you probably want to convert to its local space (unless it's positioned at 0,0 globally - then it doesn't especially matter).
var outerPoint:Point = outerPlanets.globalToLocal(planetPosition);
points.x = outerPoint.x;
points.y = outerPoint.y;
Needless to say, for games it's best to have everything in the global coordinate space unless it's truly encapsulated assets (like smoke on a rocket etc.)

Away3D - shadows cast by DirectionalLight are off

I am implementing an Away3D 4.x app where I have some meshes that should cast shadows. I setup a DirectionalLight and a FilteredShadowMapMethod, then apply the method onto the materials. However, as you can see on the screenshot, the light as if ignores objects that are close to the ground (their Y position is small) and only casts shadows for objects that are above certain Y coordinate. You can see this nicely on the bricks on the right.
I don't understand what I am doing wrong, could someone please help? This is the main part of my code:
light1 = new DirectionalLight(0, -3, -5);
light1.ambient = 0.5;
light1.diffuse = 1.0;
light1.specular = 1.0;
lightPicker = new StaticLightPicker([light1]);
this.scene.addChild(light1);
shadowMapMethod = new FilteredShadowMapMethod(light1);
groundCloseMaterial = new TextureMaterial(Cast.bitmapTexture(GroundDiffuseClose));
groundCloseMaterial.lightPicker = lightPicker;
groundCloseMaterial.specular = 0;
groundCloseMaterial.ambient = 1;
groundCloseMaterial.shadowMethod = shadowMapMethod;
groundCloseMaterial.repeat = true;
groundCloseMaterial.mipmap = false;
groundClose = new Mesh(new PlaneGeometry(MAX_WORLD_X*2, MAX_WORLD_Z*2), groundCloseMaterial);
groundClose.geometry.scaleUV(20, 20);
groundClose.y = 0.1;
//-- create bricks
greyBrickMaterial = new TextureMaterial(Cast.bitmapTexture(BrickDiffuse));
greyBrickMaterial.specularMap = Cast.bitmapTexture(BrickSpecular);
greyBrickMaterial.normalMap = Cast.bitmapTexture(BrickNormals);
greyBrickMaterial.lightPicker = lightPicker;
greyBrickMaterial.mipmap = false;
greyBrickMaterial.specular = 1;
greyBrickMaterial.ambient = 1;
greyBrickMaterial.shadowMethod = shadowMapMethod;
Bricks are created as just CubeMeshes with the brick material. Similarly, the are some SphereMeshes with their own material, that is created the same way as greyBrickMaterial, flying around and one huge CubeMesh in the distance.
Notice also the weird light effect on the big brown cube - that kind of lighting just doesn't make sense!
Ok with a help of a community member on Away3d forums, I found a solution.
In short, the light's position values should be < 1.0 to prevent strong reflections on some surfaces:
light1 = new DirectionalLight(0., -0.7, -0.7);
Secondly, playing with the .epsilon attribute of the shadowMapMethod helps bring the shadows to start from where they should, rather than to be offset:
shadowMapMethod = new FilteredShadowMapMethod(light1);
shadowMapMethod.epsilon = 0.08;
Long answer here: http://away3d.com/forum/viewthread/5787/

AS3: Camera-Drag is jerking

I have a big problem because I need to move my camera by dragging the mouse (finger on mobile) to a position you want.
The code itself works fine but I have a bad jerking while dragging.
My Code:
if(_drag)
{
var mousePos:Point = new Point(_gameRef._stage.mouseX, _gameRef._stage.mouseY);
var localPos:Point = _gameRef.MainElement.globalToLocal(mousePos);
var diffX:Number = MathHelper.Difference(_prevMPosX, localPos.x);
var diffY:Number = MathHelper.Difference(_prevMPosY, localPos.y);
// Add the position changes for the camera
if(localPos.x < _prevMPosX)
_gameRef.CamController.x += diffX;
if(localPos.x > _prevMPosX)
_gameRef.CamController.x -= diffX;
if(localPos.y < _prevMPosY)
_gameRef.CamController.y += diffY;
if(localPos.y > _prevMPosY)
_gameRef.CamController.y -= diffY;
// change the previous mouse position to the current
_prevMPosX = localPos.x;
_prevMPosY = localPos.y;
e.updateAfterEvent();
}
The funny thing is that when I change the + to - and opposite then it works without jerking (but it doesn't feel natural so it's not the solution to my problem).
Thanks a lot!
Alright, the fault was to use the local coordinates.
No I've made every dependency from my global stage coordinates and it works without any jerking!

How to make a movieclip appear and reappear in the same location?

Well, I'm working on a shooting game in which I have to click enemies to make two counters count the number of hits I get. In this case the enemies are ghosts and I tried making some kind of animation when they are shot so the animation replaces them after I click on them.
However I can't seem to make them reappear again in the same location, it's a very simple drawing made with the shape and drawing tools of Flash CS5.
The code I use in this case for the shooting part is this one:
function disparar (event:MouseEvent):void{
contar +=1;
disparos.text = contar.toString();
var destino1:Boolean = this.mira.hitTestObject(this.FRojo)
if (destino1 == true){
cuenta +=1;
aciertos.text = cuenta.toString();
this.FRojo.visible = false;
colorante.color = 0xFF0000;
this.bang.transform.colorTransform = colorante;
this.bang.x = this.FRojo.x;
this.bang.y = this.FRojo.y;
this.bang.scaleX = this.FRojo.scaleX;
this.bang.scaleY = this.FRojo.scaleY;
this.bang.play();
this.FRojo.visible = true;
}
In fact you can see the whole file in here, it's very simple, but I can't seem to make the movieclip either disappear and reappear or make the animation that follows reappear each time I hit one of the ghosts. Could anyone help me with this? I'd really appreciate the help.
You're hiding the movie clip by setting this.FRojo.visible = false; and then setting it back to true pretty much right after so it never hides.
Try replacing this.FRojo.visible = true;
with
setTimeout(function(){FRojo.visible = true;}, 1000);
That will make it reappear after 1 second (1000 milliseconds).
So remove this and make sure each one is FRojo, FAzul and FMorado.
If you use a tweening library like greensock you can do some cool fades rather than it just reappearing.
EDIT
You have another error inside your BANG movie clip. On frame 10 replace
this.bang.x = 50;
this.bang.y = 10;
this.bang.scaleX = 1;
this.bang.scaleY = 1;
with
this.x = 50;
this.y = 10;
this.scaleX = 1;
this.scaleY = 1;

Flex-AS3 weired issue with Point

I was trying to convert global coordinates to local coordinates of a UIComplenent in my flex project using below code using below code
var gp:Point = new Point(e.stageX,e.stageY); //global point
var lp:Point = uic.globalToLocal(gp); //local point
uic is UIComponent in which I have subclass of Sprite for drawing something
I have set the sprite's mouseEnabled and mouseChildren to false to not interrupt the mouse event.
above code is within uic's mousemove event where I was tracing the gp and lp gp was giving correct value and suprisingly lp was giving negetive values. when I move the move to the top left corner of uic i expect lp to be 0,0 but it is giving the -width of of uic. I broke my head for hours and ended up finding an alternate by using offsets. Infact my original code was much simpler like this which was same issue
var lp:Point = new Point(e.localX,e.localY);
I am not sure what exactly is causing this problem. the workaround had lot of issues and it creating a mess in my rest of the algorithms.
Just now I found even more interesting thing (which is actually weird). for some reason I went and create a new lp2
var lp2:Point = new Point(e.localX,e.localY);
now surprisingly it was giving correct values as expected and I went back and changed the code as
var gp:Point = new Point(e.stageX,e.stageY); //global point
var lp:Point = uic.globalToLocal(gp); //local point
var lp2:Point = new Point(e.localX,e.localY);
var lp2:Point = uic.globalToLocal(gp);
now it is expected to have all the lp, lp2 and lp3 variables to be same but weiredly lp two is giving wrong value and lp2 and lp3 were giving correct. I am suspecting using the variable lp has something to do. I am not sure about that but above proves it so right now I am using lp2.
does any one know why is this behavior? is it a bug? or am I overseen something?
Admittedly, I didn't look at your previous questions before leaving my comment :) I take it your questions seem to leave people quite perplex... It's probably due to the way you present them as totally abstract behaviors.
Taking the example above, I'm not sure you're going the right way about the globalToLocal method.
My understanding of globalToLocal is that given a Point and a DisplayObject, globalToLocal will return the position of the Point in relation to the DisplayObject.
var pt:Point = new Point ( 10, 20 ); // x, y in relation to the Stage
var shape:Shape = new Shape();
shape.x = 10;
shape.y = 30;
// x, y should trace 0 , 10 , which is the position of the
//point in relation to shape.
pt = shape.globalToLocal(pt );
//or if you prefer to declare a new variable
var pointToShape:Point = shape.globalToLocal(pt );
In your example you state that you're trying to get the local coordinates of uic , your UIComponent , when in fact you're only returning the values of your Mouse position in relation to uic. Then you state:
"now it is expected to have all the lp, lp2 and lp3 variables to be the same "
No , because you keep redeclaring your variables:
var lp2:Point = new Point(e.localX,e.localY);
//the next declaration/statement cancels the previous one
var lp2:Point = uic.globalToLocal(gp);
Please note that once a variable has been declared , it is not necessary to redeclare it in subsequent statements. In the example above , there's no relationships between the two lp2 declaration, you may as well write:
var x:int = 10;
x = 20;
x = whatever;// each statement practically cancels the previous one.