Me and my freind are trying to create a game engine to make a ringtoss simulator using bullet physic on VS C++. Everything goes quite well until we need some way to determite the score (detect if the ring was put inside the pole). For the ring I use btCompoundShape with 36 little Shpere, here is the code:
btRigidBody* SceneManager::AddRing(float rad, float thick, float x, float y, float z, float mass)
{
btTransform t;
btCompoundShape *comShape = new btCompoundShape;
btSphereShape* sphere = new btSphereShape(thick / 2.0);
//sphere->setUserIndex(8);
float masses[36];
for (int i = 0; i < 36; i++)
{
t.setIdentity();
t.setOrigin(btVector3((rad - thick / 2.0)*sin(3.14159265359 / 180.0 * 10 * i), 0, (rad - thick / 2.0)*cos(3.14159265359 / 180.0 * 10 * i)));
comShape->addChildShape(t, sphere);
//comShape->addChildShape(t, box);
masses[i] = mass / 36;
}
btVector3 inertia(0, 0, 0);
t.setIdentity();
comShape->calculatePrincipalAxisTransform(masses, t, inertia);
t.setIdentity();
t.setOrigin(btVector3(x, y, z));
btMotionState* motion = new btDefaultMotionState(t);
btRigidBody::btRigidBodyConstructionInfo info(mass, motion, comShape, inertia);
btRigidBody* body = new btRigidBody(info);
sceneWorld->addRigidBody(body);
vRigidBody.push_back(body);
return body;
}
Anyhow, I have try three diffrent way to check the goal:
I use callBackFunc and body->setUserIndex(int i), however for this method, the ring only need to touch the pole to count as goal.
I check the position of the center of the ring to the pole, this way work but sometime when the ring get to close to the pole or stand sideway to it, it also count.
I check 4 point on the ring like the 4 direction on the compase relative to the position of the pole, this suffer the same result as above.
I am new to bullet Physic, if any adept out there who could help I would really appreciate it.
Related
Hello I'm trying to make a billiards game using libgdx. I'm using 3d models for the balls and an Orthographic Camera to view them. I am having trouble getting them to roll correctly after rolling on a different axis. Here is a clip of what they look like when they're rolling.
As you can see they appear to be rotating as if they were on their starting axis. Is there any way to rotate it so that it looks like it's actually rolling. I am also not very familiar with transformation matrices or quaternions so im not too sure where to go.
Edit: Updated for clarity
Here is the code I use to update the rotation
public boolean update() {
if (!visible) {
return false;
}
Vector2 vBall = ballBody.getLinearVelocity();
float vAngle = ballBody.getAngularVelocity();
isMoving = true;
float x = ballBody.getPosition().x * SCALE;
float y = ballBody.getPosition().y * SCALE;
Vector2 axisInPlane = new Vector2(y - center.y, x - center.x).rotateRad(Math.PI/2f);
Vector3 axis3D = new Vector3(axisInPlane.x,axisInPlane.y,0f);
ball3D.transform.rotate(axis, (float) Math.toDegrees(dist / RADIUS_PX));
ball3D.transform.setTranslation(mapX(x), mapY(y), 0);
Just to be sure, center is an arbitrary fixed point where there is no rotation and all rotations are derived from this distance/angle as the ball has no slippage.
So you can directly get the axis with
Vector2 axisInPlane = new Vector2(y - center.y, x - center.x).rotateRad(Math.PI/2f);
Vector3 axis3D = new Vector3(axisInPlane.x,axisInPlane.y,0f);
Also Math.toDegree takes radians as an argument, not a float, so dist/RADIUS_PX will be off, you have to supply as a fraction of 2PI (360 degs in radians). Also this should be the circumference of the ball not the radius. I don't know what class ball3D is but I would check that ball3D.transform.rotate does take degrees as an argument and if it does replace that line with
float rotateRadians =(float) Math.toDegrees((dist/CIRCUMFERENCE_PX)*Math.PI*2f);
ball3D.transform.rotate(axis, rotateRadians );
This video will show my current situation, and I currently can't find any answers to it online.
https://www.youtube.com/watch?v=O8Mh-1Emoc8&feature=youtu.be
My Code:
public Vector3D pickBlock() {
glDisable(GL_TEXTURE);
IntBuffer viewport = BufferUtils.createIntBuffer(16);
FloatBuffer modelview = BufferUtils.createFloatBuffer(16);
FloatBuffer projection = BufferUtils.createFloatBuffer(16);
FloatBuffer winZ = BufferUtils.createFloatBuffer(1);
float winX, winY;
FloatBuffer position = BufferUtils.createFloatBuffer(3);
glGetFloat(GL_MODELVIEW_MATRIX, modelview);
glGetFloat(GL_PROJECTION_MATRIX, projection);
glGetInteger(GL_VIEWPORT, viewport);
winX = (float)Display.getWidth() / 2;
winY = (float)viewport.get(3) - (float)Display.getHeight() / 2;
glReadPixels(Display.getWidth() / 2, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, winZ);
gluUnProject(winX, winY, winZ.get(), modelview, projection, viewport, position);
glEnable(GL_TEXTURE);
return new Vector3D(position.get(0) / 2 + 0.5f, position.get(1) / 2 + 0.5f, position.get(2) / 2 + 0.5f);
}
It returns "/ 2 + 0.5f" because that is needed because of the offsets I have for the blocks (if I removed the 0.5f, the offset would be in the center instead of the corner)
I seams to me that the error, based on the video, comes from when you are facing in the positive z direction (or whatever your back direction is). My guess is that you aren't taking the facing direction into account as I see in your code that you are just adding a constant 0.5F to the position of your cursor.
Therfore, when you are facing backwards, it adds 0.5 which makes it be behind the wall (since back is negative Z). one simple check would be weather the Z component of your forward vector is positive or negative, and deciding the factor added to the cursor based on that, then doing the same for the X.
Depending on how you implemented your camera (IE: if you used Euler angles (rx, ry, rz) or if you used Quaternions / forward vectors), the way you would do that check would vary, feel free to ask me for examples based on your system if you need.
hope this helped!
PS: if you're using angles, you can either check for the range of the y-axis rotation value and determine which direction you are facing and thus weather to add or subtract, OR you can calculate the forward vector based on your angles, and then check the for sign of the component.
I'm working on a new game written with LibGdx Engine and Java.
I've got a problem with some of the physics in this game.
I want to shoot the arrow in a ballistic trajectory (angry bird style)
and can't find the equation to do so .
I am using these velocity equations:
float velx = (float) (Math.cos(rotation) * spd);
float vely = (float) (Math.sin(rotation) * spd);
I add this to the current position and the arrow shoots in one direction - straight.
I thought maybe changing the rotation would help me achieve what I want (a ballistic path).
It does help, but I want to have the trajectory as well.
I saw this
ProjectileEquation class that someone already posted but didn't know how to work with it:
public class ProjectileEquation
{
public float gravity;
public Vector2 startVelocity = new Vector2();
public Vector2 startPoint = new Vector2();
public Vector2 gravityVec = new Vector2(0,-10f);
public float getX(float n) {
return startVelocity.x * (n ) + startPoint.x;
}
public float getY(float n) {
float t = n;
return 0.5f * gravity * t * t + startVelocity.y * t + startPoint.y;
}
}
I'm looking for some help to help me use this class for ballistic trajectories.
This is how I tried using it:
for(int i =0;i<30;i++)
{
Texture f = ResData.Square_1;
ProjectileEquation e= new ProjectileEquation();
e.gravity = 1;
e.startPoint = new Vector2(bow.getX(),bow.getY());//new Vector2(-bow.getX(),-bow.getY()); //My bow is opposite so it suppose to work fine
e.startVelocity = getVelocityOf(bow.getRotation());
Vector3 touchpos = new Vector3();
s.draw(f,e.getX(i) ,e.getX(i),5,5);
}
The ProjectileEquation class you post looks like it'll calculate the X and Y position given a time delta, so the float you pass in should be the time delta since you started the arrow moving (in seconds).
That code will not give you the angle of the arrow though. To find that, I would suggest you keep hold of the previous X and Y, then you can use Math.atan2() to calculate the angle based on the previous XY and the current XY. Google atan2 for a load of info on how to use it.
The very best way to do this however would be to use Box2d and model the scene correctly. Then you wouldn't have to get involved in the maths at all. I read somewhere that that's what Angry Birds uses, and is an excellent choice for modelling these sorts of physics games.
I hope your game goes well.
I'm trying to develop heat map, now initially I would have to draw the intensity mask, and since I'm using GWT so I have randomly generated some coordinates and placed my circles ( with required gradience ) at those locations so the output comes out to be circles overlapping each other. And If I look at the intensity mask from Dylan Vester, it comes to be very smooth How can I draw my heat map ?? Also how the output is achieved similar to Dylan Vester?? Question also is if I'm drawing circles then how to decide the intensity at the intersection of two or more circles, how they have achieved ?? Here is my code
// creating the object for the heat points
Heat_Point x = new Heat_Point();
// Variables for random locations
int Min = 1,Max = 300;
int randomx,randomy;
// Generating set of random values
for( int i = 0 ; i < 100 ; i++ ) {
// Generating random x and y coordinates
randomx = Min + (int)(Math.random() * ((Max - Min) + 1));
randomy = Min + (int)(Math.random() * ((Max - Min) + 1));
// Drawing the heat points at generated locations
x.Draw_Heatpoint(c1, randomx, randomy);
}
And Here is how I'm plotting my heat point that is Heat_Point class
Context con1 = c1.getContext2d(); // c1 is my canvas
CanvasGradient x1;
x1 = ((Context2d) con1).createRadialGradient(x,y,10,x,y,20);
x1.addColorStop(0,"black");
x1.addColorStop(1,"white");
((Context2d) con1).beginPath();
((Context2d) con1).setFillStyle(x1);
((Context2d) con1).arc(x,y,20, 0, Math.PI * 2.0, true);
((Context2d) con1).fill();
((Context2d) con1).closePath();`
here I was supposed to add some images but I didn't have enough reputation :D :P
I took a quick look at HeatmapJS (http://www.patrick-wied.at/static/heatmapjs/) and it seems he uses radial gradients (like you have above) and he also uses opacity and a color filter called "multiply blend" to smooth out the intensity of the colors in the heat map.
His code is quite impressive. It's open source, so you might want to check it out!
So I have a circle of planes which get constructed as:
plane.x = Math.cos(angle) * radius;
plane.z = Math.sin(angle) * radius;
plane.rotationY = (-360 / numItems) * i - 90;
which calculates how many angular slices there are for total number of planes (rotationY) and places each plane into it's place on a circle of radius.
then to update their rotation around the circle I have:
var rotateTo:Number = (-360 / numItems) * currentItem + 90;
TweenLite.to(planesHolder, 1, { rotationY:rotateTo, ease:Quint.easeInOut } );
as you can see planes are circling and each is oriented 90 degrees out from the circle.
I'm using this as a reference - it's pretty much that: http://papervision2.com/a-simple-papervision-carousel/
Now, what I'd like to find out is how could I calculate degree of orientation for each individual plane to always face camera without normal, if it's possible at all. I've tried plane.LookAt(camera), but that doesn't work. Basically every plane should have orientation as the one facing camera in the middle.
Somehow I think I can't modify that example from link to do that.
edit: OK I answered my own question after I wrote it. Helps to read your own thoughts written. So as I'm orienting planes individually and rotating them all as a group, what I did after tween of the group in code above, was to loop through each plane and orient it to the Y orientation of the forward plane as so:
for (var i:int = 0; i < planes.length; i++) {
TweenLite.to(planes[i], 1, { rotationY:(-360 / numItems * rotoItem - 90), ease:Quint.easeInOut } );
}
rotoItem is the one at the front. Case closed.
OK I answered my own question after I wrote it. Helps to read your own thoughts written. So as I'm orienting planes individually and rotating them all as a group, what I did after tween of the group in code above, was to loop through each plane and orient it to the Y orientation of the forward plane as so:
for (var i:int = 0; i < planes.length; i++) {
TweenLite.to(planes[i], 1, { rotationY:(-360 / numItems * rotoItem - 90), ease:Quint.easeInOut } );
}
rotoItem is the one at the front. Case closed.