Jump to content

SpiderPig

Members
  • Posts

    2,348
  • Joined

  • Last visited

Everything posted by SpiderPig

  1. It works flawlessly if I delete the actor and component and then remake them. So I'd say the above post shows a bug in the Collide method. void EnableRidgedBody(bool state) { if (state == true) { is_rigid_body = true; is_airborne = true; auto collider = CreateCylinderCollider(0.5f, 1.8f); if (rigid_body == nullptr) { rigid_body = CreatePivot(world); rigid_body->SetShadows(true); rigid_body->SetCollider(collider); rigid_body->SetCollisionType(COLLISION_PLAYER); rigid_body->SetMass(1.0f); } actor = CreateActor(rigid_body); callback = actor->AddComponent<CollisionCallback>(); model->SetParent(rigid_body); } else { is_rigid_body = false; is_airborne = false; model->SetParent(nullptr); model->SetRotation(0.0f, 0.0f, 0.0f); callback = nullptr; actor = nullptr; } }
  2. The idea here is to switch between a rigid body when physics is needed and a kinematic joint when control is needed. This might end up working but right now the Collide method in the CallbackCollision component is not being called a second time round... If you wait for the player to fall, is_rigid_body will set to False, then hit space to jump, the player will jump and fall again but this time will not trigger the collide method. The component is still attached and is still calling the update method. A bug perhaps or bad coding by me? #include "UltraEngine.h" #include "ComponentSystem.h" using namespace UltraEngine; class Player { public: shared_ptr<World> world = nullptr; shared_ptr<Model> model = nullptr; shared_ptr<Entity> rigid_body, controller_body; shared_ptr<Actor> actor = nullptr; shared_ptr<CollisionCallback> callback = nullptr; shared_ptr<Joint> joint = nullptr; bool is_controlable = false; bool is_rigid_body = false; bool is_airborne = false; Player(shared_ptr<World> world) { this->world = world; model = CreateCylinder(world, 0.5f, 1.8f); model->SetCollider(nullptr); model->SetColor(1, 0, 0); EnableRidgedBody(true); } ~Player() {} void SetPosition(float x, float y, float z) { if (is_rigid_body) { rigid_body->SetPosition(x, y, z); } } void EnableRidgedBody(bool state) { if (state == true) { is_rigid_body = true; is_airborne = true; auto collider = CreateCylinderCollider(0.5f, 1.8f); if (rigid_body == nullptr) { rigid_body = CreatePivot(world); rigid_body->SetShadows(true); rigid_body->SetCollider(collider); rigid_body->SetCollisionType(COLLISION_PLAYER); rigid_body->SetMass(1.0f); actor = CreateActor(rigid_body); callback = actor->AddComponent<CollisionCallback>(); } model->SetParent(rigid_body); } else { is_rigid_body = false; is_airborne = false; model->SetParent(nullptr); model->SetRotation(0.0f, 0.0f, 0.0f); // callback = nullptr; // actor = nullptr; //rigid_body = nullptr; } } void EnableController(bool state) { if (state == true) { is_controlable = true; if (joint == nullptr) { auto pos = model->GetPosition(true); auto col = CreateCylinderCollider(0.5f, 1.8f); controller_body = CreatePivot(world); controller_body->SetShadows(true); controller_body->SetCollider(col); controller_body->SetCollisionType(COLLISION_NONE); controller_body->SetMass(1.0f); controller_body->SetPosition(pos, true); joint = CreateKinematicJoint(pos, controller_body); } model->SetParent(controller_body); } else { // joint = nullptr; // controller_body = nullptr; is_controlable = false; } } void SetInput(float move, float angle) { } void Update() { if (is_airborne == true && callback->collided == true) { auto vel = rigid_body->GetVelocity(true); auto speed_sqr = (vel.x * vel.x) + (vel.y * vel.y) + (vel.z * vel.z); if (speed_sqr < FLT_EPSILON) { callback->collided = false; EnableRidgedBody(false); EnableController(true); } } if (is_controlable == true) { auto target_position = model->GetPosition(true); auto angle = 0.0f; auto up = Vec3(0.0f, 1.0f, 0.0f); auto window = ActiveWindow(); if (window != nullptr) { if (window->KeyDown(KEY_UP)) {} if (window->KeyHit(KEY_SPACE)) { EnableController(false); EnableRidgedBody(true); rigid_body->AddForce(up * 250.0f); } else { joint->SetPose(target_position, Vec3(0.0f)); } } } } }; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 1440, 900, displays[0]); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto camera = CreateCamera(world); camera->Move(0, 2, -3); camera->SetClearColor(1, 0, 0); auto light = CreateDirectionalLight(world); light->SetRotation(35, 35, 35); auto floor = CreateBox(world, 100.0f, 0.5f, 100.0f); auto default_font = LoadFont("Fonts\\arial.ttf"); auto ui = CreateInterface(world, default_font, framebuffer->size); ui->SetRenderLayers(2); ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.0f); auto ui_camera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); ui_camera->SetPosition((float)framebuffer->size.x * 0.5f, (float)framebuffer->size.y * 0.5f, 0); ui_camera->SetRenderLayers(2); ui_camera->SetClearMode(CLEAR_DEPTH); auto label = CreateLabel("", 10, 10, 500, 200, ui->root); auto player = make_shared<Player>(world); player->SetPosition(0, 5, 0); while (window->KeyHit(KEY_ESCAPE) == false && window->Closed() == false) { while (PeekEvent()) { ui->ProcessEvent(WaitEvent()); } player->Update(); auto pos = player->model->GetPosition(true); auto rot = player->model->GetRotation(); WString text = "Position : " + String(pos.x) + ", " + String(pos.y) + ", " + String(pos.z) + "\n" + "Rotation : " + String(rot.x) + ", " + String(rot.y) + ", " + String(rot.z) + "\n" + "Rigid Body : " + String(player->is_rigid_body == true ? "True" : "False") + "\n" + "Collide : " + String(player->callback->collided == true ? "True" : "False") + "\n" + "Collision Count : " + String(player->callback->collision_count) + "\n" + "Still Updating : " + String(player->callback->is_updating == true ? "True" : "False"); label->SetText(text); player->callback->is_updating = false; world->Update(); world->Render(framebuffer); } return 0; } Component: #pragma once #include "UltraEngine.h" #include "../ComponentSystem.h" class CollisionCallback : public Component { private: public: bool collided = false, is_updating = false; int collision_count = 0; virtual void Update() { is_updating = true; } virtual void Collide(shared_ptr<Actor> collidedactor, const Vec3& position, const Vec3& normal, const dFloat speed) { collided = true; collision_count++; } };
  3. Actually... why does a parents shadow mode effect it's children's?
  4. Ah yes, that fixes it. Maybe this should be done by default though?
  5. I think I may have addressed this before but can't remember... an entity will not cast a shadow if it has a pivot as a parent. #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0]); auto world = CreateWorld(); auto framebuffer = CreateFramebuffer(window); auto camera = CreateCamera(world); camera->SetClearColor(0.0f, 0.0f, 1.0f); camera->SetFov(70); camera->SetRange(0.01f, 1000.0f); camera->SetPosition(0, 1, -3); auto light = CreateDirectionalLight(world); light->SetColor(5.0f); light->SetRotation(35, 45, 0); auto floor = CreateBox(world, 100.0f, 0.1f, 100.0f); auto pivot = CreatePivot(world); auto box = CreateBox(world); box->SetParent(pivot); pivot->SetPosition(0.0f, 2.0f, 0.0f); while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer, false); } return 0; }
  6. I thought it might be too fast. Just posted it encase it shed light on an underlying issue.
  7. Alternatively if we had access to the newton world and entities bodies we could probably use newton commands ourselves. float pin[3] = {0, 1, 0}; auto joint = NewtonConstraintCreateUpVector(world->GetPhysicsWorld(), pin, entity->GetBody())
  8. Looking great! Are you using the geometry shader to generate the grass?
  9. I don't know if this is a bug, but I think it should work? Pressing space sets the joint to nullptr and should no longer control the entity? Would also be good if we can disable the joint without deleting it... and then re-enable it again a while later. E.g. Allow an object to be intermittingly controlled and succumb to gravity at a key press. #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0]); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto camera = CreateCamera(world); camera->Move(0, 2, -3); camera->SetClearColor(1, 0, 0); auto light = CreateDirectionalLight(world); light->SetRotation(35, 35, 35); auto floor = CreateBox(world, 100.0f, 0.5f, 100.0f); auto default_font = LoadFont("Fonts\\arial.ttf"); auto ui = CreateInterface(world, default_font, framebuffer->size); ui->SetRenderLayers(2); ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.0f); auto ui_camera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); ui_camera->SetPosition((float)framebuffer->size.x * 0.5f, (float)framebuffer->size.y * 0.5f, 0); ui_camera->SetRenderLayers(2); ui_camera->SetClearMode(CLEAR_DEPTH); auto label = CreateLabel("", 10, 10, 500, 200, ui->root); auto m = CreateCylinder(world, 0.5f, 1.8f); m->SetMass(1.0f); m->SetPosition(0, 2, 0); camera->SetParent(m); auto joint = CreateKinematicJoint(0.0f, 2.0f, 0.0f, m); joint->SetMaxForce(FLT_MAX); while (true) { while (PeekEvent()) { ui->ProcessEvent(WaitEvent()); } auto pos = m->GetPosition(true); auto rot = m->GetRotation(); label->SetText("Position : " + String(pos.x) + ", " + String(pos.y) + ", " + String(pos.z) + "\n" + "Rotation : " + String(rot.x) + ", " + String(rot.y) + ", " + String(rot.z)); if (window->KeyHit(KEY_SPACE)) { joint = nullptr; } if (joint != nullptr) { auto target_pos = pos; if (window->KeyDown(KEY_W)) { target_pos.z += 1.0f; } if (window->KeyDown(KEY_S)) { target_pos.z -= 1.0f; } joint->SetPose(target_pos, Vec3(0, 0, 0)); } world->Update(); world->Render(framebuffer); } return 0; }
  10. Not a big deal but here it is anyway. Tap the W key quickly and you will see that the shadow lags and creates a dark spot briefly on the cylinder. #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0]); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto camera = CreateCamera(world); camera->Move(0, 2, -3); camera->SetClearColor(1, 0, 0); auto light = CreateDirectionalLight(world); light->SetRotation(35, 35, 35); auto floor = CreateBox(world, 100.0f, 0.5f, 100.0f); auto default_font = LoadFont("Fonts\\arial.ttf"); auto ui = CreateInterface(world, default_font, framebuffer->size); ui->SetRenderLayers(2); ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.0f); auto ui_camera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); ui_camera->SetPosition((float)framebuffer->size.x * 0.5f, (float)framebuffer->size.y * 0.5f, 0); ui_camera->SetRenderLayers(2); ui_camera->SetClearMode(CLEAR_DEPTH); auto label = CreateLabel("", 10, 10, 500, 200, ui->root); auto m = CreateCylinder(world, 0.5f, 1.8f); m->SetMass(1.0f); m->SetPosition(0, 2, 0); camera->SetParent(m); auto joint = CreateKinematicJoint(0.0f, 2.0f, 0.0f, m); joint->SetMaxForce(FLT_MAX); while (true) { while (PeekEvent()) { ui->ProcessEvent(WaitEvent()); } auto pos = m->GetPosition(true); auto rot = m->GetRotation(); label->SetText("Position : " + String(pos.x) + ", " + String(pos.y) + ", " + String(pos.z) + "\n" + "Rotation : " + String(rot.x) + ", " + String(rot.y) + ", " + String(rot.z)); auto target_pos = pos; if (window->KeyDown(KEY_W)) { target_pos.z += 1.0f; } if (window->KeyDown(KEY_S)) { target_pos.z -= 1.0f; } joint->SetPose(target_pos, Vec3(0,0,0)); world->Update(); world->Render(framebuffer); } return 0; }
  11. Hmm, it possibly will then. I'll try it. I'm sure the vector joint would still come in handy though.
  12. I'm not sure... a kinematic joint would allow rotation on all three axis still? A vector joint only allows rotation around the vector itself.
  13. I think Leadwerks had this... can we get this for Ultra too? CreateVectorJoint() Would also need to change its pin as well... something Leadwerks didn't allow from memory. vector->SetPin(0, 1, 0)
  14. I use AddForce() for moving physics bodies toward multiple gravity sources so I need a controller that will respond to that as well as being able to have the up direction dynamically changed.
  15. In Leadwerks I used to be able to make a player controller and turn off gravity for that entity and just use AddForce() for my own gravity system. I didn't see a problem with doing it this way for rigid bodies, but I never did think it was a good idea for the character controller. Doesn't seem to work in Ultra anyway and in all fairness that's okay because I am going to have to make my own controller I think. I'm going to post a few attempts here and see if I can't finally get this to work the way I want! This used to work in Leadwerks: #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0]); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto camera = CreateCamera(world); camera->Move(0, 2, -3); camera->SetClearColor(1, 0, 0); auto light = CreateDirectionalLight(world); light->SetRotation(35, 35, 35); auto floor = CreateBox(world, 100.0f, 0.5f, 100.0f); auto default_font = LoadFont("Fonts\\arial.ttf"); auto ui = CreateInterface(world, default_font, framebuffer->size); ui->SetRenderLayers(2); ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.0f); auto ui_camera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); ui_camera->SetPosition((float)framebuffer->size.x * 0.5f, (float)framebuffer->size.y * 0.5f, 0); ui_camera->SetRenderLayers(2); ui_camera->SetClearMode(CLEAR_DEPTH); auto m = CreateCylinder(world, 0.5f, 1.8f); m->SetPhysicsMode(PHYSICS_PLAYER); m->SetPosition(0, 5, 0); m->SetMass(1.0f); m->SetGravityMode(false); while (true) { m->AddForce(0.0f, -9.8f, 0.0f); world->Update(); world->Render(framebuffer); } return 0; }
  16. I've only had this happen when using a custom widget. If you hide the parent of the custom widget before at least one loop it will crash. #include "Engine.h" using namespace UltraEngine; //Declare new style constants enum CustomWidgetStyle { CUSTOMWIDGET_DEFAULT = 0 }; //Declare new widget class class CustomWidget : public Widget { bool hover; protected: virtual bool Initialize(const WString& text, const int x, const int y, const int width, const int height, shared_ptr<Widget> parent, const int style) { return Widget::Initialize(text, x, y, width, height, parent, style); } //Called when the mouse moves if this widget has the focus virtual void MouseMove(const int x, const int y) {} //Called when the mouse cursor enters the widget bounds virtual void MouseEnter(const int x, const int y) { hover = true; Redraw(); } //Called when the mouse cursor leaves the widget bounds virtual void MouseLeave(const int x, const int y) { hover = false; Redraw(); } //Called when the mouse button is pressed virtual void MouseDown(const MouseButton button, const int x, const int y) { if (button == MOUSE_LEFT) EmitEvent(EVENT_WIDGETACTION, Self()); } //Called when the mouse button is released virtual void MouseUp(const MouseButton button, const int x, const int y) {} //Called when another widget becomes selected virtual void LoseFocus() {} //Called when mouse double-click occurs virtual void DoubleClick(const MouseButton button, const int x, const int y) {} //Called when mouse triple-click occurs virtual void TripleClick(const MouseButton button, const int x, const int y) {} //Called when widget is selected virtual void GainFocus() {} //Called when key is pressed virtual void KeyDown(const KeyCode key) {} //Called when key is released virtual void KeyUp(const KeyCode key) {} //Called for each keydown event virtual void KeyChar(const int keychar) {} //Called when mouse wheel turns and mouse is hovered over this widget virtual void MouseWheel(const int delta, const int x, const int y) {} //Called each time the widget is redrawn virtual void Draw(const int x, const int y, const int width, const int height) { blocks.clear(); AddBlock("Text", iVec2(0), this->size, Vec4(1), TEXT_CENTER | TEXT_MIDDLE); } public: //Constructor CustomWidget() : hover(false) {} friend shared_ptr<Widget> CreateCustomWidget(const WString&, const int, const int, const int, const int, shared_ptr<Widget>, const CustomWidgetStyle); }; //Create function shared_ptr<Widget> CreateCustomWidget(const WString& text, const int x, const int y, const int width, const int height, shared_ptr<Widget> parent, const CustomWidgetStyle style) { auto widget = std::make_shared<CustomWidget>(); widget->Initialize(text, x, y, width, height, parent, style); return widget; } int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0]); auto framebuffer = CreateFramebuffer(window); auto world = CreateWorld(); auto camera = CreateCamera(world); camera->Move(0, 0, -3); camera->SetClearColor(1, 0, 0); auto box = CreateBox(world); auto default_font = LoadFont("Fonts\\arial.ttf"); auto ui = CreateInterface(world, default_font, framebuffer->size); ui->SetRenderLayers(2); ui->root->SetColor(0.0f, 0.0f, 0.0f, 0.0f); auto ui_camera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); ui_camera->SetPosition((float)framebuffer->size.x * 0.5f, (float)framebuffer->size.y * 0.5f, 0); ui_camera->SetRenderLayers(2); ui_camera->SetClearMode(CLEAR_DEPTH); //Create widget auto panel = CreatePanel(10, 10, 100, 100, ui->root); auto widget = CreateCustomWidget("Custom", 20, 20, 50, 30, panel, CUSTOMWIDGET_DEFAULT); while (true) { panel->SetHidden(true);//Causes crash while (PeekEvent()) { auto ev = WaitEvent(); ui->ProcessEvent(ev); } // panel->SetHidden(true);//No crash here world->Update(); world->Render(framebuffer); } return 0; }
  17. I believe it is just like calling Abs() for each of the x, y & z components of the vector. Saves time writing it out all the time. Vec3 Abs(Vec3 value) { value.x = Abs(value.x); value.y = Abs(value.y); value.z = Abs(value.z); return value; }
  18. Can we get Abs() to take a Vec3? 🤔
  19. Ah yes. That did the trick. GetBounds(BOUNDS_RECURSIVE)
  20. The bounds are returning 0 size for some objects I'm loading. I think its when there are two or more entities in the file. Here cube1 shows the correct bounds size but cube2 (has two cubes in it) returns 0. #include "Engine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { auto displays = GetDisplays(); auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0]); auto world = CreateWorld(); auto framebuffer = CreateFramebuffer(window); auto camera = CreateCamera(world); camera->SetClearColor(0.0f, 0.0f, 1.0f); camera->SetFov(70); camera->SetRange(0.01f, 1000.0f); camera->SetPosition(0, 1, -3); auto light = CreateDirectionalLight(world); light->SetColor(5.0f); light->SetRotation(35, 45, 0); auto font = LoadFont("Fonts/arial.ttf"); auto ui = CreateInterface(world, font, framebuffer->size); ui->SetRenderLayers(2); ui->root->SetColor(0, 0, 0, 0); auto ui_cam = CreateCamera(world, PROJECTION_ORTHOGRAPHIC); ui_cam->SetPosition(framebuffer->size.x / 2, framebuffer->size.y / 2, 0); ui_cam->SetRenderLayers(2); ui_cam->SetClearMode(CLEAR_DEPTH); auto label = CreateLabel("", 10, 10, 200, 30, ui->root); auto cube1 = LoadModel(world, "Cube.gltf"); auto cube2 = LoadModel(world, "Cube2.gltf"); auto b1 = cube1->GetBounds(); auto b2 = cube2->GetBounds(); while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { label->SetText("Size1 : " + String(b1.size.x) + ", " + String(b1.size.y) + ", " + String(b1.size.z) + "\n" "Size2 : " + String(b2.size.x) + ", " + String(b2.size.y) + ", " + String(b2.size.z)); world->Update(); world->Render(framebuffer, false); } return 0; } Cubes.zip
  21. I think I just need better environment maps.
  22. Okay now that I see them side by side they're not too much different. The one in blender does look better though. Looks more specular. Lighting is not my strength. Blender: Game:
  23. I thought it might look better. Although the colours do look more washed out than in blender. Especially the greys. I'll take a screenshot...
  24. I'm going to be using a lot of low poly assets (flat shading and plain colours - only a diffuse texture which sets the colour per triangle) and I'm not sure if the PBR lighting should be used still or if I should use the classic shading?
×
×
  • Create New...