mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-05 14:47:22 +08:00
199 lines
6.6 KiB
C#
199 lines
6.6 KiB
C#
using CodeWalker.GameFiles;
|
|
using SharpDX;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace CodeWalker.World
|
|
{
|
|
public class Entity
|
|
{
|
|
public Space Space;
|
|
public YmapEntityDef EntityDef;
|
|
|
|
public float Radius;
|
|
public Vector3 Center;
|
|
public Vector3 Position;
|
|
public Quaternion Orientation = Quaternion.Identity;
|
|
public Quaternion OrientationInv = Quaternion.Identity;
|
|
|
|
public float Mass;
|
|
public Matrix MomentOfInertia;
|
|
public Vector3 Momentum;
|
|
public Vector3 Velocity;
|
|
public Vector3 AngularMomentum;
|
|
public Vector3 AngularVelocity;
|
|
|
|
public bool WasColliding;
|
|
|
|
public bool EnableCollisions;
|
|
public bool Enabled;
|
|
|
|
public float Lifetime;
|
|
public float Age;
|
|
|
|
//public CollisionShape ..
|
|
|
|
public virtual void PreUpdate(float elapsed)
|
|
{ }
|
|
|
|
}
|
|
|
|
|
|
|
|
public class PedEntity : Entity
|
|
{
|
|
|
|
public Vector2 ControlMovement;
|
|
public bool ControlJump;
|
|
public bool ControlBoost;
|
|
|
|
public Vector3 ForwardVec;
|
|
|
|
public Quaternion CameraOrientation = Quaternion.LookAtLH(Vector3.Zero, Vector3.Up, Vector3.ForwardLH);
|
|
public Entity CameraEntity = new Entity();
|
|
|
|
public bool OnGround = false;
|
|
|
|
|
|
public PedEntity()
|
|
{
|
|
Radius = 0.5f;
|
|
Center = new Vector3(0.0f, 0.0f, -1.2f); //base collision point is 1.7m below center... for camera offset
|
|
|
|
Mass = 80.0f;
|
|
|
|
ForwardVec = Vector3.UnitY;
|
|
CameraEntity.Orientation = CameraOrientation;
|
|
CameraEntity.OrientationInv = Quaternion.Invert(Orientation);
|
|
}
|
|
|
|
public override void PreUpdate(float elapsed)
|
|
{
|
|
|
|
//float rotspd = 0.5f;
|
|
float movspd = 10.0f;
|
|
float velspd = 10.0f;
|
|
float jmpvel = 3.0f;
|
|
float boostmult = 10.0f;
|
|
if (ControlBoost) movspd *= boostmult;
|
|
|
|
Quaternion rot = Quaternion.Identity;// .RotationAxis(Vector3.UnitZ, -ControlMovement.X * rotspd * elapsed);
|
|
Quaternion ori = Quaternion.Multiply(Orientation, rot);
|
|
SetOrientation(ori);
|
|
|
|
|
|
float jmpamt = (ControlJump ? jmpvel : 0);
|
|
Vector3 curvel = Velocity;
|
|
Vector3 controlvel = new Vector3(ControlMovement * movspd, jmpamt);
|
|
Vector3 targetvel = controlvel + new Vector3(0, 0, curvel.Z);
|
|
Vector3 newvel = curvel + (targetvel - curvel) * velspd * elapsed;
|
|
Velocity = newvel;
|
|
var coll = Space.FindFirstCollision(this, elapsed);
|
|
if (coll.Hit)
|
|
{
|
|
Vector3 collpos = coll.PrePos; //last known ok position
|
|
Vector3 disp = Velocity * elapsed;
|
|
Vector3 oldpos = Position;
|
|
Vector3 targetpos = Position + disp;
|
|
float displ = disp.Length();
|
|
|
|
//////BoundingSphere sph = new BoundingSphere(targetpos + Center, Radius);
|
|
//////r.SphereHit = SphereIntersect(sph);
|
|
|
|
if ((disp.Z > -0.25f))/* && (displ < Radius * 2.0f)*/
|
|
{
|
|
Vector3 raydir = new Vector3(0.0f, 0.0f, -1.0f);
|
|
Vector3 rayoff = new Vector3(0.0f, 0.0f, 0.0f);
|
|
Ray ray = new Ray(targetpos + Center + rayoff, raydir);
|
|
var rayhit = Space.RayIntersect(ray, 1.0f);
|
|
if (rayhit.Hit)
|
|
{
|
|
if (rayhit.HitDist > 0)
|
|
{
|
|
Position = rayhit.Position - Center + new Vector3(0, 0, Radius);
|
|
//collpos = Position;//targetpos;//
|
|
}
|
|
else
|
|
{
|
|
//the start of the ray was a collision... can't move here
|
|
Position = collpos;
|
|
}
|
|
}
|
|
else //might happen when about to go off a big drop?
|
|
{
|
|
Position = targetpos;// collpos;
|
|
//collpos = targetpos;
|
|
}
|
|
}
|
|
else //moving fast...
|
|
{
|
|
Position = collpos; //last known ok position
|
|
}
|
|
//Position = collpos; //last known ok position
|
|
|
|
|
|
|
|
bool wasOnGround = OnGround;
|
|
OnGround = (Vector3.Dot(coll.SphereHit.Normal, Vector3.UnitZ) > 0.8f);
|
|
if (OnGround)
|
|
{
|
|
}
|
|
|
|
|
|
Vector3 findisp = Position - oldpos;
|
|
float findispl = findisp.Length();
|
|
float fdisp = Math.Min(displ, findispl);
|
|
Vector3 dispdir = findisp / Math.Max(findispl, 0.0001f);
|
|
float absvel = fdisp / Math.Max(elapsed, 0.0001f);
|
|
Velocity = dispdir * absvel;
|
|
|
|
//Vector3 veldir = Vector3.Normalize(Position - oldpos);
|
|
//float vellen = (collpos - oldpos).Length() / Math.Max(elapsed, 0.0001f);
|
|
//Velocity = veldir * vellen;
|
|
|
|
//Velocity = (Position - oldpos) / Math.Max(elapsed, 0.0001f);
|
|
|
|
}
|
|
else
|
|
{
|
|
Position = coll.HitPos; //hitpos is the end pos if not hit
|
|
OnGround = false;
|
|
|
|
var raydir = new Vector3(0.0f, 0.0f, -1.0f);
|
|
var ray = new Ray(Position, raydir);
|
|
var rayhit = Space.RayIntersect(ray, float.MaxValue);
|
|
if (!rayhit.Hit && rayhit.TestComplete)
|
|
{
|
|
//must be under the map? try to find the ground...
|
|
ray.Position = Position + new Vector3(0.0f, 0.0f, 1000.0f);
|
|
rayhit = Space.RayIntersect(ray, float.MaxValue);
|
|
if (rayhit.Hit)
|
|
{
|
|
Position = rayhit.Position + new Vector3(0.0f, 0.0f, Radius) - Center;
|
|
OnGround = true;
|
|
}
|
|
else
|
|
{ }//didn't find the ground, what to do now?
|
|
}
|
|
}
|
|
|
|
CameraEntity.Position = Position;
|
|
}
|
|
|
|
|
|
private void SetOrientation(Quaternion ori)
|
|
{
|
|
Orientation = ori;
|
|
OrientationInv = Quaternion.Invert(Orientation);
|
|
CameraEntity.Orientation = Quaternion.Multiply(Orientation, CameraOrientation);
|
|
CameraEntity.OrientationInv = Quaternion.Invert(Orientation);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|