Compare commits

...

4 commits

7 changed files with 92 additions and 14 deletions

View file

@ -12,8 +12,8 @@
TypeMeta::TypeMeta(const InstanceType* instType) : descriptor(&InstanceRef::TYPE), instType(instType) {} TypeMeta::TypeMeta(const InstanceType* instType) : descriptor(&InstanceRef::TYPE), instType(instType) {}
InstanceRef::InstanceRef() {}; InstanceRef::InstanceRef() : ref(nullptr) {};
InstanceRef::InstanceRef(std::weak_ptr<Instance> instance) : ref(instance) {}; InstanceRef::InstanceRef(std::weak_ptr<Instance> instance) : ref(instance.expired() ? nullptr : instance.lock()) {};
InstanceRef::~InstanceRef() = default; InstanceRef::~InstanceRef() = default;
const TypeDesc InstanceRef::TYPE = { const TypeDesc InstanceRef::TYPE = {
@ -27,13 +27,21 @@ const TypeDesc InstanceRef::TYPE = {
}; };
const std::string InstanceRef::ToString() const { const std::string InstanceRef::ToString() const {
return ref.expired() ? "" : ref.lock()->name; return ref == nullptr ? "NULL" : ref->name;
}
InstanceRef::operator std::shared_ptr<Instance>() {
return ref;
} }
InstanceRef::operator std::weak_ptr<Instance>() { InstanceRef::operator std::weak_ptr<Instance>() {
return ref; return ref;
} }
bool InstanceRef::operator ==(InstanceRef other) const {
return this->ref == other.ref;
}
// Serialization // Serialization
void InstanceRef::Serialize(pugi::xml_node node) const { void InstanceRef::Serialize(pugi::xml_node node) const {
@ -50,16 +58,43 @@ static int inst_gc(lua_State*);
static int inst_index(lua_State*); static int inst_index(lua_State*);
static int inst_newindex(lua_State*); static int inst_newindex(lua_State*);
static int inst_tostring(lua_State*); static int inst_tostring(lua_State*);
static int inst_eq(lua_State*);
static const struct luaL_Reg metatable [] = { static const struct luaL_Reg metatable [] = {
{"__gc", inst_gc}, {"__gc", inst_gc},
{"__index", inst_index}, {"__index", inst_index},
{"__newindex", inst_newindex}, {"__newindex", inst_newindex},
{"__tostring", inst_tostring}, {"__tostring", inst_tostring},
{"__eq", inst_eq},
{NULL, NULL} /* end of array */ {NULL, NULL} /* end of array */
}; };
void InstanceRef::PushLuaValue(lua_State* L) const { void InstanceRef::PushLuaValue(lua_State* L) const {
if (ref.expired()) return lua_pushnil(L); if (ref == nullptr) return lua_pushnil(L);
// Get or create InstanceRef table
lua_getfield(L, LUA_REGISTRYINDEX, "__instances");
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
lua_newtable(L);
// Set metatable
lua_newtable(L);
lua_pushstring(L, "kv");
lua_setfield(L, -2, "__mode");
lua_setmetatable(L, -2);
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, "__instances");
}
// Check if value already exists, and if so, return that instead
lua_pushlightuserdata(L, ref.get());
lua_rawget(L, -2);
if (!lua_isnil(L, -1)) {
lua_remove(L, -2); // Remove __instances
return;
}
lua_pop(L, 1);
int n = lua_gettop(L); int n = lua_gettop(L);
@ -72,8 +107,13 @@ void InstanceRef::PushLuaValue(lua_State* L) const {
// Create the instance's metatable // Create the instance's metatable
luaL_newmetatable(L, "__mt_instance"); luaL_newmetatable(L, "__mt_instance");
luaL_register(L, NULL, metatable); luaL_register(L, NULL, metatable);
lua_setmetatable(L, n+1); lua_setmetatable(L, n+1);
// Add instance to __instances
lua_pushlightuserdata(L, ref.get());
lua_pushvalue(L, -2); // Push userdata
lua_rawset(L, -4); // Put into __instance
lua_remove(L, -2); // Remove __instance
} }
result<Variant, LuaCastError> InstanceRef::FromLuaValue(lua_State* L, int idx) { result<Variant, LuaCastError> InstanceRef::FromLuaValue(lua_State* L, int idx) {
@ -152,4 +192,14 @@ static int inst_tostring(lua_State* L) {
lua_pushstring(L, inst->name.c_str()); lua_pushstring(L, inst->name.c_str());
return 1; return 1;
} }
static int inst_eq(lua_State* L) {
auto userdata = (std::shared_ptr<Instance>**)lua_touserdata(L, 1);
std::shared_ptr<Instance> inst = **userdata;
auto userdata2 = (std::shared_ptr<Instance>**)luaL_checkudata(L, 2, "__mt_instance");
std::shared_ptr<Instance> inst2 = **userdata2;
lua_pushboolean(L, inst == inst2);
return 1;
}

View file

@ -7,7 +7,7 @@
class Instance; class Instance;
class InstanceRef { class InstanceRef {
std::weak_ptr<Instance> ref; std::shared_ptr<Instance> ref;
public: public:
InstanceRef(); InstanceRef();
InstanceRef(std::weak_ptr<Instance>); InstanceRef(std::weak_ptr<Instance>);
@ -15,6 +15,7 @@ public:
static const TypeDesc TYPE; static const TypeDesc TYPE;
operator std::shared_ptr<Instance>();
operator std::weak_ptr<Instance>(); operator std::weak_ptr<Instance>();
virtual const std::string ToString() const; virtual const std::string ToString() const;
@ -22,4 +23,6 @@ public:
virtual void PushLuaValue(lua_State*) const; virtual void PushLuaValue(lua_State*) const;
static result<InstanceRef, DataParseError> Deserialize(pugi::xml_node node); static result<InstanceRef, DataParseError> Deserialize(pugi::xml_node node);
static result<Variant, LuaCastError> FromLuaValue(lua_State*, int idx); static result<Variant, LuaCastError> FromLuaValue(lua_State*, int idx);
bool operator ==(InstanceRef) const;
}; };

View file

@ -12,12 +12,12 @@
#include "vector.h" #include "vector.h"
#include "cframe.h" #include "cframe.h"
// #define __VARIANT_TYPE std::variant< \ // #define __VARIANT_TYPE std::variant< \_
// Null, \ // Null, \_
// Bool, \ // Bool, \_
// Int, \ // Int, \_
// Float, \ // Float, \_
// String \ // String \_
// > // >
typedef std::variant< typedef std::variant<

View file

@ -70,6 +70,7 @@ public:
DEF_PROP_CATEGORY(BEHAVIOR) DEF_PROP_CATEGORY(BEHAVIOR)
DEF_PROP_(on_update=onUpdated) bool anchored = false; DEF_PROP_(on_update=onUpdated) bool anchored = false;
DEF_PROP_(on_update=onUpdated) bool canCollide = true;
DEF_PROP bool locked = false; DEF_PROP bool locked = false;
DEF_PROP_CATEGORY(SURFACE) DEF_PROP_CATEGORY(SURFACE)

View file

@ -9,6 +9,7 @@
#include "physics/util.h" #include "physics/util.h"
#include <memory> #include <memory>
#include <reactphysics3d/collision/CollisionCallback.h> #include <reactphysics3d/collision/CollisionCallback.h>
#include <reactphysics3d/collision/OverlapCallback.h>
#include <reactphysics3d/engine/PhysicsCommon.h> #include <reactphysics3d/engine/PhysicsCommon.h>
rp::PhysicsCommon* Workspace::physicsCommon = new rp::PhysicsCommon; rp::PhysicsCommon* Workspace::physicsCommon = new rp::PhysicsCommon;
@ -42,6 +43,25 @@ void PhysicsEventListener::onContact(const rp::CollisionCallback::CallbackData&
} }
} }
void PhysicsEventListener::onTrigger(const rp::OverlapCallback::CallbackData& data) {
for (size_t i = 0; i < data.getNbOverlappingPairs(); i++) {
auto pair = data.getOverlappingPair(i);
auto type = pair.getEventType();
if (type == rp::OverlapCallback::OverlapPair::EventType::OverlapStay) continue;
auto part0 = reinterpret_cast<Part*>(pair.getBody1()->getUserData())->shared<Part>();
auto part1 = reinterpret_cast<Part*>(pair.getBody2()->getUserData())->shared<Part>();
if (type == reactphysics3d::OverlapCallback::OverlapPair::EventType::OverlapStart) {
part0->Touched->Fire({ (Variant)InstanceRef(part1) });
part1->Touched->Fire({ (Variant)InstanceRef(part0) });
} else if (type == reactphysics3d::OverlapCallback::OverlapPair::EventType::OverlapExit) {
part0->TouchEnded->Fire({ (Variant)InstanceRef(part1) });
part1->TouchEnded->Fire({ (Variant)InstanceRef(part0) });
}
}
}
void Workspace::InitService() { void Workspace::InitService() {
if (initialized) return; if (initialized) return;
initialized = true; initialized = true;
@ -107,6 +127,9 @@ void Workspace::SyncPartPhysics(std::shared_ptr<Part> part) {
part->rigidBody->setType(part->anchored ? rp::BodyType::STATIC : rp::BodyType::DYNAMIC); part->rigidBody->setType(part->anchored ? rp::BodyType::STATIC : rp::BodyType::DYNAMIC);
part->rigidBody->getCollider(0)->setCollisionCategoryBits(0b11); part->rigidBody->getCollider(0)->setCollisionCategoryBits(0b11);
part->rigidBody->getCollider(0)->setIsSimulationCollider(part->canCollide);
part->rigidBody->getCollider(0)->setIsTrigger(!part->canCollide);
rp::Material& material = part->rigidBody->getCollider(0)->getMaterial(); rp::Material& material = part->rigidBody->getCollider(0)->getMaterial();
material.setFrictionCoefficient(0.35); material.setFrictionCoefficient(0.35);
material.setMassDensity(1.f); material.setMassDensity(1.f);

View file

@ -44,6 +44,7 @@ class PhysicsEventListener : public rp::EventListener {
PhysicsEventListener(Workspace*); PhysicsEventListener(Workspace*);
void onContact(const rp::CollisionCallback::CallbackData&) override; void onContact(const rp::CollisionCallback::CallbackData&) override;
void onTrigger(const rp::OverlapCallback::CallbackData&) override;
}; };
class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service { class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service {

View file

@ -476,7 +476,7 @@ void renderOutlines() {
// Render AABB of selected parts // Render AABB of selected parts
PartAssembly selectionAssembly = PartAssembly::FromSelection(); PartAssembly selectionAssembly = PartAssembly::FromSelection();
if (!selectionAssembly.multipleSelected()) return; if (selectionAssembly.size() == Vector3()) return;
glm::vec3 outlineSize = selectionAssembly.bounds(); glm::vec3 outlineSize = selectionAssembly.bounds();
glm::vec3 outlinePos = selectionAssembly.assemblyOrigin().Position(); glm::vec3 outlinePos = selectionAssembly.assemblyOrigin().Position();