How to add camera damping? - c++

I asked a question about how to add camera damping in Ogre but didnt get any answer so here is a more vague question.
How would you add camera damping?
I googled this question and got answers in XNA and Unity and each is different than the other so I cant even figure out what technique, function or maths they are using.
I have a camera and its position, I have an object and the position where I want the camera to be and slowly move it to that position, how can I do this?
I tried using lerp but it didnt work, I dont know if that is the wrong way of doing it or my lerp function might be wrong so I dont know.
Can someone please help me out. Thanks

Here is my lerp function
Ogre::Vector3 lerp (Ogre::Vector3 &sourceLocation, Ogre::Vector3 &destLocation, Ogre::Real Time)
{
return sourceLocation+ (destLocation - sourceLocation) * Time;
}
in cpp file
this->camPos = this->lerp(this->camPos, this->playerNode->getSceneNode()->getPosition() + Ogre::Vector3(0,60,-100), 1000.0f);
this->getCamera()->setPosition(this->camPos);
but the camera just ends up miles away from the object

Thanks for answering Peter. Makes a bit more sense now, the lerp function is just returning a long vector since the time is constant however Im not sure about the second part.
I need to have a variable that increments with the frame?
Ogre::Real frametime += frame_event.timeSinceLastFrame * 0.01;
this->camPos = this->lerp(this->camPos, this->playerNode->getSceneNode()->getPosition() + Ogre::Vector3(0,60,-100), frametime);
this does slowly move the camera towards the target and then stop but since the frametime is increasing, the time it takes to get to the target destination gets quicker as well. do I just set the frametime to 0 when it reaches destination?
can you please explain a bit more about the second part. I would really really appreciate your help.
Thanks

Your calculation for lerp is the issue, your getting the vector between dest and source and massively scaling it up.
Your lerp time should not be constant, it should be scaling from 0 to 1 based on the time period you want to go from source to dest.
Before moving:
float length= (dest -start).Length();
Update ()
float distancedTravelled = (CurrentTime - StartTime) * cameraSpeed;
float lerp = distanceTravelled /length;
Pass lerp to function.
Faster camera speed is the quicker you go

Related

Scalable Ambient Obscurance rendering issue

I am trying to implement this SAO algorithm.
I am getting the following result :
I can't figure out why I have the nose on top of the walls, it seems to be a z-buffer issue.
Here are my input values :
const float projScale = 100.0;
const float radius = 0.9;
const float bias = 0.0005;
const float intensityDivR6 = pow(radius, 6);
I am using the original shader without modifications, except that I disable the usage of mipmaps of the depth buffer.
My depth buffer (on different scene, sorry) :
It should be an issue with the zbuffer linearization or it's not between -1 and 1.
Thank you Bruno, I finally figure out what were the issues.
The first was that I didn't transform my Z correctly, they use a specific pre-pass to make the Z linear and put it between -1 and 1. I was using an incompatible method to do it.
I also had to negate my near and far planes values directly in the projection matrix to compute correctly some uniforms.
Result :
I had a similar problem, having visual wrong occlusion, linked to the near/far, so I decided to give you what I've done to fix it.
The problem I had is discribed in a previous comment. I was getting self occlusion, when the camera was close to an object or when the radius was really too big.
If you take a closer look at the conversion from depth buffer value to camera-space value (the reconstructCSZ function from the g3d engine), you will see that replacing the depth by 0 will give you the near plane if you work with positive near/far. So, what it means is that every time you will get a tap outside the model, you will get a z component equals to near, which will give you wrong occlusion for fragments having a z close to 0.
You basically have to discard each taps that are located on the near plane, to avoid them being taken into account when comptuing the full contribution.

Lerping issue with timers

I have been having an issue related to timers when I am lerping objects in my game engine. The lerping is almost correct and when I am applying the lerping to an object moving or rotating it is fine except every few seconds it appears as if the object quickly flashes to it's previous position before continuing to move smoothly.
Running the engine in windowed mode gives me 1500~fps but if I run in full screen with vsync clamping to 60fps the glitch happens a lot more often.
I have been trying to find either a good resource or explanation on lerping and how I can improve what I have.
For working out the tick gap I use:
float World::GetTickGap()
{
float gap = (float) (TimeMs() - m_lastTick) / m_tickDelay;
return gap > 1.f ? 1.f : gap;
}
My update function:
m_currentTick = TimeMs();
if(m_currentTick > m_lastTick+m_tickDelay)
{
m_lastTick = m_currentTick;
//Update actors
}
Then when rendering each actor I am giving the tick gap for them to lerp between their positions.
My lerping function:
float math::Lerp(float a, float b, float t)
{
return a + t*(b-a);
}
And an example of the lerping function being called:
renderPosition.x = (math::Lerp(m_LastPosition.x, m_Position.x, tickDelay));
I'm unsure where to start on trying to fix this problem. As far as I'm aware it is the timing issues with the functions. Though could anything else cause a small dip in performance at a constant rate?
Any help with this problem would be greatly appreciated. :)
I'm not really able to reconstruct your code from what you posted
But I remember that calling your time function more than once per frame is bad idea generally.
You seem to do that. Try thinking about what effect that has.
E.g. It might mean that the "update Actors" loops are out of sync with the "tickGap" intervals and actors are updated a second time with 0 gap.

Scaling objects from a center point by a specific number

I'm not sure if doing something wrong in my program or not but I could use some quick guidance if you could and more than likely the problem is I'm thinking to hard about it (which is always the case for me) and I can't think of the way to explain it (hence the crappy title of this question) and gave me a little trouble simply Googling for help.
I'm aware of how to scale an object by way of:
double scale = 2.0;
Array<Real2> newPoints;
Foreach(Real2 point, points)
{
Vector2 vector = point - centerPoint;
vector *= scale;
newPoints.Add(center + vector);
}
However let's say I wanted to scale the size of the object by 3.6(units) instead of by a percentage.. How would I go about that?
It made sense to me at least that I would do something along the lines of
vector *= 1 - (3.6/vector.length);
but I'm still getting incorrect results running my application. Any help on this issue? Like I said sorry if I explained this incorrectly, I'm horrible when it comes to that stuff so if there's anyway i can clarify let me know. Thank you for your help.
It seems that you want to scale the object so that it's new size is (say) 3.6 units larger than it's old size. In that case, the code would be the same except for
scale = (old_size + 3.6) / old_size;
You still need to scale each vector by the same amount, in order to preserve the overall shape of the object.

How can my sprite body will jump and come back to original place in box2d

How can my sprite will jump and come back to original place??
I am using box2d physics engine in iphone apps.
I am using impulse but cant work properly.
Is any one know the logic or code than tell me.
-(void)jump
{
b2Vec2 pos=ballbody->GetPosition();
// float vel=ballbody->GetAngularVelocity();
double radian=atan2(pos.x+10, pos.y+10);
float angle=CC_RADIANS_TO_DEGREES(radian);
NSLog(#"Angle: %f",angle);
float impulseFactor = 1.0;
float force=ballbody->GetMass()*10;
//force/=6.0;
//b2Vec2 force=b2Vec2(0,50.0f);
// float apply=force*JUMP_IMPULSE*impulseFactor;
ballbody->ApplyLinearImpulse(b2Vec2(angle,force), ballbody->GetWorldCenter());
// [self applyLinearImpulse:b2Vec2(0,[self mass]*JUMP_IMPULSE*impulseFactor) point:[self worldCenter]];
}
Thanks
please check whether gravity has been set
if not set gravity upon the particular angle you have put the force.
third case is note down that position... get the current position... get angle.... set linear velocity to that angle.... keep on checking the position and as soon as it reaches that position set linear velocity zero..... (this sounds confusing but i didn't understood your problem fully so as much as i did understood i can help only this much)

Inverse Interpolation with angles greater than Pi?

I'm making an API for skeletal animation. Right now it works fine, except Lets say you want to go from 2.0f to 1.0f. It will end up doing almost a full circle when it should only do about 1/6th of one.
I think I've got a way to find it it should go counter clockwise but I'm not sure how to use it with this:
bool CCW = fmod( (endKeyFrame->getAngle() -
startKeyFrame->getAngle() + TWO_PI), TWO_PI) > 3.141592;
remainingInterpolationFrames = endKeyFrame->getFrame() - startKeyFrame->getFrame();
//Linear interpolation
curIncreaseAngle = (endKeyFrame->getAngle() -
startKeyFrame->getAngle()) / remainingInterpolationFrames;
Thanks
I think this may help. Especially sections 8,9 and 30.