Compare commits
4 commits
7ab1364803
...
8c6f038b9f
Author | SHA1 | Date | |
---|---|---|---|
8c6f038b9f | |||
c1c088118b | |||
23baed05a6 | |||
ede0540c74 |
7 changed files with 92 additions and 14 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
|
@ -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<
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue