Code: Select all
using System;
using Irrlicht;
using Irrlicht.Core;
using Irrlicht.Video;
using Irrlicht.Scene;
using ApocalypseS314;
using ApocalypseS314.ApoServer;
using System.Collections;
namespace ApocalypseS314.Graphic
{
public class ApoCamera
{
private ISceneNode m_pTargetNode;
private ICameraSceneNode m_camera;
private Vector3D lastTargetPos;
private const float m_maxSpeed = 4.5f;
private const float m_InitialSpeed = 0.2f;
private const float m_decal = 150.0f;
private float m_maxDistance;
private float m_minDistance;
private float m_height; //distance above object camera tries to float at
private float m_leash; //max distance object can be from camera before it moves
private float m_speed; //rate at which camera moves per Update() s
public ICameraSceneNode getCamera() { return m_camera; }
// class constructor
public ApoCamera(ISceneNode targetNode, ISceneManager smgr, ISceneNode node)
{
m_speed = m_InitialSpeed;
m_height = 110.0f;
m_leash = 100.0f;
m_maxDistance = 1000.0f;
m_minDistance = 800.0f;
//create a camera
lastTargetPos = targetNode.Position;
m_camera = smgr.AddCameraSceneNode(null, lastTargetPos + new Vector3D(0,150,150),lastTargetPos,-1);
m_camera.FarValue = 10000.0f;
m_pTargetNode = targetNode;
}
public void refreshCamera()
{
if(m_camera == null || m_pTargetNode == null) return;
Vector3D currTargetPos = m_pTargetNode.Position;
currTargetPos.X -= (float)( System.Math.Cos(m_pTargetNode.Rotation.Y * 3.14159265/180)*m_decal );
currTargetPos.Z += (float)( System.Math.Sin(m_pTargetNode.Rotation.Y * 3.14159265/180)*m_decal );
//if too far away, move camera closer
Vector3D camToTarg = currTargetPos - m_camera.Position ;
//leash is only in the X-Z plane, so only count distance using X and Z
Vector2D xzDist = new Vector2D( camToTarg.X, camToTarg.Z );
if(m_camera.Position.GetDistanceFromSQ(m_pTargetNode.Position) > m_maxDistance && m_speed < m_maxSpeed) // MaxDistance
{
m_speed += 0.2f;
}
else if(m_camera.Position.GetDistanceFromSQ(m_pTargetNode.Position) < m_minDistance && m_speed > m_InitialSpeed)
{
m_speed -= 0.2f;
}
if(xzDist.GetLengthSQ() > m_leash) { //need to move closer
camToTarg = new Vector3D( xzDist.X, 0, xzDist.Y);
camToTarg = camToTarg.Normalize() * m_speed;
//set X-Z position
m_camera.Position = m_camera.Position + camToTarg;
//set Y position
float h_tolerance = m_height / 10; //the ammount of leway given to how close we need to be to the right height
float h_delta = m_camera.Position.Y - currTargetPos.Y + m_height; //distance from prefered height position
if( m_camera.Position.Y < ( currTargetPos.Y + m_height) - h_tolerance)
{
m_camera.Position = new Vector3D( m_camera.Position.X, m_camera.Position.Y + h_delta/2, m_camera.Position.Z);
}
else if( m_camera.Position.Y > ( currTargetPos.Y + m_height) + h_tolerance )
{
m_camera.Position = new Vector3D( m_camera.Position.X,m_camera.Position.Y - h_delta/2, m_camera.Position.Z);
}
}
float H = 50.0f+(m_camera.Position.GetDistanceFromSQ(m_pTargetNode.Position)/1000.0f);
if(H > 230.0f)
H = 230.0f;
//if(m_camera.Target.GetDistanceFromSQ(m_pTargetNode.Position) > 250.0f)
// return;
m_camera.Target = m_pTargetNode.Position + new Vector3D(0,H,0);//look at Target position
lastTargetPos = currTargetPos;
}
}
}
I hope that can help someone.
There is a litte bug, the camera "jump" some time... i don't now why.
If somebody have a idea