Now FPS character controller demo with fixed shading

This commit is contained in:
Antoine Pilote
2021-06-16 00:04:21 -04:00
parent 43297e2752
commit 8f238cd4ca
31 changed files with 639 additions and 55 deletions

View File

@@ -1,5 +1,40 @@
{
"Entities": [
{
"CharacterControllerComponent": {
"Height": 1.2000000476837158,
"Mass": 2500.0,
"Radius": 0.20000000298023224
},
"NameComponent": {
"Name": "Player"
},
"ParentComponent": {
"HasParent": false
},
"TransformComponent": {
"Rotation": {
"x": 0.0,
"y": -0.0,
"z": 0.0
},
"Scale": {
"x": 1.0,
"y": 1.0,
"z": 1.0
},
"Translation": {
"x": -15.681736946105957,
"y": 17.139999389648438,
"z": 10.975672721862793
},
"Type": "TransformComponent"
},
"WrenScriptComponent": {
"Class": "PlayerScript",
"Script": "Scripts/Player.wren"
}
},
{
"NameComponent": {
"Name": "Trenchbroom map"
@@ -8,7 +43,7 @@
"HasParent": false
},
"QuakeMapComponent": {
"HasCollisions": false,
"HasCollisions": true,
"Path": "C:\\Dev\\Nuake\\Editor\\resources\\Maps\\texture_test.map"
},
"TransformComponent": {
@@ -43,7 +78,7 @@
"y": 0.9591699838638306,
"z": 0.20000000298023224
},
"IsVolumetric": false,
"IsVolumetric": true,
"Strength": 10.0,
"SyncDirectionWithSky": true,
"Type": 0
@@ -66,11 +101,54 @@
"z": 1.0
},
"Translation": {
"x": 7.035792350769043,
"y": 5.795107364654541,
"z": -0.9431453943252563
"x": -359.2229919433594,
"y": -1.979316234588623,
"z": -322.51702880859375
},
"Type": "TransformComponent"
},
"WrenScriptComponent": {
"Class": "TestScript",
"Script": "Scripts/entityScript.wren"
}
},
{
"CameraComponent": {
"CameraInstance": {
"AspectRatio": 1.7106741666793823,
"Exposure": 1.0,
"Fov": 88.0,
"Speed": 1.0,
"m_Type": 1
}
},
"NameComponent": {
"Name": "Camera"
},
"ParentComponent": {
"HasParent": false
},
"TransformComponent": {
"Rotation": {
"x": 0.0,
"y": -0.0,
"z": 0.0
},
"Scale": {
"x": 1.0,
"y": 1.0,
"z": 1.0
},
"Translation": {
"x": 0.0,
"y": 0.75,
"z": 0.0
},
"Type": "TransformComponent"
},
"WrenScriptComponent": {
"Class": "CamScript",
"Script": "Scripts/Cam.wren"
}
}
],
@@ -78,7 +156,7 @@
"m_Environement": {
"AmbientColor": {
"w": 0.0,
"x": null,
"x": 0.0,
"y": 0.0,
"z": 0.0
},

View File

@@ -0,0 +1,60 @@
import "Scripts/ScriptableEntity" for ScriptableEntity
import "Scripts/Engine" for Engine
import "Scripts/Scene" for Scene
import "Scripts/Math" for Vector3, Math
import "Scripts/Input" for Input
class CamScript is ScriptableEntity {
construct new() {
_Pitch = 0
_Yaw = 0
_mouseLastX = 0
_mouseLastY = 0
Input.HideMouse()
}
init() {
}
update(ts) {
var x = Input.GetMouseX()
var y = Input.GetMouseY()
var diffx = x - _mouseLastX
var diffy = _mouseLastY - y
_mouseLastX = x
_mouseLastY = y
var sens = 0.1
diffx = diffx * sens
diffy = diffy * sens
_Yaw = _Yaw + diffx
_Pitch = _Pitch + diffy
if(_Pitch > 89) _Pitch = 89
if(_Pitch < -89) _Pitch = -89
var cam = this.GetComponent("Camera")
var rad_yaw = Math.Radians(_Yaw)
var rad_pitch = Math.Radians(_Pitch)
var camX = Math.Cos(rad_yaw) * Math.Cos(rad_pitch)
var camY = Math.Sin(rad_pitch)
var camZ = Math.Sin(rad_yaw) * Math.Cos(rad_pitch)
var newDir = Vector3.new(camX, camY, camZ)
cam.SetDirection(newDir)
}
CheckInput() {
}
exit() {
}
}

View File

@@ -1,5 +1,16 @@
class Math {
foreign static Sqrt_(x, y, z)
foreign static Sin(s)
foreign static Cos(s)
foreign static Radians(s)
foreign static Degrees(s)
static Cross(vec1, vec2) {
var result = this.Cross_(vec1.x, vec1.y, vec1.z, vec2.x, vec2.y, vec2.z)
return Vector3.new(result[0], result[1], result[2])
}
foreign static Cross_(x, y, z, x1, y2, z2)
}
class Vector3 {
@@ -7,6 +18,7 @@ class Vector3 {
x {_x}
y {_y}
z {_z}
x=(value) {
_x = value
}
@@ -49,6 +61,18 @@ class Vector3 {
}
}
-(other) {
if(other is Vector3) {
return Vector3.new(_x - other.x,
_y - other.y,
_z - other.z)
} else if(other is Num) {
return Vector3.new(_x - other,
_y - other,
_z - other)
}
}
construct new(x, y, z) {
_x = x
_y = y
@@ -59,6 +83,10 @@ class Vector3 {
return Math.Sqrt_(_x, _y, _z)
}
Cross(vec) {
Math.Cross(this, vec)
}
Normalize() {
var length = this.Sqrt()
var x = _x / length

View File

@@ -0,0 +1,28 @@
import "Scripts/Math" for Vector3
class CollisionResult {
LocalPosition { _Local}
WorldPosition { _World}
Normal { _Normal}
construct new(l, w, n) {
_Local = l
_World = w
_Normal = n
}
}
class Physics {
foreign static Raycast_(x, y, z, x2, y2, z2)
static Raycast(v1, v2) {
var result = this.Raycast_(v1.x, v1.y, v1.z, v2.x, v2.y, v2.z)
var local = Vector3.new(result[0], result[1], result[2])
var world = Vector3.new(result[3], result[4], result[5])
var normal = Vector3.new(result[6], result[7], result[8])
return CollisionResult.new(local, world, normal)
}
}

View File

@@ -0,0 +1,99 @@
import "Scripts/ScriptableEntity" for ScriptableEntity
import "Scripts/Engine" for Engine
import "Scripts/Scene" for Scene
import "Scripts/Math" for Vector3
import "Scripts/Input" for Input
import "Scripts/Physics" for Physics, CollisionResult
class PlayerScript is ScriptableEntity {
construct new() {
_InputDir = Vector3.new(0, 0, 0)
_Velocity = Vector3.new(0, 0, 0)
_Accel = 150
_Deccel = 0.92
_AirDeccel = 0.7
_Gravity = 20
_MaxSpeed = 20
_Jump = 800
//Input.HideMouse()
}
init() {
Engine.Log("Player init")
}
update(ts) {
this.CheckInput()
var camEntity = Scene.GetEntity("Camera")
var cam = camEntity.GetComponent("Camera")
var dir = cam.GetDirection()
dir.y = 0
dir = dir.Normalize()
var right = cam.GetRight()
right.y = 0
right = right.Normalize()
var new_Velocity = (dir * _InputDir.z) + (right * _InputDir.x)
var controller = this.GetComponent("CharacterController")
var transform = this.GetComponent("Transform")
var from = transform.GetTranslation()
var to = from - Vector3.new(0, 1, 0)
var normal = Physics.Raycast(from, to).Normal.Normalize()
Engine.Log("Normal col: (%(normal.x), %(normal.y), %(normal.z))")
if(!controller.IsOnGround()) {
_Velocity.y = _Velocity.y - _Gravity
//_Velocity.x = _Velocity.x * _AirDeccel
//_Velocity.z = _Velocity.z * _AirDeccel
} else {
_Velocity.y = -20
if(Input.IsKeyPressed(32)) _Velocity.y = _Jump
_Velocity.x = _Velocity.x + new_Velocity.x * _Accel
_Velocity.z = _Velocity.z + new_Velocity.z * _Accel
_Velocity.x = _Velocity.x * _Deccel
_Velocity.z = _Velocity.z * _Deccel
}
controller.MoveAndSlide(_Velocity * ts)
}
CheckInput() {
/*
87 = W
65 = A
83 = S
68 = D
32 = SPACE
*/
if(Input.IsKeyDown(87)) {
_InputDir.z = 1
} else if(Input.IsKeyDown(83)) {
_InputDir.z = -1
} else {
_InputDir.z = 0
}
if(Input.IsKeyDown(65)) {
_InputDir.x = 1
} else if(Input.IsKeyDown(68)) {
_InputDir.x = -1
} else {
_InputDir.x = 0
}
}
exit() {
Engine.Log("Player exit")
}
}

View File

@@ -24,6 +24,8 @@ class Scene {
return CharacterController.new(id)
} else if (component == "Camera") {
return Camera.new(id)
} else if (component == "Transform") {
return TransformComponent.new(id)
}
}
@@ -32,6 +34,7 @@ class Scene {
// Components
//
// Transform
foreign static GetTranslation_(e)
//foreign static SetTranslation_(e, x, y, z)
//foreign static SetRotation_(e, x, y, z)
//foreign static SetScale_(e, x, y, z)
@@ -53,6 +56,7 @@ class Scene {
// Character controller
foreign static MoveAndSlide_(e, x, y, z)
foreign static IsCharacterControllerOnGround_(e)
//foreign static IsOnGround_(e)
@@ -97,6 +101,19 @@ class Entity {
*/
}
class TransformComponent {
construct new(id) {
_entityId = id
}
GetTranslation() {
var result = Scene.GetTranslation_(_entityId)
return Vector3.new(result[0], result[1], result[2])
}
}
class Light {
construct new(id) {
_entityId = id
@@ -131,6 +148,10 @@ class CharacterController {
MoveAndSlide(vel) {
Scene.MoveAndSlide_(_entityId, vel.x, vel.y, vel.z)
}
IsOnGround() {
return Scene.IsCharacterControllerOnGround_(_entityId)
}
}
class Camera {

View File

@@ -0,0 +1,23 @@
import "Scripts/Engine" for Engine
import "Scripts/ScriptableEntity" for ScriptableEntity
class TestScript is ScriptableEntity {
construct new() {
_deltaTime = 0
}
init() {
Engine.Log("Hello init")
}
update(ts) {
_deltaTime = _deltaTime + ts
}
exit() {
Engine.Log("Hello exit")
}
}

View File

@@ -1,27 +1,23 @@
import "Scripts/Engine" for Engine
import "Scripts/Input" for Input
import "Scripts/Scene" for Scene, Entity
class Test {
construct new() {}
init() {
System.print("hello init")
}
update(t) {
System.print("hello update %(t)")
}
exit() {
System.print("hello exit ")
}
// Gets called on the click event.
static hello() {
// Get the entity named Light
var entity = Scene.GetEntity("Light")
var light = entity.GetComponent("Light")
light.SetIntensity(1.0)
if(Input.IsMouseButtonPressed(2) == true) {
Engine.Log("RIGHT CLICK!!!!!!")
}
// Get the component light
var light = entity.GetComponent("Light")
//light.SetIntensity(222.0) // Change intensity
var currentIntensity = light.GetIntensity() // Get new intensity
Engine.Log("Current intensity %(currentIntensity)")
}
}
}

View File

@@ -1 +1 @@
{"Description":"","Name":"", "DefaultScene":"Scenes/test.scene"}
{"DefaultScene":"Scenes/test.scene","Description":"","Name":""}

View File

@@ -35,7 +35,7 @@ void EditorInterface::Init()
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
ImGui::DockSpaceOverViewport(viewport, dockspace_flags);
this->filesystem = FileSystemUI();
//this->filesystem = FileSystemUI();
}
@@ -854,7 +854,7 @@ void EditorInterface::DrawRessourceWindow()
textureID = m_SelectedMaterial->m_Normal->GetID();
if (ImGui::ImageButtonEx(ImGui::GetCurrentWindow()->GetID("#image3"), (void*)textureID, ImVec2(80, 80), ImVec2(0, 1), ImVec2(1, 0), ImVec2(2,2), ImVec4(0,0,0,1), ImVec4(1, 1, 1, 1)))
{
std::string texture = FileDialog::OpenFile("*.png|*.jpg");
std::string texture = FileDialog::OpenFile("*.png");
if (texture != "")
{
m_SelectedMaterial->SetNormal(TextureManager::Get()->GetTexture(texture));
@@ -1130,13 +1130,13 @@ void EditorInterface::Draw()
DrawRessourceWindow();
DrawViewport();
DrawSceneTree();
DrawFileSystem();
DrawDirectoryExplorer();
//DrawDirectoryExplorer();
DrawEntityPropreties();
DrawLogger();
// new stuff
filesystem.Draw();
filesystem.DrawDirectoryExplorer();
if(m_ShowImGuiDemo)
ImGui::ShowDemoWindow();

View File

@@ -9,7 +9,7 @@ class Material;
class EditorInterface
{
private:
FileSystemUI filesystem;
FileSystemUI filesystem = FileSystemUI();
Entity m_SelectedEntity;
bool m_IsEntitySelected = false;
bool m_DrawGrid = false;

View File

@@ -34,7 +34,7 @@ void FileSystemUI::Draw()
}
if (open)
{
//EditorInterfaceDrawFiletree(rootDirectory);
EditorInterfaceDrawFiletree(rootDirectory);
ImGui::TreePop();
}
}
@@ -88,6 +88,12 @@ void FileSystemUI::DrawDirectory(Ref<Directory> directory)
std::string id = ICON_FA_FOLDER + std::string("##") + directory->name;
if (ImGui::Button(id.c_str(), ImVec2(100, 100)))
m_CurrentDirectory = directory;
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::MenuItem("Htest"));
ImGui::EndPopup();
}
ImGui::Text(directory->name.c_str());
ImGui::PopFont();
}
@@ -199,6 +205,54 @@ void FileSystemUI::DrawDirectoryExplorer()
i++;
}
}
if (ImGui::BeginPopupContextItem("item context menu"))
{
float value;
if (ImGui::Selectable("Set to zero")) value = 0.0f;
if (ImGui::Selectable("Set to PI")) value = 3.1415f;
ImGui::SetNextItemWidth(-1);
ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
ImGui::EndPopup();
}
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::Button("New Wren script"))
{
ImGui::OpenPopup("CreateNewFile");
}
if (ImGui::MenuItem("New interface script"))
{
}
if (ImGui::MenuItem("New Scene"))
{
}
if (ImGui::MenuItem("New folder"))
{
}
if (ImGui::MenuItem("New interface"))
{
}
if (ImGui::MenuItem("New stylesheet"))
{
}
if (ImGui::BeginPopup("CreateNewFile"))
{
static char name[32] = "Label1";
char buf[64];
sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
ImGui::Text("Edit name:");
ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));
if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
if(ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter)))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
}
ImGui::EndPopup();
}
ImGui::EndTable();
}

View File

@@ -7,6 +7,22 @@
#include "src/Scripting/ScriptLoader.h"
#include "src/Core/Logger.h"
/* TODOS:
*
* Engine:
* Trigger zones from trenchbroom
* Scripting API vectors operation
* Scripting API for all component
* Scripting API for editing UI maybe
* Launch game standalone
* Fix physics system
* trenchbroom physics element
*
* Editor:
* File browser refact
*
*/
class Engine {
private:
static float m_LastFrameTime;

View File

@@ -99,7 +99,7 @@ void FileSystem::Scan()
RootDirectory = CreateRef<Directory>();
RootDirectory->Files = std::vector<Ref<File>>();
RootDirectory->Directories = std::vector<Ref<Directory>>();
RootDirectory->name = Root;
RootDirectory->name = FileSystem::AbsoluteToRelative(Root);
RootDirectory->fullPath = Root;
ScanDirectory(RootDirectory);
}

View File

@@ -27,7 +27,7 @@ bool Input::IsKeyPressed(int keycode)
bool result = state == GLFW_PRESS;
// First time pressed?
if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == false)
if (m_Keys.find(keycode) == m_Keys.end() || m_Keys[keycode] == true)
{
if (result)
m_Keys[keycode] = true;

View File

@@ -25,7 +25,7 @@ namespace Physics
}
};
CharacterController::CharacterController(float height, float radius, float mass)
CharacterController::CharacterController(float height, float radius, float mass, Vector3 position)
{
m_surfaceHitNormals = std::vector<glm::vec3>();
@@ -35,12 +35,12 @@ namespace Physics
btQuaternion quat = btQuaternion(0, 0, 0);
m_Transform = new btTransform();
m_Transform->setOrigin(btVector3(0.0f, 10.0f, 0.0f));
m_Transform->setOrigin(btVector3(position.x, position.y, position.z));
m_Transform->setRotation(quat);
m_MotionState = new btDefaultMotionState(*m_Transform);
btVector3 inertia;
m_CollisionShape->calculateLocalInertia(mass, inertia);
//m_CollisionShape->calculateLocalInertia(mass, inertia);
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, m_MotionState, m_CollisionShape, inertia);
@@ -52,7 +52,7 @@ namespace Physics
rigidBodyCI.m_linearDamping = 0.0f;
m_Rigidbody = new btRigidBody(rigidBodyCI);
m_Rigidbody->setGravity(btVector3(0, 0, 0));
// Keep upright
m_Rigidbody->setAngularFactor(0.0f);
@@ -71,6 +71,7 @@ namespace Physics
void CharacterController::MoveAndSlide(glm::vec3 velocity)
{
m_Rigidbody->setGravity(btVector3(0, 0, 0));
m_manualVelocity = velocity;
// Sync ghost with actually object
m_GhostObject->setWorldTransform(m_Rigidbody->getWorldTransform());
@@ -162,7 +163,7 @@ namespace Physics
m_Rigidbody->setLinearVelocity(vel);
m_onGround = true;
IsOnGround = true;
}
float testOffset = 0.07f;
@@ -189,8 +190,8 @@ namespace Physics
void CharacterController::UpdateVelocity()
{
m_manualVelocity.y = m_Rigidbody->getLinearVelocity().getY();
//m_manualVelocity.y = m_Rigidbody->getLinearVelocity().getY();
btVector3 grav = m_Rigidbody->getGravity();
btVector3 finalVel = btVector3(m_manualVelocity.x, m_manualVelocity.y, m_manualVelocity.z);
m_Rigidbody->setLinearVelocity(finalVel);

View File

@@ -5,6 +5,7 @@
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <vector>
#include "../Core/Maths.h"
namespace Physics
{
class CharacterController
@@ -12,14 +13,14 @@ namespace Physics
public:
bool IsOnGround = false;
bool m_hittingWall;
float m_stepHeight = 0.05f;
float m_stepHeight = .1f;
btTransform* m_Transform;
btCollisionShape* m_CollisionShape;
btRigidBody* m_Rigidbody;
btPairCachingGhostObject* m_GhostObject;
btMotionState* m_MotionState;
bool m_onGround;
//bool m_onJumpableGround; // A bit lower contact than just onGround
float m_bottomYOffset;
@@ -33,7 +34,7 @@ namespace Physics
btVector3 m_previousPosition;
float m_jumpRechargeTimer;
CharacterController(float height, float radius, float mass);
CharacterController(float height, float radius, float mass, Vector3 position);
void MoveAndSlide(glm::vec3 velocity);
private:

View File

@@ -21,6 +21,8 @@ namespace Physics
dynamicsWorld->setDebugDrawer(new BulletDebugDrawer());
m_Bodies = std::map<btRigidBody*, Ref<RigidBody>>();
SetGravity(Vector3(0, -10000, 0));
}
@@ -58,12 +60,18 @@ namespace Physics
btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo);
dynamicsWorld->rayTest(btFrom, btTo, res);
btVector3 localNormal;
if(res.m_collisionObject)
{
// TODO: Fix the godammn fucked up normal
localNormal = res.m_collisionObject->getWorldTransform().getBasis().inverse() * res.m_hitNormalWorld;
}
// Map bullet result to dto.
RaycastResult result{
glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()),
glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()),
glm::vec3(res.m_hitNormalWorld.x(), res.m_hitNormalWorld.y(), res.m_hitNormalWorld.z())
glm::vec3(localNormal.x(), localNormal.y(), localNormal.z())
};
return result;

View File

@@ -15,6 +15,21 @@ public:
}
json Serialize() {
BEGIN_SERIALIZE();
SERIALIZE_VAL(Height);
SERIALIZE_VAL(Radius);
SERIALIZE_VAL(Mass);
END_SERIALIZE();
}
bool Deserialize(const std::string str) {
BEGIN_DESERIALIZE();
Height = j["Height"];
Radius = j["Radius"];
Mass = j["Mass"];
return true;
}
void SyncWithTransform(TransformComponent& tc)
{
btVector3 pos = CharacterController->m_motionTransform.getOrigin();

View File

@@ -4,7 +4,7 @@
class NameComponent {
public:
std::string Name = "Entity";
int Id;
json Serialize()
{
BEGIN_SERIALIZE();

View File

@@ -19,6 +19,7 @@ struct ParentComponent
bool Deserialize(std::string str)
{
return true;
}

View File

@@ -78,9 +78,9 @@ void QuakeMapComponent::Build()
vertex_uv vertex_uv = get_standard_uv(vertex.vertex, face, texture->width, texture->height);
vertices.push_back(Vertex{
glm::vec3(vertex.vertex.y * (1.0f / 64), vertex.vertex.z * (1.0f / 64), vertex.vertex.x * (1.0f / 64)),
glm::vec2(vertex_uv.u, vertex_uv.v),
glm::vec3(vertex.normal.x, vertex.normal.z, vertex.normal.y),
glm::vec3(vertex.tangent.x, vertex.tangent.z, vertex.tangent.y), glm::vec3(0.0, 1.0, 0.0), 0.0f
glm::vec2(vertex_uv.u, 1.0 -vertex_uv.v),
glm::vec3(vertex.normal.y, vertex.normal.z, vertex.normal.x),
glm::vec3(vertex.tangent.y, vertex.tangent.z, vertex.tangent.x), glm::vec3(0.0, 1.0, 0.0), 0.0f
});
//printf("vertex: (%f %f %f), normal: (%f %f %f)\n",

View File

@@ -32,6 +32,7 @@ public:
{
BEGIN_DESERIALIZE();
this->Path = j["Path"];
this->HasCollisions = j["HasCollisions"];
Build(); // Maybe have some kind of loading bar or something.
return true;
}

View File

@@ -9,6 +9,7 @@
#include "Components/LightComponent.h"
#include "Components/QuakeMap.h"
#include <src/Scene/Entities/Components/WrenScriptComponent.h>
#include <src/Scene/Entities/Components/CharacterControllerComponent.h>
void Entity::AddChild(Entity ent)
{
if ((int)m_EntityHandle != ent.GetHandle())
@@ -34,6 +35,8 @@ json Entity::Serialize()
SERIALIZE_OBJECT_REF_LBL("LightComponent", GetComponent<LightComponent>());
if (HasComponent<WrenScriptComponent>())
SERIALIZE_OBJECT_REF_LBL("WrenScriptComponent", GetComponent<WrenScriptComponent>());
if (HasComponent<CharacterControllerComponent>())
SERIALIZE_OBJECT_REF_LBL("CharacterControllerComponent", GetComponent<CharacterControllerComponent>());
END_SERIALIZE();
}
@@ -47,6 +50,7 @@ bool Entity::Deserialize(const std::string& str)
DESERIALIZE_COMPONENT(QuakeMapComponent);
DESERIALIZE_COMPONENT(LightComponent);
DESERIALIZE_COMPONENT(WrenScriptComponent);
DESERIALIZE_COMPONENT(CharacterControllerComponent);
return true;
}

View File

@@ -76,7 +76,7 @@ void Scene::OnInit()
{
auto [transform, cc] = ccview.get<TransformComponent, CharacterControllerComponent>(e);
cc.CharacterController = CreateRef<Physics::CharacterController>(cc.Height, cc.Radius, cc.Mass);
cc.CharacterController = CreateRef<Physics::CharacterController>(cc.Height, cc.Radius, cc.Mass, transform.Translation);
Entity ent = Entity({ e, this });
PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController);
@@ -325,7 +325,7 @@ void Scene::Draw()
}
Renderer::m_Shader->Bind();
Renderer::m_Shader->SetUniform3f("u_EyePosition", cam->GetTranslation().x, cam->GetTranslation().y, cam->GetTranslation().z);
Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0);
if (cam)
{
@@ -348,6 +348,8 @@ void Scene::Draw()
copyT.Translation = globalOffset;
}
Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform());
Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective());
Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform());
@@ -433,7 +435,7 @@ void Scene::EditorDraw()
if (m_EditorCamera)
{
Renderer::m_Shader->SetUniform1f("u_Exposure", m_EditorCamera->Exposure);
Renderer::m_Shader->SetUniform3f("u_EyePosition", m_EditorCamera->GetTranslation().x, m_EditorCamera->GetTranslation().y, m_EditorCamera->GetTranslation().z);
auto view = m_Registry.view<TransformComponent, ModelComponent, ParentComponent>();
for (auto e : view) {
auto [transform, model, parent] = view.get<TransformComponent, ModelComponent, ParentComponent>(e);

View File

@@ -22,7 +22,11 @@ namespace ScriptAPI
void RegisterModule(WrenVM* vm) override
{
RegisterMethod("Sqrt_(_,_,_)", (void*)Sqrt);
RegisterMethod("Sin(_)", (void*)Sin);
RegisterMethod("Cos(_)", (void*)Cos);
RegisterMethod("Radians(_)", (void*)Radians);
RegisterMethod("Degrees(_)", (void*)Degrees);
RegisterMethod("Cross_(_,_,_,_,_,_)", (void*)Cross);
}
static void Sqrt(WrenVM* vm)
@@ -33,6 +37,55 @@ namespace ScriptAPI
float result = glm::sqrt((x * x) + (y * y) + (z * z));
wrenSetSlotDouble(vm, 0, result);
}
static void Cos(WrenVM* vm)
{
float d = wrenGetSlotDouble(vm, 1);
float result = glm::cos(d);
wrenSetSlotDouble(vm, 0, result);
}
static void Sin(WrenVM* vm)
{
float d = wrenGetSlotDouble(vm, 1);
float result = glm::sin(d);
wrenSetSlotDouble(vm, 0, result);
}
static void Radians(WrenVM* vm)
{
float d = wrenGetSlotDouble(vm, 1);
float result = glm::radians(d);
wrenSetSlotDouble(vm, 0, result);
}
static void Degrees(WrenVM* vm)
{
float d = wrenGetSlotDouble(vm, 1);
float result = glm::degrees(d);
wrenSetSlotDouble(vm, 0, result);
}
static void Cross(WrenVM* vm)
{
Vector3 v1 = Vector3(wrenGetSlotDouble(vm, 1),
wrenGetSlotDouble(vm, 2),
wrenGetSlotDouble(vm, 3));
Vector3 v2 = Vector3(wrenGetSlotDouble(vm, 4),
wrenGetSlotDouble(vm, 5),
wrenGetSlotDouble(vm, 6));
Vector3 cross = glm::cross(v1, v2);
wrenSetSlotNewList(vm, 0);
wrenSetSlotDouble(vm, 1, cross.x);
wrenSetSlotDouble(vm, 2, cross.y);
wrenSetSlotDouble(vm, 3, cross.z);
wrenInsertInList(vm, 0, -1, 1);
wrenInsertInList(vm, 0, -1, 2);
wrenInsertInList(vm, 0, -1, 3);
}
};

View File

@@ -0,0 +1,63 @@
#pragma once
#include "wren.h"
#include <string>
#include <src/Core/Logger.h>
#include "../Core/Maths.h"
#include "ScriptModule.h"
#include <iostream>
#include <wren.h>
#include "../Core/Physics/PhysicsManager.h"
namespace ScriptAPI
{
class PhysicsModule : public ScriptModule
{
std::string ModuleName = "Engine";
std::string GetModuleName() override
{
return "Physics";
}
void RegisterModule(WrenVM* vm) override
{
RegisterMethod("Raycast_(_,_,_,_,_,_)", (void*)Raycast);
}
static void Raycast(WrenVM* vm)
{
Vector3 v1 = Vector3(wrenGetSlotDouble(vm, 1),
wrenGetSlotDouble(vm, 2),
wrenGetSlotDouble(vm, 3));
Vector3 v2 = Vector3(wrenGetSlotDouble(vm, 4),
wrenGetSlotDouble(vm, 5),
wrenGetSlotDouble(vm, 6));
RaycastResult result = PhysicsManager::Get()->Raycast(v1, v2);
wrenSetSlotNewList(vm, 0);
// Returns a list with 3 vectors placed sequentially
// should be reconstructed in the wren side.
wrenSetSlotDouble(vm, 1, result.LocalPoint.x);
wrenSetSlotDouble(vm, 2, result.LocalPoint.y);
wrenSetSlotDouble(vm, 3, result.LocalPoint.z);
wrenSetSlotDouble(vm, 4, result.WorldPoint.x);
wrenSetSlotDouble(vm, 5, result.WorldPoint.y);
wrenSetSlotDouble(vm, 6, result.WorldPoint.z);
wrenSetSlotDouble(vm, 7, result.Normal.x - result.WorldPoint.x);
wrenSetSlotDouble(vm, 8, result.Normal.y - result.WorldPoint.y);
wrenSetSlotDouble(vm, 9, result.Normal.z - result.WorldPoint.z);
wrenInsertInList(vm, 0, -1, 1);
wrenInsertInList(vm, 0, -1, 2);
wrenInsertInList(vm, 0, -1, 3);
wrenInsertInList(vm, 0, -1, 4);
wrenInsertInList(vm, 0, -1, 5);
wrenInsertInList(vm, 0, -1, 6);
wrenInsertInList(vm, 0, -1, 7);
wrenInsertInList(vm, 0, -1, 8);
wrenInsertInList(vm, 0, -1, 9);
}
};
}

View File

@@ -29,12 +29,14 @@ namespace ScriptAPI
{
RegisterMethod("GetEntityID(_)", (void*)GetEntity);
RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent);
RegisterMethod("GetTranslation_(_)", (void*)GetTranslation);
RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity);
RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity);
RegisterMethod("SetCameraDirection_(_,_,_,_)", (void*)SetCameraDirection);
RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection);
RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight);
RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide);
RegisterMethod("IsCharacterControllerOnGround_(_)", (void*)IsCharacterControllerOnGround);
}
static void GetEntity(WrenVM* vm)
@@ -158,7 +160,14 @@ namespace ScriptAPI
wrenInsertInList(vm, 0, 2, 3);
}
static void IsCharacterControllerOnGround(WrenVM* vm)
{
int handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& characterController = ent.GetComponent<CharacterControllerComponent>();
bool result = characterController.CharacterController->IsOnGround;
wrenSetSlotBool(vm, 0, result);
}
static void MoveAndSlide(WrenVM* vm)
{
@@ -172,5 +181,22 @@ namespace ScriptAPI
characterController.CharacterController->MoveAndSlide(Vector3(x, y, z));
}
static void GetTranslation(WrenVM* vm)
{
int handle = wrenGetSlotDouble(vm, 1);
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
auto& transform = ent.GetComponent<TransformComponent>();
// set the slots
wrenSetSlotDouble(vm, 1, transform.Translation.x);
wrenSetSlotDouble(vm, 2, transform.Translation.y);
wrenSetSlotDouble(vm, 3, transform.Translation.z);
// Fill the list
wrenSetSlotNewList(vm, 0);
wrenInsertInList(vm, 0, 0, 1);
wrenInsertInList(vm, 0, 1, 2);
wrenInsertInList(vm, 0, 2, 3);
}
};
}

View File

@@ -6,6 +6,7 @@
#include <src/Scripting/Modules/SceneModule.h>
#include <src/Scripting/Modules/MathModule.h>
#include <src/Scripting/Modules/InputModule.h>
#include <src/Scripting/Modules/PhysicsModule.h>
WrenVM* ScriptingEngine::m_WrenVM;
@@ -112,6 +113,8 @@ void ScriptingEngine::Init()
RegisterModule(mathModule);
Ref<ScriptAPI::InputModule> inputModule = CreateRef<ScriptAPI::InputModule> ();
RegisterModule(inputModule);
Ref<ScriptAPI::PhysicsModule> physicsModule = CreateRef<ScriptAPI::PhysicsModule>();
RegisterModule(physicsModule);
}

View File

@@ -153,7 +153,8 @@ int Window::Init()
// TODO: Style should move to editor
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.Fonts->AddFontDefault();
//io.Fonts->AddFontDefault();
io.Fonts->AddFontFromFileTTF("resources/Fonts/OpenSans-Regular.ttf", 16.0);
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
ImGui::StyleColorsDark();

View File

@@ -7,7 +7,7 @@ After attaching the WrenScript component on an entity, you can select the script
In addition to pointing to the script file, you need to specify which class in the script is considered as the
entity script.
The class chosen must inherite from ScriptableEntity.
The class chosen must inherit from ScriptableEntity.
Here is an example of a barebone entity scripts::
@@ -16,13 +16,15 @@ Here is an example of a barebone entity scripts::
class TestScript is ScriptableEntity {
construct new() {
}
init() {
}
update(ts) {
}
exit() {