mirror of
https://github.com/Relintai/godot-lportal.git
synced 2024-11-11 10:52:09 +01:00
Allow multiportal views
Multiple portals can view into a room. Added functions for querying current room of DOB.
This commit is contained in:
parent
4fa3991280
commit
7cad808ebe
@ -139,6 +139,7 @@ void LPortal::CreateGeometry(PoolVector<Vector3> p_vertices, const Transform &tr
|
||||
{
|
||||
Vector3 ptWorld = trans.xform(p_vertices[n]);
|
||||
m_ptsWorld.set(n, ptWorld);
|
||||
m_ptCentre += ptWorld;
|
||||
|
||||
print("\t\t" + itos(n) + "\tLocal : " + Variant(p_vertices[n]) + "\tWorld : " + ptWorld);
|
||||
}
|
||||
@ -166,6 +167,7 @@ void LPortal::SortVertsClockwise()
|
||||
ptCentre += verts[n];
|
||||
}
|
||||
ptCentre /= nPoints;
|
||||
m_ptCentre = ptCentre;
|
||||
|
||||
|
||||
// now algorithm
|
||||
@ -238,6 +240,7 @@ void LPortal::CopyReversedGeometry(const LPortal &source)
|
||||
print("CopyReversedGeometry");
|
||||
// points are the same but reverse winding order
|
||||
int nPoints = source.m_ptsWorld.size();
|
||||
m_ptCentre = source.m_ptCentre;
|
||||
|
||||
m_ptsWorld.resize(nPoints);
|
||||
|
||||
@ -268,6 +271,7 @@ void LPortal::PlaneFromPoints()
|
||||
LPortal::LPortal() {
|
||||
// unset
|
||||
m_iRoomNum = -1;
|
||||
// m_uiFrameTouched_Blocked = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -54,8 +54,12 @@ public:
|
||||
|
||||
// normal determined by winding order
|
||||
Vector<Vector3> m_ptsWorld;
|
||||
Vector3 m_ptCentre; // world
|
||||
Plane m_Plane;
|
||||
|
||||
// frame counter when last touched .. prevents going backward through portals
|
||||
//unsigned int m_uiFrameTouched_Blocked;
|
||||
|
||||
LPortal();
|
||||
|
||||
void CopyReversedGeometry(const LPortal &source);
|
||||
|
72
lroom.cpp
72
lroom.cpp
@ -52,7 +52,7 @@ Spatial * LRoom::GetGodotRoom() const
|
||||
|
||||
|
||||
|
||||
void LRoom::AddDOB(Spatial * pDOB)
|
||||
void LRoom::DOB_Add(Spatial * pDOB)
|
||||
{
|
||||
LDob dob;
|
||||
dob.m_ID = pDOB->get_instance_id();
|
||||
@ -60,7 +60,7 @@ void LRoom::AddDOB(Spatial * pDOB)
|
||||
m_DOBs.push_back(dob);
|
||||
}
|
||||
|
||||
bool LRoom::RemoveDOB(Node * pDOB)
|
||||
bool LRoom::DOB_Remove(Node * pDOB)
|
||||
{
|
||||
ObjectID id = pDOB->get_instance_id();
|
||||
|
||||
@ -78,11 +78,15 @@ bool LRoom::RemoveDOB(Node * pDOB)
|
||||
|
||||
|
||||
// returns -1 if no change, or the linked room we are moving into
|
||||
LRoom * LRoom::UpdateDOB(LRoomManager &manager, Spatial * pDOB)
|
||||
LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB)
|
||||
{
|
||||
const Vector3 &pt = pDOB->get_global_transform().origin;
|
||||
|
||||
const float slop = 0.2f;
|
||||
// is it the camera?
|
||||
bool bCamera = pDOB->get_instance_id() == manager.m_cameraID;
|
||||
float slop = 0.2f;
|
||||
if (bCamera)
|
||||
slop = 0.0f;
|
||||
|
||||
// the camera can't have slop because we might end up front side of a door without entering the room,
|
||||
// hence can't see into the room through the portal!
|
||||
@ -109,6 +113,27 @@ LRoom * LRoom::UpdateDOB(LRoomManager &manager, Spatial * pDOB)
|
||||
}
|
||||
|
||||
|
||||
void LRoom::FirstTouch(LRoomManager &manager)
|
||||
{
|
||||
// set the frame counter
|
||||
m_uiFrameTouched = manager.m_uiFrameCounter;
|
||||
|
||||
// keep track of which rooms are shown this frame
|
||||
manager.m_pCurr_VisibleRoomList->push_back(m_RoomID);
|
||||
|
||||
// hide all objects
|
||||
for (int n=0; n<m_SOBs.size(); n++)
|
||||
{
|
||||
const LSob sob = m_SOBs[n];
|
||||
Object * pNode = ObjectDB::get_instance(sob.m_ID);
|
||||
VisualInstance * pObj = Object::cast_to<VisualInstance>(pNode);
|
||||
|
||||
if (pObj)
|
||||
pObj->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, const LCamera &cam, const LVector<Plane> &planes, int portalID_from)
|
||||
{
|
||||
// prevent too much depth
|
||||
@ -125,13 +150,7 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
||||
|
||||
// first touch
|
||||
if (m_uiFrameTouched < manager.m_uiFrameCounter)
|
||||
{
|
||||
// set the frame counter
|
||||
m_uiFrameTouched = manager.m_uiFrameCounter;
|
||||
|
||||
// keep track of which rooms are shown this frame
|
||||
manager.m_pCurr_VisibleRoomList->push_back(m_RoomID);
|
||||
}
|
||||
FirstTouch(manager);
|
||||
|
||||
// show this room and add to visible list of rooms
|
||||
GetGodotRoom()->show();
|
||||
@ -178,8 +197,8 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
||||
|
||||
if (bShow)
|
||||
pObj->show();
|
||||
else
|
||||
pObj->hide();
|
||||
// else
|
||||
// pObj->hide();
|
||||
|
||||
}
|
||||
}
|
||||
@ -202,17 +221,25 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
||||
if (pLinkedRoom->m_uiFrameTouched == manager.m_uiFrameCounter)
|
||||
continue;
|
||||
|
||||
// const Vector3 &portal_normal = pPortal->m_Plane.normal;
|
||||
// print("\ttesting portal " + pPortal->get_name() + " normal " + portal_normal);
|
||||
// cull by portal angle to camera.
|
||||
// Note we need to deal with 'side on' portals, and the camera has a spreading view, so we cannot simply dot
|
||||
// the portal normal with camera direction, we need to take into account angle to the portal itself.
|
||||
const Vector3 &portal_normal = port.m_Plane.normal;
|
||||
print("\ttesting portal " + port.get_name() + " normal " + portal_normal);
|
||||
|
||||
// we will dot the portal angle with a ray from the camera to the portal centre
|
||||
// (there might be an even better ray direction but this will do for now)
|
||||
Vector3 dir_portal = port.m_ptCentre - cam.m_ptPos;
|
||||
|
||||
// doesn't actually need to be normalized?
|
||||
float dot = dir_portal.dot(portal_normal);
|
||||
|
||||
// direction with the camera? (might not need to check)
|
||||
// float dot = cam.m_ptDir.dot(portal_normal);
|
||||
// if (dot <= -0.0f) // 0.0
|
||||
// {
|
||||
// Variant vd = dot;
|
||||
// print("\t\tportal culled (wrong direction) dot is " + String(vd));
|
||||
// continue;
|
||||
// }
|
||||
if (dot <= -0.0f) // 0.0
|
||||
{
|
||||
print("\t\tportal culled (wrong direction) dot is " + String(Variant(dot)) + ", dir_portal is " + dir_portal);
|
||||
continue;
|
||||
}
|
||||
|
||||
// is it culled by the planes?
|
||||
LPortal::eClipResult overall_res = LPortal::eClipResult::CLIP_INSIDE;
|
||||
@ -259,6 +286,7 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
|
||||
// add the planes for the portal
|
||||
port.AddPlanes(cam.m_ptPos, new_planes);
|
||||
|
||||
|
||||
if (pLinkedRoom)
|
||||
pLinkedRoom->DetermineVisibility_Recursive(manager, depth + 1, cam, new_planes, port_id);
|
||||
|
||||
|
7
lroom.h
7
lroom.h
@ -85,11 +85,12 @@ public:
|
||||
protected:
|
||||
// main function
|
||||
void DetermineVisibility_Recursive(LRoomManager &manager, int depth, const LCamera &cam, const LVector<Plane> &planes, int portalID_from = -1);
|
||||
void FirstTouch(LRoomManager &manager);
|
||||
|
||||
|
||||
void AddDOB(Spatial * pDOB);
|
||||
bool RemoveDOB(Node * pDOB);
|
||||
LRoom * UpdateDOB(LRoomManager &manager, Spatial * pDOB);
|
||||
void DOB_Add(Spatial * pDOB);
|
||||
bool DOB_Remove(Node * pDOB);
|
||||
LRoom * DOB_Update(LRoomManager &manager, Spatial * pDOB);
|
||||
|
||||
public:
|
||||
LRoom();
|
||||
|
@ -119,7 +119,7 @@ LRoom * LRoomManager::GetRoomFromDOB(Node * pNode)
|
||||
}
|
||||
|
||||
|
||||
void LRoomManager::register_dob(Node * pDOB)
|
||||
void LRoomManager::dob_register(Node * pDOB)
|
||||
{
|
||||
print_line("register_dob " + pDOB->get_name());
|
||||
|
||||
@ -139,14 +139,14 @@ void LRoomManager::register_dob(Node * pDOB)
|
||||
if (!pRoom)
|
||||
return;
|
||||
|
||||
pRoom->AddDOB(pSpat);
|
||||
pRoom->DOB_Add(pSpat);
|
||||
|
||||
// save the room ID on the dob metadata
|
||||
Obj_SetRoomNum(pSpat, iRoomNum);
|
||||
}
|
||||
|
||||
|
||||
bool LRoomManager::update_dob(Node * pDOB)
|
||||
bool LRoomManager::dob_update(Node * pDOB)
|
||||
{
|
||||
// find the room the object is attached to
|
||||
LRoom * pRoom = GetRoomFromDOB(pDOB);
|
||||
@ -157,41 +157,56 @@ bool LRoomManager::update_dob(Node * pDOB)
|
||||
if (!pSpat)
|
||||
return false;
|
||||
|
||||
// is it the camera?
|
||||
//bool bCamera = pDOB->get_instance_id() == m_cameraID;
|
||||
|
||||
LRoom * pNewRoom = pRoom->UpdateDOB(*this, pSpat);
|
||||
LRoom * pNewRoom = pRoom->DOB_Update(*this, pSpat);
|
||||
|
||||
if (pNewRoom)
|
||||
{
|
||||
// remove from the list in old room and add to list in new room, and change the metadata
|
||||
int iRoomNum = pNewRoom->m_RoomID;
|
||||
|
||||
pRoom->RemoveDOB(pDOB);
|
||||
pNewRoom->AddDOB(pSpat);
|
||||
pRoom->DOB_Remove(pDOB);
|
||||
pNewRoom->DOB_Add(pSpat);
|
||||
|
||||
// save the room ID on the dob metadata
|
||||
Obj_SetRoomNum(pSpat, iRoomNum);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LRoomManager::teleport_dob(Node * pDOB)
|
||||
bool LRoomManager::dob_teleport(Node * pDOB)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LRoomManager::unregister_dob(Node * pDOB)
|
||||
void LRoomManager::dob_unregister(Node * pDOB)
|
||||
{
|
||||
LRoom * pRoom = GetRoomFromDOB(pDOB);
|
||||
pRoom->RemoveDOB(pDOB);
|
||||
pRoom->DOB_Remove(pDOB);
|
||||
}
|
||||
|
||||
int LRoomManager::dob_get_room_id(Node * pDOB)
|
||||
{
|
||||
return Obj_GetRoomNum(pDOB);
|
||||
}
|
||||
|
||||
Node * LRoomManager::rooms_get_room(int room_id)
|
||||
{
|
||||
const LRoom * pRoom = GetRoom(room_id);
|
||||
|
||||
if (!pRoom)
|
||||
return NULL;
|
||||
|
||||
return pRoom->GetGodotRoom();
|
||||
}
|
||||
|
||||
|
||||
void LRoomManager::set_camera(Node * pCam)
|
||||
|
||||
void LRoomManager::rooms_set_camera(Node * pCam)
|
||||
{
|
||||
m_cameraID = 0;
|
||||
|
||||
@ -212,7 +227,7 @@ void LRoomManager::set_camera(Node * pCam)
|
||||
}
|
||||
|
||||
// convert empties and meshes to rooms and portals
|
||||
void LRoomManager::convert()
|
||||
void LRoomManager::rooms_convert()
|
||||
{
|
||||
LRoomConverter conv;
|
||||
conv.Convert(*this);
|
||||
@ -347,14 +362,17 @@ void LRoomManager::_notification(int p_what) {
|
||||
void LRoomManager::_bind_methods()
|
||||
{
|
||||
// main functions
|
||||
ClassDB::bind_method(D_METHOD("rooms_convert"), &LRoomManager::convert);
|
||||
ClassDB::bind_method(D_METHOD("rooms_set_camera"), &LRoomManager::set_camera);
|
||||
ClassDB::bind_method(D_METHOD("rooms_convert"), &LRoomManager::rooms_convert);
|
||||
ClassDB::bind_method(D_METHOD("rooms_set_camera"), &LRoomManager::rooms_set_camera);
|
||||
ClassDB::bind_method(D_METHOD("rooms_get_room"), &LRoomManager::rooms_get_room);
|
||||
|
||||
// functions to add dynamic objects to the culling system
|
||||
// Note that these should not be placed directly in rooms, the system will 'soft link' to them
|
||||
// so they can be held, e.g. in pools elsewhere in the scene graph
|
||||
ClassDB::bind_method(D_METHOD("dob_register"), &LRoomManager::register_dob);
|
||||
ClassDB::bind_method(D_METHOD("dob_unregister"), &LRoomManager::unregister_dob);
|
||||
ClassDB::bind_method(D_METHOD("dob_update"), &LRoomManager::update_dob);
|
||||
ClassDB::bind_method(D_METHOD("dob_teleport"), &LRoomManager::teleport_dob);
|
||||
ClassDB::bind_method(D_METHOD("dob_register"), &LRoomManager::dob_register);
|
||||
ClassDB::bind_method(D_METHOD("dob_unregister"), &LRoomManager::dob_unregister);
|
||||
ClassDB::bind_method(D_METHOD("dob_update"), &LRoomManager::dob_update);
|
||||
ClassDB::bind_method(D_METHOD("dob_teleport"), &LRoomManager::dob_teleport);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("dob_get_room_id"), &LRoomManager::dob_get_room_id);
|
||||
}
|
||||
|
@ -61,20 +61,24 @@ public:
|
||||
LRoomManager();
|
||||
|
||||
// convert empties and meshes to rooms and portals
|
||||
void convert();
|
||||
void rooms_convert();
|
||||
|
||||
// choose which camera you want to use to determine visibility.
|
||||
// normally this will be your main camera, but you can choose another for debugging
|
||||
void set_camera(Node * pCam);
|
||||
void rooms_set_camera(Node * pCam);
|
||||
|
||||
// Dynamic objects .. cameras, players, boxes etc
|
||||
// These are defined by their ability to move from room to room.
|
||||
// You can still move static objects within the same room (e.g. elevators, moving platforms)
|
||||
// as these don't require checks for changing rooms.
|
||||
void register_dob(Node * pDOB);
|
||||
void unregister_dob(Node * pDOB);
|
||||
bool update_dob(Node * pDOB);
|
||||
bool teleport_dob(Node * pDOB);
|
||||
void dob_register(Node * pDOB);
|
||||
void dob_unregister(Node * pDOB);
|
||||
bool dob_update(Node * pDOB);
|
||||
bool dob_teleport(Node * pDOB);
|
||||
|
||||
// supplementary functions available from script
|
||||
int dob_get_room_id(Node * pDOB);
|
||||
Node * rooms_get_room(int room_id);
|
||||
|
||||
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user