Libgdx arcball camera and billboard - libgdx

I just implemented an arcball cam in libgdx
private void rotate(float pitch, float yaw, float roll) {
tempQuat.setEulerAngles(pitch, yaw, roll);
rotationQuat.mulLeft(tempQuat);
}
...
float aspect = camera.viewportWidth / camera.viewportHeight;
camera.projection.setToProjection(Math.abs(camera.near), Math.abs(camera.far), camera.fieldOfView, aspect);
camera.view.setToLookAt(camera.position, tempVector.set(camera.position).add(camera.direction), camera.up);
rotate(MyGestureListener.mXAngle, MyGestureListener.mYAngle, 0);
camera.view.rotate(rotationQuat);
camera.combined.set(camera.projection);
Matrix4.mul(camera.combined.val, camera.view.val);
camera.invProjectionView.set(camera.combined);
Matrix4.inv(camera.invProjectionView.val);
camera.frustum.update(camera.invProjectionView);
Everything works fine, but one thing is not good:
I have some decal that always rotated to the camera as a billboard:
p.decalPoint.setPosition(p.pos.x, p.pos.y, p.pos.z);
p.decalPoint.setRotation(camera.direction, camera.up);
Now this is broken. Why? How can I fix this?
I need an arcball camera like here:
https://youtu.be/YxNjjyv8W0I
The above code works well, but billboarding not working with the cam.

You are bypassing the camera and manually updating the matrices and frustum members, but forgot to update the other members. So you'll have to either update the other members (like position, direction and up) as well, or instead use the functionality the camera provides:
The call to camera.projection.setToProjection is not needed.
The call to camera.view.setToLookAt is not needed.
The call to camera.view.rotate would be camera.rotate.
The call to camera.combined.set and Matrix4.mul is not needed.
The call to camera.invProjectionView.set and Matrix4.inv is not needed.
The call to camera.frustum.update is not needed.
Add a call to camera.update();
See also http://www.badlogicgames.com/wordpress/?p=1550 for more info.

I ended up using two rotation matrix and a camfocusvector as an arcball
Quaternions are not suitable for this

Related

move dynamic body object in box2d when touchbegin

I am creating a game like bounce ball using box2d in cocos2d-x. I created a dynamic body object and i want it to move when touch began. I am using the following code to move the dynamic body but it is not moving. Please anyone could help me to solve the problem.
bullet2=CCSprite::create("block.png");
bullet2->setPosition(ccp(2740, 1220));
this->addChild(bullet2,0);
ballBodyDefB.type=b2_dynamicBody;
ballBodyDefB.position.Set(2740/PTM_RATIO, 1170/PTM_RATIO);
ballBodyDefB.userData=bullet2;
ballBodyDefB.gravityScale=0;
_bullet=_world->CreateBody(&ballBodyDefB);
b2PolygonShape bulletshape;
bulletshape.SetAsBox(bullet2->getContentSize().width/PTM_RATIO/2,
bullet2->getContentSize().height/PTM_RATIO/2);
b2FixtureDef b_bullet ;
b_bullet.shape = &bulletshape;
b_bullet.density = 1.0f;
b_bullet.friction = 0.1f;
b_bullet.restitution = 0.0;
_bullet->CreateFixture(&b_bullet);
CCTouchbegan:
b2Vec2 force = b2Vec2(0, -450);
_block->ApplyLinearImpulse(force, _block->GetPosition());
Hi moving the sprite which follow b2body is easy. You need to attach Sprite to the b2body.userData and in box2d world step synchronize the position and rotation of your sprite with your b2body.
I can't answer directly your question, please post your code and what version of cocos2d-x you have for more details:
Check if your code contain code about: (depend on cocos2d-x version, you use CCSprite which is deprecated in 3.2, we use Sprite only anyway)
box2d world (you already have _world)
_world step iteration
syncing sprite position with b2body
Anyway you can find more details at these links:
http://www.cocos2d-x.org/wiki/Box2D and http://www.cocos2d-x.org/wiki/Getting_Started_with_Cocos2d-x

Box2d MovieClip to original position

I want to try a simple task where if i move a object inside the world and then press a button it should go back to its original position , but its not working , below is the code i am using - the file is here - http://www.fastswf.com/yAnIvBs (when i remove the event listener)
with event listener - http://www.fastswf.com/rpYsIt8
////////========================
stop();
var startXPos:Number = level1WorldObj.box1.x;
var startYPos:Number = level1WorldObj.box1.y;
function areaS(e:Event) {
level1WorldObj.box1.y= startYPos;
level1WorldObj.box1.x= startXPos;
level1WorldObj.box1.removeEventListener(Event.ENTER_FRAME, areaS);
}
but1.addEventListener(MouseEvent.CLICK,nClick3);
function nClick3(event:MouseEvent):void{
level1WorldObj.box1.addEventListener(Event.ENTER_FRAME, areaS);
level1WorldObj.box1.y= startYPos;
level1WorldObj.box1.x= startXPos;
}
/////////////////======================
Now i want to be able to do it many time so i kept the variables that detect the initial x, y as global ...
Here you can see how it behaves in debugdraw mode , strangely only the clip moves not the actual body - http://www.fastswf.com/-Ijkta4
Can some one please guide me here ...
Thanks in advance ...
Jin
The graphics that you see (box1) aren't related to the physical object behind the scenes - you're currently only moving the graphics not the object itself.
You need to use either SetPosition() or SetTransform() on the b2Body of the object
Edit 07/7
As you're using the Box2D World Construction Kit, I took a look at the source code (available here: https://github.com/jesses/wck). The main class seems to be BodyShape (https://raw.githubusercontent.com/jesses/wck/master/wck/BodyShape.as).
Looking through it, you should be able to access the b2Body directly. If it's null (which is probably the source of the TypeError that you're getting, then you haven't called createBody(), which is what actually takes all of your properties as creates the physical object behind the scenes.
Once you have a b2Body, if you want to position it based on the graphics, there's a function syncTransform() to do just that.
You should turn on debugDraw on your World class to make it easier to see what's going on in the background. NOTE: this needs to be done before calling create()
I was able to find solution to this problem , i found the starting point by using this -
trace(level1WorldObj.box1.b2body.GetPosition().x);
trace(level1WorldObj.box1.b2body.GetPosition().y);
then once i had the position manually i took down the coordinates and used the below code ....
level1WorldObj.box1.b2body.SetTransform(new V2(-2, 2),0 );
Thanks #divillysausages for all the help ...
Regards

Infinite duration for libGDX particle emitter

I've been trying to make some fire particle emitter with libGDX.
I downloaded an example (http://pastebin.com/cNWs0tt1#). It looks fine, but it eventually ends (the fire extinguishes) and then starts over. I see in the file that is says the duration is 60000ms. So they relied on putting a high number.
Well, that's lame. I tried putting a duration of 0, which of course doesn't work as it just keeps on dying over and over.
So how can I make a particle emitter with unlimited duration?
You can set the continous-flag to true, the effect will start over and over again.
In the editor:
Or in the source-file:
- Options -
attached: false
continuous: true <----------------------------
aligned: false
additive: true
behind: false
I found a simple workaround for what you are trying to accomplish.
effect.findEmitter("youremitter").durationTimer = 0;
If you call this each time the effect is being rendered, you can reset each emitter to it's starting duration timer. I have tested it and it seems to work very nicely.
Do note however that you need to call this line for each one of your emitters. For example, if you have a rocket ship with a flame/smoke particle effect, you should do this.
public void render(float delta) {
effect.findEmitter("fire").durationTimer = 0;
effect.findEmitter("smoke").durationTimer = 0;
// Render your particle effect here
}
I hope this helps, good luck!

cocos2dx/coco2d layer transition

I hope to pop down a score panel when players win and pass the gate.
Normally it will pop down score board.
I think the best way is to use layer and pull down it.
But I only get the transition of scene, just wonder is there any way for layer transition?
Did not see an equivalent of CCTransitionScene :CCScene for CCLayer but layers can runActions using which we can bring out most of the animations/transitions.
Here is what I do in such situations but I guess you are thinking of the same thing. Nevertheless,
1.Create a layer and add it as a child at a position outside of your screen frame.
2.Then use CCMoveTo to move it to the desired location when you want to pull it down.
I have done something similar in the past.
Display your layer offscreen
i.e setposition(0, CCDirector::sharedDirector()->getWinSize().height*1.5f);
create an action to move it onscreen (I like to use CCEaseSineOut)
you can also use a callfunc to call a function when it has finished its animation
scoreLayer->runAction( CCSequence::create( CCEaseSineOut::create(CCMoveTo::create(1.0f, ccp(0, 0-_screenHeight*1.5f))), CCCallFunc::create(this, callfunc_selector(MainLayer::scorefinishedMove)), NULL));
Note: that function might need some fixes to ending brackets etc. And you may want to seperate out some of those actions rather than putting the initialization right in the runAction function
For layer transition you can do this:
CCScene* newScene = CCTransitionCrossFade::create(.5f,Layer2::scene());
CCDirector::sharedDirector()->pushScene(newScene);
In Layer2.cpp
CCScene* Layer2::scene()
{
CCScene* scene = CCScene::create();
CCLayer* layer = new Layer2();
scene->addChild(layer,1);
return scene;
}

How to replace bitmapData.copyPixels() with bitmapData.draw()

I'm trying to draw a level of my game using a tileset and a xml with the info. It works using copyPixels, but some tiles need to be flipped before they are drawn, so for that I need to use draw() instead of copyPixels(), but I can't get it to work. This is how I use copyPixes:
rectangleSelection = (desiredTile.x, desiredTile.y, tileWidth, tileHeight);
bmpData.copyPixels(tileset.bitmapData, rectangleSelection, new Point(pt.x, pt.y));
//pt.x and pt.y = tile location to be drawn().
How can I do the same thing using the bitmapData.draw() method? I just can't make it work.