GL - adding a camera on the client
This commit is contained in:
parent
6cf5ed3a22
commit
f657a58a4f
|
@ -192,6 +192,7 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GameClientState\Camera.cpp" />
|
||||
<ClCompile Include="GameClientState\C_obj\C_DynamicObj.cpp" />
|
||||
<ClCompile Include="GameClientState\C_obj\C_Player.cpp" />
|
||||
<ClCompile Include="GameClientState\C_obj\C_StaticObj.cpp" />
|
||||
|
@ -205,6 +206,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GameClientRecieverFunc.h" />
|
||||
<ClInclude Include="GameClientState\Camera.h" />
|
||||
<ClInclude Include="GameClientState\C_obj\C_DynamicObj.h" />
|
||||
<ClInclude Include="GameClientState\C_obj\C_Player.h" />
|
||||
<ClInclude Include="GameClientState\C_obj\C_StaticObj.h" />
|
||||
|
|
|
@ -8,6 +8,7 @@ struct C_Player::myData
|
|||
Oyster::Math3D::Float4x4 view;
|
||||
Oyster::Math3D::Float4x4 proj;
|
||||
Oyster::Graphics::Model::Model *model;
|
||||
Oyster::Math3D::Float4 lookDir;
|
||||
int ID;
|
||||
}privData;
|
||||
|
||||
|
@ -29,7 +30,7 @@ void C_Player::Init(ModelInitData modelInit)
|
|||
privData->model->WorldMatrix = modelInit.world;
|
||||
privData->model->Visible = modelInit.visible;
|
||||
privData->ID = modelInit.id;
|
||||
|
||||
privData->lookDir = Oyster::Math3D::Float4 (0,0,1,0);
|
||||
}
|
||||
void C_Player::setPos(Oyster::Math::Float4x4 world)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
#include "Camera.h"
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
this->m_position = Oyster::Math::Float3(0, 50, 0);
|
||||
this->mRight = Oyster::Math::Float3(1, 0, 0);
|
||||
this->mUp = Oyster::Math::Float3(0, 1, 0);
|
||||
this->mLook = Oyster::Math::Float3(0, 0, 1);
|
||||
}
|
||||
|
||||
Camera::~Camera()
|
||||
{
|
||||
}
|
||||
|
||||
void Camera::SetPosition(const Oyster::Math::Float3& v)
|
||||
{
|
||||
this->m_position = v;
|
||||
}
|
||||
|
||||
Oyster::Math::Float3 Camera::GetPosition()const
|
||||
{
|
||||
return this->m_position;
|
||||
}
|
||||
|
||||
Oyster::Math::Float3 Camera::GetRight()const
|
||||
{
|
||||
return this->mRight;
|
||||
}
|
||||
|
||||
Oyster::Math::Float3 Camera::GetUp()const
|
||||
{
|
||||
return this->mUp;
|
||||
}
|
||||
|
||||
Oyster::Math::Float3 Camera::GetLook()const
|
||||
{
|
||||
return this->mLook;
|
||||
}
|
||||
|
||||
float Camera::GetNearZ()const
|
||||
{
|
||||
return this->mNearZ;
|
||||
}
|
||||
|
||||
float Camera::GetFarZ()const
|
||||
{
|
||||
return this->mFarZ;
|
||||
}
|
||||
|
||||
float Camera::GetAspect()const
|
||||
{
|
||||
return this->mAspect;
|
||||
}
|
||||
|
||||
Oyster::Math::Float3 Camera::CrossMatrix(const Oyster::Math::Float3& vector, const Oyster::Math::Float4x4& matrix)
|
||||
{
|
||||
Oyster::Math::Float3 vec;
|
||||
vec.x = matrix.m11*vector.x + matrix.m12*vector.y + matrix.m13*vector.z;
|
||||
vec.y = matrix.m21*vector.x + matrix.m22*vector.y + matrix.m23*vector.z;
|
||||
vec.z = matrix.m31*vector.x + matrix.m32*vector.y + matrix.m33*vector.z;
|
||||
return vec;
|
||||
}
|
||||
|
||||
void Camera::SetLens(float fovY, float aspect, float zn, float zf)
|
||||
{
|
||||
this->mFovY = fovY;
|
||||
this->mAspect = aspect;
|
||||
this->mNearZ = zn;
|
||||
this->mFarZ = zf;
|
||||
|
||||
/*float yScale = tan((Oyster::Math::pi*0.5f) - (mFovY*0.5f));
|
||||
float xScale = yScale/this->mAspect;
|
||||
|
||||
mProj = Oyster::Math::Float4x4(xScale, 0, 0, 0,
|
||||
0, yScale, 0, 0,
|
||||
0, 0, zf/(zf-zn), 1,
|
||||
0, 0, -zn*zf/(zf-zn), 0);
|
||||
mProj.Transpose();*/
|
||||
mProj = Oyster::Math3D::ProjectionMatrix_Perspective(fovY,aspect,zn,zf);
|
||||
}
|
||||
|
||||
void Camera::LookAt(Oyster::Math::Float3 pos, Oyster::Math::Float3 target, Oyster::Math::Float3 worldUp)
|
||||
{
|
||||
Oyster::Math::Float3 L;
|
||||
|
||||
L = target - pos;
|
||||
L.Normalize();
|
||||
|
||||
Oyster::Math::Float3 R;
|
||||
R = worldUp.Cross(L);
|
||||
R.Normalize();
|
||||
|
||||
Oyster::Math::Float3 U;
|
||||
U = L.Cross(R);
|
||||
|
||||
this->m_position = pos;
|
||||
this->mLook = L;
|
||||
this->mRight = R;
|
||||
this->mUp = U;
|
||||
}
|
||||
|
||||
Oyster::Math::Float4x4 Camera::View()const
|
||||
{
|
||||
return this->mView;
|
||||
}
|
||||
|
||||
Oyster::Math::Float4x4 Camera::Proj()const
|
||||
{
|
||||
return this->mProj;
|
||||
}
|
||||
|
||||
Oyster::Math::Float4x4 Camera::ViewsProj()const
|
||||
{
|
||||
Oyster::Math::Float4x4 M;
|
||||
M = mView * mProj;
|
||||
return M;
|
||||
}
|
||||
|
||||
void Camera::Walk(float dist)
|
||||
{
|
||||
this->m_position += dist*this->mLook;
|
||||
}
|
||||
|
||||
void Camera::Strafe(float dist)
|
||||
{
|
||||
this->m_position += dist*this->mRight;
|
||||
}
|
||||
|
||||
void Camera::Pitch(float angle)
|
||||
{
|
||||
float radians = angle * 0.0174532925f;
|
||||
|
||||
Oyster::Math::Float4x4 R;
|
||||
|
||||
Oyster::Math3D::RotationMatrix(radians,-mRight,R);
|
||||
this->mUp = CrossMatrix(this->mUp, R);
|
||||
this->mLook = CrossMatrix(this->mLook, R);
|
||||
}
|
||||
|
||||
void Camera::Yaw(float angle)
|
||||
{
|
||||
float radians = angle * 0.0174532925f;
|
||||
|
||||
Oyster::Math::Float4x4 R;
|
||||
|
||||
Oyster::Math::Float3 up(0,1,0);
|
||||
Oyster::Math3D::RotationMatrix(radians,-up,R);
|
||||
|
||||
this->mRight = CrossMatrix(this->mRight, R);
|
||||
this->mUp = CrossMatrix(mUp, R);
|
||||
this->mLook = CrossMatrix(this->mLook, R);
|
||||
}
|
||||
|
||||
void Camera::UpdateViewMatrix()
|
||||
{
|
||||
mLook.Normalize();
|
||||
mUp = mLook.Cross(mRight);
|
||||
mUp.Normalize();
|
||||
mRight = mUp.Cross(mLook);
|
||||
mView = Oyster::Math3D::ViewMatrix_LookAtDirection(mLook, mUp, m_position);
|
||||
/*
|
||||
mLook.Normalize();
|
||||
mUp = mLook.Cross(mRight);
|
||||
mUp.Normalize();
|
||||
mRight = mUp.Cross(mLook);
|
||||
|
||||
float x = -m_position.Dot(mRight);
|
||||
float y = -m_position.Dot(mUp);
|
||||
float z = -m_position.Dot(mLook);
|
||||
|
||||
mView.m11 = mRight.x;
|
||||
mView.m21 = mRight.y;
|
||||
mView.m31 = mRight.z;
|
||||
mView.m41 = x;
|
||||
|
||||
mView.m12 = mUp.x;
|
||||
mView.m22 = mUp.y;
|
||||
mView.m32 = mUp.z;
|
||||
mView.m42 = y;
|
||||
|
||||
mView.m13 = mLook.x;
|
||||
mView.m23 = mLook.y;
|
||||
mView.m33 = mLook.z;
|
||||
mView.m43 = z;
|
||||
|
||||
mView.m14 = 0.0f;
|
||||
mView.m24 = 0.0f;
|
||||
mView.m34 = 0.0f;
|
||||
mView.m44 = 1.0f;
|
||||
|
||||
mView.Transpose();*/
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef CAMERA__H
|
||||
#define CAMERA__H
|
||||
|
||||
#include "OysterMath.h"
|
||||
|
||||
class Camera
|
||||
{
|
||||
private:
|
||||
|
||||
Oyster::Math::Float3 m_position;
|
||||
Oyster::Math::Float3 mRight;
|
||||
Oyster::Math::Float3 mUp;
|
||||
Oyster::Math::Float3 mLook;
|
||||
|
||||
|
||||
|
||||
float mNearZ;
|
||||
float mFarZ;
|
||||
float mAspect;
|
||||
float mFovY;
|
||||
|
||||
Oyster::Math::Float4x4 mView;
|
||||
Oyster::Math::Float4x4 mProj;
|
||||
|
||||
public:
|
||||
Camera();
|
||||
virtual ~Camera();
|
||||
|
||||
void SetPosition(const Oyster::Math::Float3& v);
|
||||
|
||||
Oyster::Math::Float3 GetPosition()const;
|
||||
|
||||
Oyster::Math::Float3 GetRight()const;
|
||||
Oyster::Math::Float3 GetUp()const;
|
||||
Oyster::Math::Float3 GetLook()const;
|
||||
|
||||
float GetNearZ()const;
|
||||
float GetFarZ()const;
|
||||
float GetAspect()const;
|
||||
|
||||
Oyster::Math::Float3 CrossMatrix(const Oyster::Math::Float3& v, const Oyster::Math::Float4x4& m);
|
||||
|
||||
void SetLens(float fovY, float aspect, float zn, float zf);
|
||||
|
||||
void LookAt(Oyster::Math::Float3 pos, Oyster::Math::Float3 target, Oyster::Math::Float3 worldUp);
|
||||
|
||||
void setLook(Oyster::Math::Float3 look) { mLook = look; }
|
||||
void setUp(Oyster::Math::Float3 up) { mUp = up; }
|
||||
void setRight(Oyster::Math::Float3 right) { mRight = right; }
|
||||
|
||||
Oyster::Math::Float4x4 View()const;
|
||||
Oyster::Math::Float4x4 Proj()const;
|
||||
Oyster::Math::Float4x4 ViewsProj()const;
|
||||
|
||||
void Walk(float dist);
|
||||
void Strafe(float dist);
|
||||
|
||||
void Pitch(float angle);
|
||||
void Yaw(float angle);
|
||||
|
||||
void UpdateViewMatrix();
|
||||
};
|
||||
#endif
|
|
@ -4,7 +4,7 @@
|
|||
#include "C_obj/C_DynamicObj.h"
|
||||
#include <Protocols.h>
|
||||
#include "NetworkClient.h"
|
||||
|
||||
#include "Camera.h"
|
||||
|
||||
using namespace DanBias::Client;
|
||||
|
||||
|
@ -17,7 +17,6 @@ struct GameState::myData
|
|||
int modelCount;
|
||||
Oyster::Network::NetworkClient* nwClient;
|
||||
gameStateState state;
|
||||
|
||||
|
||||
|
||||
}privData;
|
||||
|
@ -38,10 +37,12 @@ GameState::~GameState(void)
|
|||
bool GameState::Init(Oyster::Network::NetworkClient* nwClient)
|
||||
{
|
||||
// load models
|
||||
camera = new Camera;
|
||||
privData = new myData();
|
||||
privData->state = gameStateState_loading;
|
||||
privData->nwClient = nwClient;
|
||||
privData->state = LoadGame();
|
||||
|
||||
return true;
|
||||
}
|
||||
GameState::gameStateState GameState::LoadGame()
|
||||
|
@ -119,10 +120,19 @@ bool GameState::LoadModels(std::wstring mapFile)
|
|||
}
|
||||
bool GameState::InitCamera(Oyster::Math::Float3 startPos)
|
||||
{
|
||||
Oyster::Math::Float3 dir = Oyster::Math::Float3(0,0,-1);
|
||||
Oyster::Math::Float3 up =Oyster::Math::Float3(0,1,0);
|
||||
Oyster::Math::Float3 pos = Oyster::Math::Float3(0, 0, 20);
|
||||
|
||||
camera->LookAt(pos, dir, up);
|
||||
camera->SetLens(3.14f/2, 1024/768, 1, 1000);
|
||||
|
||||
privData->proj = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/2,1024.0f/768.0f,.1f,1000);
|
||||
//privData->proj = Oyster::Math3D::ProjectionMatrix_Orthographic(1024, 768, 1, 1000);
|
||||
Oyster::Graphics::API::SetProjection(privData->proj);
|
||||
|
||||
camera->UpdateViewMatrix();
|
||||
privData->view = camera->View();
|
||||
privData->view = Oyster::Math3D::ViewMatrix_LookAtDirection(Oyster::Math::Float3(0,0,-1),Oyster::Math::Float3(0,1,0),startPos);
|
||||
privData->view = Oyster::Math3D::OrientationMatrix_LookAtDirection(Oyster::Math::Float3(0,0,-1),Oyster::Math::Float3(0,1,0),startPos);
|
||||
privData->view = Oyster::Math3D::InverseOrientationMatrix(privData->view);
|
||||
return true;
|
||||
|
@ -147,81 +157,9 @@ GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyI
|
|||
// read server data
|
||||
// update objects
|
||||
{
|
||||
bool send = false;
|
||||
GameLogic::Protocol_PlayerMovement movePlayer;
|
||||
movePlayer.bForward = false;
|
||||
movePlayer.bBackward = false;
|
||||
movePlayer.bLeft = false;
|
||||
movePlayer.bRight = false;
|
||||
readKeyInput(KeyInput);
|
||||
camera->UpdateViewMatrix();
|
||||
|
||||
if(KeyInput->IsKeyPressed(DIK_W))
|
||||
{
|
||||
|
||||
if(!key_forward)
|
||||
{
|
||||
movePlayer.bForward = true;
|
||||
send = true;
|
||||
key_forward = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
key_forward = false;
|
||||
|
||||
if(KeyInput->IsKeyPressed(DIK_S))
|
||||
{
|
||||
if(!key_backward)
|
||||
{
|
||||
movePlayer.bBackward = true;
|
||||
send = true;
|
||||
key_backward = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
key_backward = false;
|
||||
|
||||
if(KeyInput->IsKeyPressed(DIK_A))
|
||||
{
|
||||
if(!key_strafeLeft)
|
||||
{
|
||||
movePlayer.bLeft = true;
|
||||
send = true;
|
||||
key_strafeLeft = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
key_strafeLeft = false;
|
||||
|
||||
if(KeyInput->IsKeyPressed(DIK_D))
|
||||
{
|
||||
if(!key_strafeRight)
|
||||
{
|
||||
movePlayer.bRight = true;
|
||||
send = true;
|
||||
key_strafeRight = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
key_strafeRight = false;
|
||||
|
||||
|
||||
if (privData->nwClient->IsConnected() && send)
|
||||
{
|
||||
privData->nwClient->Send(movePlayer);
|
||||
}
|
||||
|
||||
//send delta mouse movement
|
||||
if (KeyInput->IsMousePressed())
|
||||
{
|
||||
GameLogic::Protocol_PlayerMouse deltaMouseMove;
|
||||
deltaMouseMove.dxMouse = KeyInput->GetYaw();
|
||||
deltaMouseMove.dyMouse = KeyInput->GetPitch();
|
||||
//privData->nwClient->Send(deltaMouseMove);
|
||||
}
|
||||
|
||||
// send event data
|
||||
//
|
||||
if(KeyInput->IsKeyPressed(DIK_L))
|
||||
privData->state = GameState::gameStateState_end;
|
||||
}
|
||||
break;
|
||||
case gameStateState_end:
|
||||
|
@ -236,7 +174,9 @@ GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyI
|
|||
}
|
||||
bool GameState::Render()
|
||||
{
|
||||
Oyster::Graphics::API::SetView(privData->view);
|
||||
Oyster::Graphics::API::SetView(camera->View());
|
||||
//Oyster::Graphics::API::SetProjection(camera->Proj());
|
||||
//Oyster::Graphics::API::SetView(privData->view);
|
||||
Oyster::Graphics::API::SetProjection(privData->proj);
|
||||
Oyster::Graphics::API::NewFrame();
|
||||
for (unsigned int i = 0; i < privData->object.size(); i++)
|
||||
|
@ -259,6 +199,88 @@ bool GameState::Release()
|
|||
privData = NULL;
|
||||
return true;
|
||||
}
|
||||
void GameState::readKeyInput(InputClass* KeyInput)
|
||||
{
|
||||
|
||||
bool send = false;
|
||||
GameLogic::Protocol_PlayerMovement movePlayer;
|
||||
movePlayer.bForward = false;
|
||||
movePlayer.bBackward = false;
|
||||
movePlayer.bLeft = false;
|
||||
movePlayer.bRight = false;
|
||||
|
||||
if(KeyInput->IsKeyPressed(DIK_W))
|
||||
{
|
||||
|
||||
if(!key_forward)
|
||||
{
|
||||
movePlayer.bForward = true;
|
||||
send = true;
|
||||
key_forward = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
key_forward = false;
|
||||
|
||||
if(KeyInput->IsKeyPressed(DIK_S))
|
||||
{
|
||||
if(!key_backward)
|
||||
{
|
||||
movePlayer.bBackward = true;
|
||||
send = true;
|
||||
key_backward = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
key_backward = false;
|
||||
|
||||
if(KeyInput->IsKeyPressed(DIK_A))
|
||||
{
|
||||
if(!key_strafeLeft)
|
||||
{
|
||||
movePlayer.bLeft = true;
|
||||
send = true;
|
||||
key_strafeLeft = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
key_strafeLeft = false;
|
||||
|
||||
if(KeyInput->IsKeyPressed(DIK_D))
|
||||
{
|
||||
if(!key_strafeRight)
|
||||
{
|
||||
movePlayer.bRight = true;
|
||||
send = true;
|
||||
key_strafeRight = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
key_strafeRight = false;
|
||||
|
||||
|
||||
if (privData->nwClient->IsConnected() && send)
|
||||
{
|
||||
privData->nwClient->Send(movePlayer);
|
||||
}
|
||||
|
||||
//send delta mouse movement
|
||||
if (KeyInput->IsMousePressed())
|
||||
{
|
||||
GameLogic::Protocol_PlayerMouse deltaMouseMove;
|
||||
deltaMouseMove.dxMouse = KeyInput->GetYaw();
|
||||
deltaMouseMove.dyMouse = KeyInput->GetPitch();
|
||||
//privData->nwClient->Send(deltaMouseMove);
|
||||
camera->Yaw(KeyInput->GetYaw());
|
||||
camera->Pitch(KeyInput->GetPitch());
|
||||
}
|
||||
|
||||
|
||||
// send event data
|
||||
//
|
||||
if(KeyInput->IsKeyPressed(DIK_L))
|
||||
privData->state = GameState::gameStateState_end;
|
||||
}
|
||||
|
||||
void GameState::Protocol(ProtocolStruct* pos)
|
||||
{
|
||||
|
@ -290,6 +312,9 @@ void GameState::Protocol( ObjPos* pos )
|
|||
{
|
||||
privData->object[i]->setPos(world);
|
||||
|
||||
|
||||
camera->SetPosition(Oyster::Math::Float3(world[12], world[13], world[14]));
|
||||
camera->UpdateViewMatrix();
|
||||
//privData->view = world;
|
||||
//privData->view = Oyster::Math3D::InverseOrientationMatrix(privData->view);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "GameClientState.h"
|
||||
#include "OysterMath.h"
|
||||
#include <string>
|
||||
#include "Camera.h"
|
||||
namespace DanBias
|
||||
{
|
||||
namespace Client
|
||||
|
@ -21,6 +22,7 @@ private:
|
|||
bool key_backward;
|
||||
bool key_strafeRight;
|
||||
bool key_strafeLeft;
|
||||
Camera* camera;
|
||||
|
||||
struct myData;
|
||||
myData* privData;
|
||||
|
@ -33,6 +35,7 @@ public:
|
|||
bool InitCamera(Oyster::Math::Float3 startPos) ;
|
||||
gameStateState LoadGame();
|
||||
|
||||
void readKeyInput(InputClass* KeyInput);
|
||||
bool Render()override;
|
||||
bool Release()override;
|
||||
|
||||
|
|
|
@ -72,10 +72,25 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody()
|
|||
|
||||
void Object::BeginFrame()
|
||||
{
|
||||
|
||||
this->rigidBody->SetState(this->setState);
|
||||
|
||||
}
|
||||
// update physic
|
||||
void Object::EndFrame()
|
||||
{
|
||||
this->rigidBody->GetState(this->getState);
|
||||
|
||||
//Oyster::Math::Float rot = (setState.GetGravityNormal().xyz).Dot(getState.GetGravityNormal().xyz);
|
||||
//Oyster::Math::Float3 axis = (setState.GetGravityNormal().xyz).Cross(getState.GetGravityNormal().xyz);
|
||||
Oyster::Math::Float4x4 rotMatrix = setState.GetOrientation(); //Oyster::Math3D::RotationMatrix(rot, axis);
|
||||
Oyster::Math3D::SnapAxisYToNormal_UsingNlerp(rotMatrix, -setState.GetGravityNormal());
|
||||
setState.SetOrientation(rotMatrix);
|
||||
|
||||
|
||||
this->getState = this->rigidBody->GetState();
|
||||
|
||||
|
||||
|
||||
this->setState = this->getState;
|
||||
|
||||
}
|
|
@ -92,9 +92,13 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint)
|
|||
this->lookDir = Oyster::Math::Float4(1,0,0);
|
||||
}
|
||||
|
||||
void Player::Rotate(float x, float y)
|
||||
void Player::Rotate(float dx, float dy)
|
||||
{
|
||||
this->setState.AddRotation(Oyster::Math::Float4(x, y));
|
||||
|
||||
//this->lookDir = lookDir;
|
||||
|
||||
//this->setState.AddRotation(Oyster::Math::Float4(x, y));
|
||||
//this->setState.SetRotation();
|
||||
}
|
||||
|
||||
void Player::Jump()
|
||||
|
|
|
@ -194,8 +194,10 @@ void API_Impl::Update()
|
|||
if( gravityImpulse != Float4::null )
|
||||
{
|
||||
state.ApplyLinearImpulse( gravityImpulse );
|
||||
(*proto)->SetGravityNormal( gravityImpulse.GetNormalized().xyz );
|
||||
//state.SetGravityNormal( gravityImpulse.GetNormalized());
|
||||
//(*proto)->SetGravityNormal( gravityImpulse.GetNormalized().xyz );
|
||||
(*proto)->SetState( state );
|
||||
(*proto)->SetGravityNormal( gravityImpulse.GetNormalized().xyz );
|
||||
}
|
||||
|
||||
// Step 2: Apply Collision Response
|
||||
|
|
Loading…
Reference in New Issue