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) {}
InstanceRef::InstanceRef() {};
InstanceRef::InstanceRef(std::weak_ptr<Instance> instance) : ref(instance) {};
InstanceRef::InstanceRef() : ref(nullptr) {};
InstanceRef::InstanceRef(std::weak_ptr<Instance> instance) : ref(instance.expired() ? nullptr : instance.lock()) {};
InstanceRef::~InstanceRef() = default;
const TypeDesc InstanceRef::TYPE = {
@ -27,13 +27,21 @@ const TypeDesc InstanceRef::TYPE = {
};
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>() {
return ref;
}
bool InstanceRef::operator ==(InstanceRef other) const {
return this->ref == other.ref;
}
// Serialization
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_newindex(lua_State*);
static int inst_tostring(lua_State*);
static int inst_eq(lua_State*);
static const struct luaL_Reg metatable [] = {
{"__gc", inst_gc},
{"__index", inst_index},
{"__newindex", inst_newindex},
{"__tostring", inst_tostring},
{"__eq", inst_eq},
{NULL, NULL} /* end of array */
};
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);
@ -72,8 +107,13 @@ void InstanceRef::PushLuaValue(lua_State* L) const {
// Create the instance's metatable
luaL_newmetatable(L, "__mt_instance");
luaL_register(L, NULL, metatable);
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) {
@ -152,4 +192,14 @@ static int inst_tostring(lua_State* L) {
lua_pushstring(L, inst->name.c_str());
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 InstanceRef {
std::weak_ptr<Instance> ref;
std::shared_ptr<Instance> ref;
public:
InstanceRef();
InstanceRef(std::weak_ptr<Instance>);
@ -15,6 +15,7 @@ public:
static const TypeDesc TYPE;
operator std::shared_ptr<Instance>();
operator std::weak_ptr<Instance>();
virtual const std::string ToString() const;
@ -22,4 +23,6 @@ public:
virtual void PushLuaValue(lua_State*) const;
static result<InstanceRef, DataParseError> Deserialize(pugi::xml_node node);
static result<Variant, LuaCastError> FromLuaValue(lua_State*, int idx);
bool operator ==(InstanceRef) const;
};

View file

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

View file

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

View file

@ -9,6 +9,7 @@
#include "physics/util.h"
#include <memory>
#include <reactphysics3d/collision/CollisionCallback.h>
#include <reactphysics3d/collision/OverlapCallback.h>
#include <reactphysics3d/engine/PhysicsCommon.h>
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() {
if (initialized) return;
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->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();
material.setFrictionCoefficient(0.35);
material.setMassDensity(1.f);

View file

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

View file

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