mirror of
https://github.com/Relintai/godot-lportal.git
synced 2025-04-19 21:43:10 +02:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
8c1f7bb718 | ||
|
c63c317d76 | ||
|
bfb31a9287 | ||
|
6d3d3ec643 | ||
|
9e84c7a7cd | ||
|
ccc8cd2a1a | ||
|
d682efb517 | ||
|
18eac7e810 | ||
|
d6717de5ba | ||
|
1b40e8d6c2 | ||
|
9f049a86c1 |
@ -40,7 +40,7 @@ before_build:
|
|||||||
- SET "SCONS_CACHE=%SCONS_CACHE_ROOT%\3.2"
|
- SET "SCONS_CACHE=%SCONS_CACHE_ROOT%\3.2"
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% debug_symbols=no verbose=yes progress=no gdnative_wrapper=yes
|
- scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% debug_symbols=no progress=no gdnative_wrapper=yes
|
||||||
#- scons --version
|
#- scons --version
|
||||||
#- cd ..
|
#- cd ..
|
||||||
- ls
|
- ls
|
||||||
|
@ -141,21 +141,19 @@ Somewhat counter-intuitively, all DOBs should be maintained in your game __OUTSI
|
|||||||
|
|
||||||
All the following functions should be called on the LRoomManager node.
|
All the following functions should be called on the LRoomManager node.
|
||||||
|
|
||||||
* Call `dob_register(cam, 0.0)` to register a DOB to be handled
|
* Call `dob_id = dob_register(godot_node, position, radius)` to register a DOB to be handled
|
||||||
|
|
||||||
The number 0.0 is the radius of the DOB in the visibility system. All DOBs are managed as spheres. For a camera the radius can be zero because it will never be visible (however it DOES require to be a DOB so that the system can keep track of which room it is in).
|
The radius is needed because all DOBs are managed as spheres. For a camera the radius can be zero because it will never be visible (however it DOES require to be a DOB so that the system can keep track of which room it is in). It returns a dob_id which will need to be stored in your game and used to refer to the dob.
|
||||||
|
|
||||||
If a DOB is being culled (popping out of view) when it should not, it is normally because the bounding radius needs to be larger. On the other hand, too large a radius will make the DOB render when it is not necessary, so it is a good idea to tweak this value. It is in Godot world units, so you may be able to simply measure you object in the IDE.
|
If a DOB is being culled (popping out of view) when it should not, it is normally because the bounding radius needs to be larger. On the other hand, too large a radius will make the DOB render when it is not necessary, so it is a good idea to tweak this value. It is in Godot world units, so you may be able to simply measure you object in the IDE.
|
||||||
|
|
||||||
* Each frame, call `dob_update(dob_node)` to keep that DOB updated in the system
|
* Each frame, call `dob_update(dob_id, position)` to keep that DOB updated in the system with the new position
|
||||||
|
|
||||||
If the DOB is not moving, or you want to deactivate it to save processing, simply don't call update again until you want to reactivate it. Note that there is no need to call dob_update on the selected camera, it will be updated automatically.
|
If the DOB is not moving, or you want to deactivate it to save processing, simply don't call update again until you want to reactivate it. Note that there is no need to call dob_update on the selected camera, it will be updated automatically.
|
||||||
|
|
||||||
* When you have finished with a DOB you should call `dob_unregister(cam)` to remove the soft link from the system. This is more important when you are creating and deleting DOBs (say with multiple game levels). If you call rooms_release when unloading a level and want to keep DOBs in between levels, it is crucial that you do not update them until you have re-registered them after calling rooms_convert to create the new level (you will get an error message otherwise).
|
* When you have finished with a DOB you should call `dob_unregister(dob_id)` to remove the soft link from the system. This is more important when you are creating and deleting DOBs (say with multiple game levels). If you call rooms_release when unloading a level and want to keep DOBs in between levels, it is crucial that you do not update them until you have re-registered them after calling rooms_convert to create the new level (you will get an error message otherwise).
|
||||||
|
|
||||||
* If you are suddenly moving a DOB a large distance (rather than into a neighbouring room), you should call `dob_teleport(cam)`. This uses a different system to estimate the new room that the DOB is in. If you know in advance what room the dob will teleport to, there is a hint version of the function.
|
* DOBs should usually only move between rooms via the portals. In fact that is how their movement between rooms is defined. This is why a room's portals should form a convex space, never concave. In order to limit movement between rooms to the portals, you should use e.g. physics, or a navmesh.
|
||||||
|
|
||||||
* DOBs should only move between rooms via the portals. In fact that is how their movement between rooms is defined. This is why a room's portals should form a convex space, never concave. In order to limit movement between rooms to the portals, you should use e.g. physics, or a navmesh.
|
|
||||||
|
|
||||||
## Conversion
|
## Conversion
|
||||||
Build your rooms and portals and placed them as children in a scene graph structure something like this:
|
Build your rooms and portals and placed them as children in a scene graph structure something like this:
|
||||||
@ -186,10 +184,10 @@ Root
|
|||||||
|
|
||||||
This will provide some output to indicate the building of the optimized internal visibility structure.
|
This will provide some output to indicate the building of the optimized internal visibility structure.
|
||||||
|
|
||||||
* Set which camera you want LPortal to use by calling `rooms_set_camera(cam)`
|
|
||||||
|
|
||||||
* Register the camera as a DOB (see above section on DOBs) and update each frame.
|
* Register the camera as a DOB (see above section on DOBs) and update each frame.
|
||||||
|
|
||||||
|
* Set which camera you want LPortal to use by calling `rooms_set_camera(dob_id, camera_node)`
|
||||||
|
|
||||||
* If you want to unload a level and load a new one, call `rooms_release()`, free the old level, load the new one, and call `rooms_convert()` again (which clears the old data), and repeat each step.
|
* If you want to unload a level and load a new one, call `rooms_release()`, free the old level, load the new one, and call `rooms_convert()` again (which clears the old data), and repeat each step.
|
||||||
|
|
||||||
_Be aware that if you unload (using queue_free) and load levels with the same name then Godot can rename them to avoid name conflicts. The nodepath to the rooms assigned to the LRoomManager must be correct!_
|
_Be aware that if you unload (using queue_free) and load levels with the same name then Godot can rename them to avoid name conflicts. The nodepath to the rooms assigned to the LRoomManager must be correct!_
|
||||||
@ -380,12 +378,16 @@ var m_node_KitchenLight = get_node("/root").find_node("kitchen_light", true, fal
|
|||||||
Then after converting the level, call
|
Then after converting the level, call
|
||||||
```
|
```
|
||||||
# where LRoomManager is your LRoomManager
|
# where LRoomManager is your LRoomManager
|
||||||
$LRoomManager.dynamic_light_register(m_node_KitchenLight)
|
light_id = $LRoomManager.dynamic_light_register(m_node_KitchenLight, radius)
|
||||||
```
|
```
|
||||||
Move or rotate the light as you would normally, but to keep LPortal up to date, immediately after moving the light call 'dynamic_light_update':
|
Move or rotate the light as you would normally, but to keep LPortal up to date, immediately after moving the light call 'dynamic_light_update':
|
||||||
```
|
```
|
||||||
m_node_KitchenLight.rotate_y(0.01) # just an example
|
m_node_KitchenLight.rotate_y(0.01) # just an example
|
||||||
$LRoomManager.dynamic_light_update(m_node_KitchenLight)
|
$LRoomManager.dynamic_light_update(light_id, position, direction)
|
||||||
|
```
|
||||||
|
The direction is important for spotlights, you can calculate it using the following formula:
|
||||||
|
```
|
||||||
|
var dir = (-node_Spotlight.global_transform.basis.z).normalized()
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Global Directional lights
|
#### Global Directional lights
|
||||||
@ -398,7 +400,7 @@ As directional lights are not associated with any particular room, you should ad
|
|||||||
```
|
```
|
||||||
# where $DirectionalLight is your light node,
|
# where $DirectionalLight is your light node,
|
||||||
# and "myarea" is the name of your area (e.g. area_myarea) that you want it to affect
|
# and "myarea" is the name of your area (e.g. area_myarea) that you want it to affect
|
||||||
$LRoomManager.light_register($DirectionalLight, "myarea")
|
$LRoomManager.global_light_register($DirectionalLight, "myarea")
|
||||||
```
|
```
|
||||||
That's all you need to do. If any of the visible rooms (as calculated by LPortal) are part of the area affected by the light, the light will be drawn. If not, it will not. LPortal also calculates only those shadow casters that are relevant, but directional lights cannot as yet (Godot 3) take advantage of this information. This may change in Godot 4.
|
That's all you need to do. If any of the visible rooms (as calculated by LPortal) are part of the area affected by the light, the light will be drawn. If not, it will not. LPortal also calculates only those shadow casters that are relevant, but directional lights cannot as yet (Godot 3) take advantage of this information. This may change in Godot 4.
|
||||||
|
|
||||||
@ -487,20 +489,3 @@ Note that you should usually assign the shader to the materials while creating t
|
|||||||
|
|
||||||
### Command reference
|
### Command reference
|
||||||
_(There is a full reference available from the help section in the IDE under 'LRoomManager')_
|
_(There is a full reference available from the help section in the IDE under 'LRoomManager')_
|
||||||
* `rooms_convert()` - prepare lportal for rendering
|
|
||||||
* `rooms_set_camera()` - set which camera visibility is calculated from
|
|
||||||
* `Node * rooms_get_room()` - returns godot room node from lportal room id
|
|
||||||
* `rooms_set_active()` - turns on and off lportal
|
|
||||||
* `rooms_log_frame()` - output debug logs for the next frame
|
|
||||||
* `rooms_set_logging()` - set debug logging level, 0 - 6 (0 is none, 6 is most)
|
|
||||||
* `rooms_set_debug_planes()` - turns on and off graphic debugging of portal planes
|
|
||||||
* `rooms_set_debug_bounds()` - turns on and off graphic debugging of room bounds
|
|
||||||
|
|
||||||
* `dob_register()` - have lportal find start room
|
|
||||||
* `dob_register_hint()` - user provides start room
|
|
||||||
* `dob_unregister()`
|
|
||||||
* `int dob_update()` - returns room ID within
|
|
||||||
* `dob_teleport()` - have lportal find start room
|
|
||||||
* `dob_teleport_hint()` - user provides start room
|
|
||||||
* `int dob_get_room_id()` - return room ID the dob is currently within
|
|
||||||
|
|
||||||
|
23
README.md
23
README.md
@ -1,4 +1,4 @@
|
|||||||
# godot-lportal
|
# godot-lportal 0.2
|
||||||
Portal rendering / Occlusion culling module for Godot 3.2
|
Portal rendering / Occlusion culling module for Godot 3.2
|
||||||
|
|
||||||
You can either use LPortal as a full occlusion culling system if you can create your level as rooms and portals, or use it in a simplified single room mode to speed up culling in any 3d level.
|
You can either use LPortal as a full occlusion culling system if you can create your level as rooms and portals, or use it in a simplified single room mode to speed up culling in any 3d level.
|
||||||
@ -26,9 +26,17 @@ https://github.com/lawnjelly/lportal-demos
|
|||||||
_Feel free to leave suggestions / feature requests on the issue tracker, especially regarding ease of use._
|
_Feel free to leave suggestions / feature requests on the issue tracker, especially regarding ease of use._
|
||||||
|
|
||||||
## Current status
|
## Current status
|
||||||
As everything is now basically working, I am currently working on a small demo / test first person shooter game. This is helping me find bugs / add usability features as I go.
|
April 2nd 2020 - New API for DOBS. I had identified a breaking bug in the DOB visibility caused by the assumptions from the data coming from godot. It turns out when DOBs are hidden I can't retrieve their position etc from the Godot node, so I'm having to change the API for DOBs and dynamic lights so you pass the position manually each update. I've tested and this works.
|
||||||
|
|
||||||
Note I'm also currently rewriting the Godot 2d GLES renderer in core, so that has to take priority until it is working.
|
Note that the new dob culling isn't totally finished yet, it simply culls based on which room the dob is within, and whether that room is visible. This is approximate and won't deal with the case where a dob should be casting a shadow into the frustum from a room that is not visible. I'll get more accurate dob culling and light tracing working again in time, but it should be okay for most cases to start with.
|
||||||
|
|
||||||
|
I am currently working on a small demo / test first person shooter game. This is helping me find bugs / add usability features as I go.
|
||||||
|
|
||||||
|
I've also written a small lightmapper which started out as a bit of fun, but will be integrated in LPortal. The current voxel based lightmapper in core 3.x has a lot of bugs. JFons has been writing a replacement lightmapper for core, and I may switch to that when it is available, or have both options available. My lightmapper (and I believe JFons also) are based on path tracing rather than voxels. Reduz has also written a new lightmapper for 4.x, but whether that will be backported to 3.x and will work on CPUs remains to be seen.
|
||||||
|
|
||||||
|
I'm going to be working on improving the user interface for LPortal, exposing some of the features in the LRoomManager node, and having editor plugins for both the lightmapper and lportal.
|
||||||
|
|
||||||
|
Note I'm also working on core renderers (batching in GLES2 and GLES3, and the new 4.x GLES renderers), so there may be some periods of inactivity on LPortal.
|
||||||
|
|
||||||
## Instructions
|
## Instructions
|
||||||
* [OVERVIEW](OCCLUSION_CULLING.md)
|
* [OVERVIEW](OCCLUSION_CULLING.md)
|
||||||
@ -62,7 +70,14 @@ Note I'm also currently rewriting the Godot 2d GLES renderer in core, so that ha
|
|||||||
* PVS (primary and secondary)
|
* PVS (primary and secondary)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
You will need to compile Godot from source (for now). See:
|
|
||||||
|
For convenience to trial LPortal I have provided a win64 build under the 'releases' tab in github. However, note that for production use (on multiple platforms) you will currently have to compile from source.
|
||||||
|
|
||||||
|
I will work on increasing the number of builds for different platforms.
|
||||||
|
|
||||||
|
## Compiling from source
|
||||||
|
|
||||||
|
See:
|
||||||
http://docs.godotengine.org/en/3.0/development/compiling/index.html
|
http://docs.godotengine.org/en/3.0/development/compiling/index.html
|
||||||
|
|
||||||
Once the engine is compiling okay on your system, to add the module:
|
Once the engine is compiling okay on your system, to add the module:
|
||||||
|
BIN
config.pyc
Normal file
BIN
config.pyc
Normal file
Binary file not shown.
2
ldebug.h
2
ldebug.h
@ -24,7 +24,7 @@
|
|||||||
// you won't be able to get frame debugging of the visibility tree though.
|
// you won't be able to get frame debugging of the visibility tree though.
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
||||||
#pragma message ("LPortal DEBUG_ENABLED")
|
#pragma message ("LPortal DEBUG_ENABLED, verbose mode")
|
||||||
#define LPRINT_RUN(a, b) {if (!Lawn::LDebug::m_bRunning) {String sz;\
|
#define LPRINT_RUN(a, b) {if (!Lawn::LDebug::m_bRunning) {String sz;\
|
||||||
for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
|
for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
|
||||||
sz += "\t";\
|
sz += "\t";\
|
||||||
|
1
ldob.cpp
1
ldob.cpp
@ -117,6 +117,7 @@ void LLight::Light_SetDefaults()
|
|||||||
m_Source.Source_SetDefaults();
|
m_Source.Source_SetDefaults();
|
||||||
|
|
||||||
m_GodotID = 0;
|
m_GodotID = 0;
|
||||||
|
m_DOB_id = -1;
|
||||||
// m_eType = LT_DIRECTIONAL;
|
// m_eType = LT_DIRECTIONAL;
|
||||||
// m_eClass = LT_STATIC;
|
// m_eClass = LT_STATIC;
|
||||||
// m_fSpread = 0.0f; // for spotlight
|
// m_fSpread = 0.0f; // for spotlight
|
||||||
|
9
ldob.h
9
ldob.h
@ -69,10 +69,13 @@ public:
|
|||||||
Spatial * GetSpatial() const;
|
Spatial * GetSpatial() const;
|
||||||
VisualInstance * GetVI() const;
|
VisualInstance * GetVI() const;
|
||||||
|
|
||||||
ObjectID m_ID_Spatial;
|
bool m_bSlotTaken;
|
||||||
ObjectID m_ID_VI;
|
|
||||||
bool m_bVisible;
|
bool m_bVisible;
|
||||||
float m_fRadius;
|
float m_fRadius;
|
||||||
|
int m_iRoomID;
|
||||||
|
|
||||||
|
ObjectID m_ID_Spatial;
|
||||||
|
ObjectID m_ID_VI;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -129,6 +132,8 @@ public:
|
|||||||
|
|
||||||
LSource m_Source;
|
LSource m_Source;
|
||||||
ObjectID m_GodotID;
|
ObjectID m_GodotID;
|
||||||
|
int m_DOB_id;
|
||||||
|
|
||||||
// shadow casters
|
// shadow casters
|
||||||
int m_FirstCaster;
|
int m_FirstCaster;
|
||||||
int m_NumCasters;
|
int m_NumCasters;
|
||||||
|
179
ldoblist.cpp
Normal file
179
ldoblist.cpp
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
#include "ldoblist.h"
|
||||||
|
#include "lroom_manager.h"
|
||||||
|
#include "ldebug.h"
|
||||||
|
|
||||||
|
// returns whether changed room
|
||||||
|
bool LDobList::FindDOBOldAndNewRoom(LRoomManager &manager, int dob_id, const Vector3 &pos, int &old_room_id, int &new_room_id)
|
||||||
|
{
|
||||||
|
LDob &dob = GetDob(dob_id);
|
||||||
|
|
||||||
|
bool bCamera = (dob_id == manager.m_DOB_id_camera);
|
||||||
|
float slop = 0.2f;
|
||||||
|
if (bCamera)
|
||||||
|
slop = 0.0f;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// print_line("dob position : " + String(Variant(pt)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// current room
|
||||||
|
old_room_id = dob.m_iRoomID;
|
||||||
|
new_room_id = old_room_id; // default
|
||||||
|
|
||||||
|
bool bChangedRoom = false;
|
||||||
|
LRoom * pCurrentRoom = 0;
|
||||||
|
|
||||||
|
if (old_room_id == -1)
|
||||||
|
bChangedRoom = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pCurrentRoom = manager.GetRoom(old_room_id);
|
||||||
|
|
||||||
|
// deal with the case that the DOB has moved way outside the room
|
||||||
|
if (!pCurrentRoom->m_Bound.IsPointWithin(pos, 1.0f))
|
||||||
|
bChangedRoom = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if changed room definitely?
|
||||||
|
if (bChangedRoom)
|
||||||
|
{
|
||||||
|
// revert to expensive method (may have been teleported etc)
|
||||||
|
new_room_id = manager.FindClosestRoom(pos);
|
||||||
|
|
||||||
|
if (new_room_id != old_room_id)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
assert (pCurrentRoom);
|
||||||
|
|
||||||
|
// check each portal - has the object crossed it into the neighbouring room?
|
||||||
|
for (int p=0; p<pCurrentRoom->m_iNumPortals; p++)
|
||||||
|
{
|
||||||
|
const LPortal &port = manager.m_Portals[pCurrentRoom->m_iFirstPortal + p];
|
||||||
|
|
||||||
|
float dist = port.m_Plane.distance_to(pos);
|
||||||
|
|
||||||
|
if (dist > slop)
|
||||||
|
{
|
||||||
|
LPRINT(0, "DOB at pos " + pos + " ahead of portal " + port.get_name() + " by " + String(Variant(dist)));
|
||||||
|
|
||||||
|
new_room_id = manager.Portal_GetLinkedRoom(port).m_RoomID;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LDobList::UpdateVisibility(LRoomManager &manager, Spatial * pDOBSpatial, int dob_id)
|
||||||
|
{
|
||||||
|
LDob &dob = GetDob(dob_id);
|
||||||
|
|
||||||
|
// get the room
|
||||||
|
LRoom * pRoom = manager.GetRoom(dob.m_iRoomID);
|
||||||
|
bool bRoomVisible = pRoom->IsVisible();
|
||||||
|
|
||||||
|
Spatial * pDOB = pDOBSpatial;
|
||||||
|
|
||||||
|
bool bDobVis = pDOB->is_visible_in_tree();
|
||||||
|
if (bDobVis != bRoomVisible)
|
||||||
|
{
|
||||||
|
//String sz = "DOB " + pDOB->get_name() + "\t";
|
||||||
|
|
||||||
|
if (bRoomVisible)
|
||||||
|
{
|
||||||
|
pDOB->show();
|
||||||
|
//sz += "coming into view";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pDOB->hide();
|
||||||
|
//sz += "exiting view";
|
||||||
|
}
|
||||||
|
|
||||||
|
//print_line(sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int LDobList::UpdateDob(LRoomManager &manager, int dob_id, const Vector3 &pos)
|
||||||
|
{
|
||||||
|
LDob &dob = GetDob(dob_id);
|
||||||
|
|
||||||
|
// get the VI for showing / hiding
|
||||||
|
Spatial * pSpat = (Spatial *) dob.GetVI();
|
||||||
|
|
||||||
|
int old_room, new_room;
|
||||||
|
|
||||||
|
if (FindDOBOldAndNewRoom(manager, dob_id, pos, old_room, new_room))
|
||||||
|
{
|
||||||
|
dob.m_iRoomID = new_room;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dob_id != manager.m_DOB_id_camera)
|
||||||
|
UpdateVisibility(manager, pSpat, dob_id);
|
||||||
|
|
||||||
|
return dob.m_iRoomID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// get _global_transform DOES NOT WORK when detached from scene tree (or hidden)
|
||||||
|
const Vector3 &pt = pDOB->get_global_transform().origin;
|
||||||
|
|
||||||
|
// is it the camera?
|
||||||
|
bool bCamera = pDOB->get_instance_id() == manager.m_ID_camera;
|
||||||
|
float slop = 0.2f;
|
||||||
|
if (bCamera)
|
||||||
|
slop = 0.0f;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// print_line("dob position : " + String(Variant(pt)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// deal with the case that the DOB has moved way outside the room
|
||||||
|
if (!m_Bound.IsPointWithin(pt, 1.0f))
|
||||||
|
{
|
||||||
|
// revert to expensive method (may have been teleported etc)
|
||||||
|
int iRoomNum = manager.FindClosestRoom(pt);
|
||||||
|
//print_line("dob_teleport closest room " + itos(iRoomNum));
|
||||||
|
|
||||||
|
if (iRoomNum == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// could be no change of room...
|
||||||
|
if (iRoomNum == m_RoomID)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return manager.GetRoom(iRoomNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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!
|
||||||
|
// if (bCamera)
|
||||||
|
// slop = 0.0f;
|
||||||
|
|
||||||
|
// check each portal - has the object crossed it into the neighbouring room?
|
||||||
|
for (int p=0; p<m_iNumPortals; p++)
|
||||||
|
{
|
||||||
|
const LPortal &port = manager.m_Portals[m_iFirstPortal + p];
|
||||||
|
|
||||||
|
float dist = port.m_Plane.distance_to(pt);
|
||||||
|
|
||||||
|
if (dist > slop)
|
||||||
|
{
|
||||||
|
LPRINT(0, "DOB at pos " + pt + " ahead of portal " + port.get_name() + " by " + String(Variant(dist)));
|
||||||
|
|
||||||
|
// we want to move into the adjoining room
|
||||||
|
return &manager.Portal_GetLinkedRoom(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
*/
|
||||||
|
|
58
ldoblist.h
Normal file
58
ldoblist.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "lvector.h"
|
||||||
|
#include "ldob.h"
|
||||||
|
|
||||||
|
class LRoomManager;
|
||||||
|
|
||||||
|
class LDobList
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// getting
|
||||||
|
LDob &GetDob(int n) {return m_List[n];}
|
||||||
|
const LDob &GetDob(int n) const {return m_List[n];}
|
||||||
|
|
||||||
|
// request delete
|
||||||
|
int Request();
|
||||||
|
void DeleteDob(int id);
|
||||||
|
|
||||||
|
// funcs
|
||||||
|
int UpdateDob(LRoomManager &manager, int dob_id, const Vector3 &pos);
|
||||||
|
void UpdateVisibility(LRoomManager &manager, Spatial * pDOBSpatial, int dob_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool FindDOBOldAndNewRoom(LRoomManager &manager, int dob_id, const Vector3 &pos, int &old_room_id, int &new_room_id);
|
||||||
|
|
||||||
|
LVector<LDob> m_List;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
inline void LDobList::DeleteDob(int id)
|
||||||
|
{
|
||||||
|
GetDob(id).m_bSlotTaken = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int LDobList::Request()
|
||||||
|
{
|
||||||
|
for (int n=0; n<m_List.size(); n++)
|
||||||
|
{
|
||||||
|
LDob &d = m_List[n];
|
||||||
|
if (d.m_bSlotTaken == false)
|
||||||
|
{
|
||||||
|
d.m_bSlotTaken = true;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// none found, create new
|
||||||
|
LDob * p = m_List.request();
|
||||||
|
memset(p, 0, sizeof (LDob));
|
||||||
|
|
||||||
|
p->m_bSlotTaken = true;
|
||||||
|
p->m_iRoomID = -1;
|
||||||
|
|
||||||
|
return m_List.size()-1;
|
||||||
|
}
|
@ -7,13 +7,17 @@
|
|||||||
#define LDEBUG_CAMERA
|
#define LDEBUG_CAMERA
|
||||||
#define LDEBUG_LIGHTS
|
#define LDEBUG_LIGHTS
|
||||||
#define LDEBUG_LIGHT_AFFECTED_ROOMS
|
#define LDEBUG_LIGHT_AFFECTED_ROOMS
|
||||||
|
//#define LDEBUG_DOB_VISIBILITY
|
||||||
|
|
||||||
|
#define LPORTAL_DOBS_NO_SOFTSHOW
|
||||||
|
//#define LPORTAL_DOBS_AUTO_UPDATE
|
||||||
|
|
||||||
//#define LDEBUG_UNMERGE
|
//#define LDEBUG_UNMERGE
|
||||||
|
|
||||||
// single compilation unit
|
// single compilation unit
|
||||||
#include "register_types.cpp"
|
#include "register_types.cpp"
|
||||||
#include "ldebug.cpp"
|
#include "ldebug.cpp"
|
||||||
|
#include "ldoblist.cpp"
|
||||||
#include "lroom.cpp"
|
#include "lroom.cpp"
|
||||||
#include "lroom_manager.cpp"
|
#include "lroom_manager.cpp"
|
||||||
#include "lroom_converter.cpp"
|
#include "lroom_converter.cpp"
|
||||||
|
45
lroom.cpp
45
lroom.cpp
@ -55,19 +55,19 @@ Spatial * LRoom::GetGodotRoom() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
void LRoom::DOB_Add(const LDob &dob)
|
void LRoom::DOB_Add(int id)
|
||||||
{
|
{
|
||||||
m_DOBs.push_back(dob);
|
m_DOB_ids.push_back(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int LRoom::DOB_Find(Node * pDOB) const
|
unsigned int LRoom::DOB_Find(int id) const
|
||||||
{
|
{
|
||||||
ObjectID id = pDOB->get_instance_id();
|
// ObjectID id = pDOB->get_instance_id();
|
||||||
|
|
||||||
for (int n=0; n<m_DOBs.size(); n++)
|
for (int n=0; n<m_DOB_ids.size(); n++)
|
||||||
{
|
{
|
||||||
if (m_DOBs[n].m_ID_Spatial == id)
|
if (m_DOB_ids[n] == id)
|
||||||
{
|
{
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
@ -78,9 +78,9 @@ unsigned int LRoom::DOB_Find(Node * pDOB) const
|
|||||||
|
|
||||||
bool LRoom::DOB_Remove(unsigned int ui)
|
bool LRoom::DOB_Remove(unsigned int ui)
|
||||||
{
|
{
|
||||||
if (ui < m_DOBs.size())
|
if (ui < m_DOB_ids.size())
|
||||||
{
|
{
|
||||||
m_DOBs.remove_unsorted(ui);
|
m_DOB_ids.remove_unsorted(ui);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +91,7 @@ bool LRoom::DOB_Remove(unsigned int ui)
|
|||||||
// returns -1 if no change, or the linked room we are moving into
|
// returns -1 if no change, or the linked room we are moving into
|
||||||
LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB)
|
LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB)
|
||||||
{
|
{
|
||||||
|
// get _global_transform DOES NOT WORK when detached from scene tree (or hidden)
|
||||||
const Vector3 &pt = pDOB->get_global_transform().origin;
|
const Vector3 &pt = pDOB->get_global_transform().origin;
|
||||||
|
|
||||||
// is it the camera?
|
// is it the camera?
|
||||||
@ -98,6 +99,10 @@ LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB)
|
|||||||
float slop = 0.2f;
|
float slop = 0.2f;
|
||||||
if (bCamera)
|
if (bCamera)
|
||||||
slop = 0.0f;
|
slop = 0.0f;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// print_line("dob position : " + String(Variant(pt)));
|
||||||
|
}
|
||||||
|
|
||||||
// deal with the case that the DOB has moved way outside the room
|
// deal with the case that the DOB has moved way outside the room
|
||||||
if (!m_Bound.IsPointWithin(pt, 1.0f))
|
if (!m_Bound.IsPointWithin(pt, 1.0f))
|
||||||
@ -139,7 +144,7 @@ LRoom * LRoom::DOB_Update(LRoomManager &manager, Spatial * pDOB)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// instead of directly showing and hiding objects we now set their layer,
|
// instead of directly showing and hiding objects we now set their layer,
|
||||||
// and the camera will hide them with a cull mask. This is so that
|
// and the camera will hide them with a cull mask. This is so that
|
||||||
@ -316,6 +321,7 @@ void LRoom::FinalizeVisibility(LRoomManager &manager)
|
|||||||
|
|
||||||
//print_line("FinalizeVisibility room " + get_name() + " NumSOBs " + itos(m_SOBs.size()) + ", NumDOBs " + itos(m_DOBs.size()));
|
//print_line("FinalizeVisibility room " + get_name() + " NumSOBs " + itos(m_SOBs.size()) + ", NumDOBs " + itos(m_DOBs.size()));
|
||||||
|
|
||||||
|
#ifndef LPORTAL_DOBS_NO_SOFTSHOW
|
||||||
for (int n=0; n<m_DOBs.size(); n++)
|
for (int n=0; n<m_DOBs.size(); n++)
|
||||||
{
|
{
|
||||||
const LDob &dob = m_DOBs[n];
|
const LDob &dob = m_DOBs[n];
|
||||||
@ -350,22 +356,7 @@ void LRoom::FinalizeVisibility(LRoomManager &manager)
|
|||||||
// pS->hide();
|
// pS->hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
// call when releasing a level, this should unregister all dobs within all rooms
|
|
||||||
void LRoom::Release(LRoomManager &manager)
|
|
||||||
{
|
|
||||||
for (int n=0; n<m_DOBs.size(); n++)
|
|
||||||
{
|
|
||||||
LDob &dob = m_DOBs[n];
|
|
||||||
|
|
||||||
Spatial * pS = dob.GetSpatial();
|
|
||||||
if (pS)
|
|
||||||
{
|
|
||||||
// signifies released or unregistered
|
|
||||||
manager.Meta_SetRoomNum(pS, -2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,6 +381,7 @@ void LRoom::Room_MakeVisible(bool bVisible)
|
|||||||
|
|
||||||
m_bVisible = bVisible;
|
m_bVisible = bVisible;
|
||||||
|
|
||||||
|
/*
|
||||||
if (m_bVisible)
|
if (m_bVisible)
|
||||||
{
|
{
|
||||||
// show room
|
// show room
|
||||||
@ -418,6 +410,7 @@ void LRoom::Room_MakeVisible(bool bVisible)
|
|||||||
p->hide();
|
p->hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
15
lroom.h
15
lroom.h
@ -58,7 +58,7 @@ public:
|
|||||||
int m_iNumSOBs;
|
int m_iNumSOBs;
|
||||||
|
|
||||||
// dynamic objects
|
// dynamic objects
|
||||||
LVector<LDob> m_DOBs;
|
//LVector<uint32_t> m_DOB_ids;
|
||||||
|
|
||||||
// local lights affecting this room
|
// local lights affecting this room
|
||||||
LVector<int> m_LocalLights;
|
LVector<int> m_LocalLights;
|
||||||
@ -105,9 +105,6 @@ public:
|
|||||||
// allows us to show / hide all dobs as the room visibility changes
|
// allows us to show / hide all dobs as the room visibility changes
|
||||||
void Room_MakeVisible(bool bVisible);
|
void Room_MakeVisible(bool bVisible);
|
||||||
|
|
||||||
// call when releasing a level, this should unregister all dobs within all rooms
|
|
||||||
void Release(LRoomManager &manager);
|
|
||||||
|
|
||||||
// show godot room and all linked dobs and all sobs
|
// show godot room and all linked dobs and all sobs
|
||||||
void Debug_ShowAll(bool bActive);
|
void Debug_ShowAll(bool bActive);
|
||||||
|
|
||||||
@ -118,11 +115,11 @@ public:
|
|||||||
// naive version, adds all the non visible objects in visible rooms as shadow casters
|
// naive version, adds all the non visible objects in visible rooms as shadow casters
|
||||||
void AddShadowCasters(LRoomManager &manager);
|
void AddShadowCasters(LRoomManager &manager);
|
||||||
|
|
||||||
void DOB_Add(const LDob &dob);
|
// void DOB_Add(int id);
|
||||||
const LDob &DOB_Get(unsigned int ui) const {return m_DOBs[ui];}
|
// int DOB_GetID(unsigned int ui) const {return m_DOB_ids[ui];}
|
||||||
unsigned int DOB_Find(Node * pDOB) const;
|
// unsigned int DOB_Find(int id) const;
|
||||||
bool DOB_Remove(unsigned int ui);
|
// bool DOB_Remove(unsigned int ui);
|
||||||
LRoom * DOB_Update(LRoomManager &manager, Spatial * pDOB);
|
// LRoom * DOB_Update(LRoomManager &manager, Spatial * pDOB);
|
||||||
|
|
||||||
LRoom();
|
LRoom();
|
||||||
Spatial * GetGodotRoom() const;
|
Spatial * GetGodotRoom() const;
|
||||||
|
@ -336,7 +336,7 @@ bool LRoomConverter::Convert_Room(Spatial * pNode, int lroomID, int areaID)
|
|||||||
// save the room ID on the godot room metadata
|
// save the room ID on the godot room metadata
|
||||||
// This is used when registering DOBs and teleporting them with hints
|
// This is used when registering DOBs and teleporting them with hints
|
||||||
// i.e. the Godot room is used to lookup the room ID of the startroom.
|
// i.e. the Godot room is used to lookup the room ID of the startroom.
|
||||||
LMAN->Meta_SetRoomNum(pNode, lroomID);
|
// LMAN->Meta_SetRoomNum(pNode, lroomID);
|
||||||
|
|
||||||
// create a new LRoom to exchange the children over to, and delete the original empty
|
// create a new LRoom to exchange the children over to, and delete the original empty
|
||||||
lroom.m_szName = szRoom;
|
lroom.m_szName = szRoom;
|
||||||
|
@ -42,7 +42,8 @@ return false;\
|
|||||||
|
|
||||||
LRoomManager::LRoomManager()
|
LRoomManager::LRoomManager()
|
||||||
{
|
{
|
||||||
m_ID_camera = 0;
|
// m_ID_camera = 0;
|
||||||
|
m_DOB_id_camera = -1;
|
||||||
m_ID_DebugPlanes = 0;
|
m_ID_DebugPlanes = 0;
|
||||||
m_ID_DebugBounds = 0;
|
m_ID_DebugBounds = 0;
|
||||||
m_ID_DebugLights = 0;
|
m_ID_DebugLights = 0;
|
||||||
@ -183,6 +184,8 @@ int LRoomManager::Meta_GetLightID(Node * pNode) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
CANT BE TRUSTED
|
||||||
void LRoomManager::Meta_SetRoomNum(Node * pNode, int num)
|
void LRoomManager::Meta_SetRoomNum(Node * pNode, int num)
|
||||||
{
|
{
|
||||||
pNode->set_meta("_lroom", num);
|
pNode->set_meta("_lroom", num);
|
||||||
@ -199,33 +202,10 @@ int LRoomManager::Meta_GetRoomNum(Node * pNode) const
|
|||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
LRoom * LRoomManager::GetRoomFromDOB(Node * pNode)
|
|
||||||
{
|
|
||||||
int iRoom = Meta_GetRoomNum(pNode);
|
|
||||||
if (iRoom < 0)
|
|
||||||
{
|
|
||||||
if (iRoom == -1)
|
|
||||||
{
|
|
||||||
WARN_PRINT_ONCE("LRoomManager::GetRoomFromDOB : metadata is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iRoom == -2)
|
|
||||||
{
|
|
||||||
WARN_PRINT_ONCE("LRoomManager::GetRoomFromDOB : are you updating an unregistered DOB?");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LRoom * pRoom = GetRoom(iRoom);
|
|
||||||
if (pRoom == 0)
|
|
||||||
{
|
|
||||||
WARN_PRINT_ONCE("LRoomManager::GetRoomFromDOB : pRoom is NULL");
|
|
||||||
}
|
|
||||||
return pRoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
// register but let LPortal know which room the dob should start in
|
// register but let LPortal know which room the dob should start in
|
||||||
bool LRoomManager::dob_register_hint(Node * pDOB, float radius, Node * pRoom)
|
bool LRoomManager::dob_register_hint(Node * pDOB, float radius, Node * pRoom)
|
||||||
{
|
{
|
||||||
@ -258,7 +238,7 @@ bool LRoomManager::dob_register_hint(Node * pDOB, float radius, Node * pRoom)
|
|||||||
|
|
||||||
return DobRegister(pSpat, radius, iRoom);
|
return DobRegister(pSpat, radius, iRoom);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void LRoomManager::CreateDebug()
|
void LRoomManager::CreateDebug()
|
||||||
{
|
{
|
||||||
@ -373,7 +353,7 @@ ObjectID LRoomManager::DobRegister_FindVIRecursive(Node * pNode) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LRoomManager::DobRegister(Spatial * pDOB, float radius, int iRoom)
|
int LRoomManager::DobRegister(Spatial * pDOB, const Vector3 &pos, float radius, int iRoom)
|
||||||
{
|
{
|
||||||
//LPRINT(3, "register_dob " + pDOB->get_name());
|
//LPRINT(3, "register_dob " + pDOB->get_name());
|
||||||
|
|
||||||
@ -383,38 +363,56 @@ bool LRoomManager::DobRegister(Spatial * pDOB, float radius, int iRoom)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRoom * pRoom = GetRoom(iRoom);
|
int did = m_DobList.Request();
|
||||||
if (!pRoom)
|
LDob &dob = m_DobList.GetDob(did);
|
||||||
return false;
|
|
||||||
|
|
||||||
// The dob is derived from spatial, but the visual instances may be children of the dob
|
dob.m_iRoomID = iRoom;
|
||||||
// rather than the node itself .. we need visual instances for layer culling for shadows
|
|
||||||
LDob dob;
|
|
||||||
dob.m_ID_Spatial = pDOB->get_instance_id();
|
dob.m_ID_Spatial = pDOB->get_instance_id();
|
||||||
dob.m_fRadius = radius;
|
dob.m_fRadius = radius;
|
||||||
|
|
||||||
|
// LRoom * pRoom = GetRoom(iRoom);
|
||||||
|
// if (!pRoom)
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
// The dob is derived from spatial, but the visual instances may be children of the dob
|
||||||
|
// rather than the node itself .. we need visual instances for layer culling for shadows
|
||||||
|
// LDob dob;
|
||||||
|
// dob.m_ID_Spatial = pDOB->get_instance_id();
|
||||||
|
// dob.m_fRadius = radius;
|
||||||
|
|
||||||
dob.m_ID_VI = DobRegister_FindVIRecursive(pDOB);
|
dob.m_ID_VI = DobRegister_FindVIRecursive(pDOB);
|
||||||
|
|
||||||
pRoom->DOB_Add(dob);
|
// pRoom->DOB_Add(dob);
|
||||||
|
|
||||||
// save the room ID on the dob metadata
|
// save the room ID on the dob metadata
|
||||||
Meta_SetRoomNum(pDOB, iRoom);
|
// Meta_SetRoomNum(pDOB, iRoom);
|
||||||
|
|
||||||
|
#ifdef LPORTAL_DOBS_NO_SOFTSHOW
|
||||||
|
VisualInstance * pVI = dob.GetVI();
|
||||||
|
if (pVI)
|
||||||
|
{
|
||||||
|
uint32_t mask = 0;
|
||||||
|
mask = LRoom::LAYER_MASK_CAMERA | LRoom::LAYER_MASK_LIGHT;
|
||||||
|
LRoom::SoftShow(pVI, mask);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// change visibility
|
// change visibility
|
||||||
DobChangeVisibility(pDOB, 0, pRoom);
|
m_DobList.UpdateDob(*this, did, pos);
|
||||||
|
// DobUpdateVisibility(pDOB, pRoom);
|
||||||
|
|
||||||
return true;
|
return did;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LRoomManager::dob_register(Node * pDOB, float radius)
|
int LRoomManager::dob_register(Node * pDOB, const Vector3 &pos, float radius)
|
||||||
{
|
{
|
||||||
CHECK_ROOM_LIST
|
CHECK_ROOM_LIST
|
||||||
|
|
||||||
if (!pDOB)
|
if (!pDOB)
|
||||||
{
|
{
|
||||||
WARN_PRINT_ONCE("dob_register : pDOB is NULL");
|
WARN_PRINT_ONCE("dob_register : pDOB is NULL");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPRINT(3, "dob_register " + pDOB->get_name() + " instance ID " + itos(pDOB->get_instance_id()));
|
LPRINT(3, "dob_register " + pDOB->get_name() + " instance ID " + itos(pDOB->get_instance_id()));
|
||||||
@ -423,30 +421,30 @@ bool LRoomManager::dob_register(Node * pDOB, float radius)
|
|||||||
if (!pSpat)
|
if (!pSpat)
|
||||||
{
|
{
|
||||||
WARN_PRINT_ONCE("dob_register : DOB is not a spatial");
|
WARN_PRINT_ONCE("dob_register : DOB is not a spatial");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 pt = pSpat->get_global_transform().origin;
|
// Vector3 pt = pSpat->get_global_transform().origin;
|
||||||
|
|
||||||
int iRoomNum = FindClosestRoom(pt);
|
int iRoomNum = FindClosestRoom(pos);
|
||||||
LPRINT(2, "dob_register closest room " + itos(iRoomNum));
|
LPRINT(2, "dob_register closest room " + itos(iRoomNum));
|
||||||
|
|
||||||
return DobRegister(pSpat, radius, iRoomNum);
|
return DobRegister(pSpat, pos, radius, iRoomNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LRoomManager::dob_update(Node * pDOB)
|
/*
|
||||||
|
// where pRoom is current room
|
||||||
|
int LRoomManager::DobUpdate(Spatial * pDOB_Spatial, LRoom * pRoom)
|
||||||
{
|
{
|
||||||
// find the room the object is attached to
|
LRoom * pNewRoom = pRoom->DOB_Update(*this, pDOB_Spatial);
|
||||||
LRoom * pRoom = GetRoomFromDOB(pDOB);
|
|
||||||
if (!pRoom)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
Spatial * pSpat = Object::cast_to<Spatial>(pDOB);
|
// // update visibility
|
||||||
if (!pSpat)
|
// if (pNewRoom)
|
||||||
return -1;
|
// DobUpdateVisibility(pSpat, pNewRoom);
|
||||||
|
// else
|
||||||
|
// DobUpdateVisibility(pSpat, pRoom);
|
||||||
|
|
||||||
LRoom * pNewRoom = pRoom->DOB_Update(*this, pSpat);
|
|
||||||
|
|
||||||
if (pNewRoom)
|
if (pNewRoom)
|
||||||
{
|
{
|
||||||
@ -456,7 +454,7 @@ int LRoomManager::dob_update(Node * pDOB)
|
|||||||
// get dob data to move to new room
|
// get dob data to move to new room
|
||||||
//unsigned int uidob_instance_id = pDOB->get_instance_id();
|
//unsigned int uidob_instance_id = pDOB->get_instance_id();
|
||||||
|
|
||||||
unsigned int dob_id = pRoom->DOB_Find(pDOB);
|
unsigned int dob_id = pRoom->DOB_Find(pDOB_Spatial);
|
||||||
// if (dob_id == -1)
|
// if (dob_id == -1)
|
||||||
// {
|
// {
|
||||||
// WARN_PRINT_ONCE("DOB is not found in room");
|
// WARN_PRINT_ONCE("DOB is not found in room");
|
||||||
@ -464,6 +462,8 @@ int LRoomManager::dob_update(Node * pDOB)
|
|||||||
// }
|
// }
|
||||||
assert (dob_id != -1);
|
assert (dob_id != -1);
|
||||||
|
|
||||||
|
print_line("dob " + itos(dob_id) + " entering room " + pNewRoom->get_name());
|
||||||
|
|
||||||
// copy across data before removing
|
// copy across data before removing
|
||||||
const LDob &data = pRoom->DOB_Get(dob_id);
|
const LDob &data = pRoom->DOB_Get(dob_id);
|
||||||
pNewRoom->DOB_Add(data);
|
pNewRoom->DOB_Add(data);
|
||||||
@ -472,19 +472,75 @@ int LRoomManager::dob_update(Node * pDOB)
|
|||||||
pRoom->DOB_Remove(dob_id);
|
pRoom->DOB_Remove(dob_id);
|
||||||
|
|
||||||
// change visibility
|
// change visibility
|
||||||
DobChangeVisibility(pSpat, pRoom, pNewRoom);
|
DobUpdateVisibility(pDOB_Spatial, pNewRoom);
|
||||||
|
|
||||||
// save the room ID on the dob metadata
|
// save the room ID on the dob metadata
|
||||||
Meta_SetRoomNum(pSpat, iRoomNum);
|
Meta_SetRoomNum(pDOB_Spatial, iRoomNum);
|
||||||
|
|
||||||
// new room number
|
// new room number
|
||||||
return iRoomNum;
|
return iRoomNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#ifdef LDEBUG_DOB_VISIBILITY
|
||||||
|
//#pragma message ("LPortal LDEBUG_DOB_VISIBILITY, dobs will flicker when hidden")
|
||||||
|
// bool bVis = pRoom->IsVisible();
|
||||||
|
|
||||||
|
// bool bSpatVisible = pSpat->is_visible_in_tree();
|
||||||
|
// if (bVis != bSpatVisible)
|
||||||
|
// {
|
||||||
|
// WARN_PRINT("DOB visibility incorrect");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool bShow = true;
|
||||||
|
|
||||||
|
// if (!bVis)
|
||||||
|
// {
|
||||||
|
// if ((Engine::get_singleton()->get_frames_drawn() % 2) == 0)
|
||||||
|
// {
|
||||||
|
// pSpat->show();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// pSpat->hide();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// pSpat->show();
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
|
||||||
// still in the same room
|
// still in the same room
|
||||||
return pRoom->m_RoomID;
|
return pRoom->m_RoomID;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int LRoomManager::dob_update(int dob_id, const Vector3 &pos)
|
||||||
|
{
|
||||||
|
#ifdef LPORTAL_DOBS_AUTO_UPDATE
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return m_DobList.UpdateDob(*this, dob_id, pos);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// find the room the object is attached to
|
||||||
|
// LRoom * pRoom = GetRoomFromDOB(pDOB);
|
||||||
|
// if (!pRoom)
|
||||||
|
// return -1;
|
||||||
|
|
||||||
|
// Spatial * pSpat = Object::cast_to<Spatial>(pDOB);
|
||||||
|
// if (!pSpat)
|
||||||
|
// return -1;
|
||||||
|
|
||||||
|
// return DobUpdate(pSpat, pRoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
bool LRoomManager::dob_teleport_hint(Node * pDOB, Node * pRoom)
|
bool LRoomManager::dob_teleport_hint(Node * pDOB, Node * pRoom)
|
||||||
{
|
{
|
||||||
CHECK_ROOM_LIST
|
CHECK_ROOM_LIST
|
||||||
@ -515,8 +571,9 @@ bool LRoomManager::dob_teleport_hint(Node * pDOB, Node * pRoom)
|
|||||||
|
|
||||||
return DobTeleport(pSpat, iRoom);
|
return DobTeleport(pSpat, iRoom);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID)
|
bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID)
|
||||||
{
|
{
|
||||||
LPRINT(5, "teleporting " + pDOB->get_name() + " to room " + itos(iNewRoomID));
|
LPRINT(5, "teleporting " + pDOB->get_name() + " to room " + itos(iNewRoomID));
|
||||||
@ -561,50 +618,55 @@ bool LRoomManager::DobTeleport(Spatial * pDOB, int iNewRoomID)
|
|||||||
Meta_SetRoomNum(pDOB, iNewRoomID);
|
Meta_SetRoomNum(pDOB, iNewRoomID);
|
||||||
|
|
||||||
// change visibility
|
// change visibility
|
||||||
DobChangeVisibility(pDOB, pOldRoom, pNewRoom);
|
DobUpdateVisibility(pDOB, pNewRoom);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// not tested...
|
// not tested...
|
||||||
|
/*
|
||||||
bool LRoomManager::dob_teleport(Node * pDOB)
|
bool LRoomManager::dob_teleport(Node * pDOB)
|
||||||
{
|
{
|
||||||
CHECK_ROOM_LIST
|
CHECK_ROOM_LIST
|
||||||
|
|
||||||
Spatial * pSpat = Object::cast_to<Spatial>(pDOB);
|
return true;
|
||||||
if (!pSpat)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Vector3 pt = pSpat->get_global_transform().origin;
|
// Spatial * pSpat = Object::cast_to<Spatial>(pDOB);
|
||||||
|
// if (!pSpat)
|
||||||
|
// return false;
|
||||||
|
|
||||||
int iRoomNum = FindClosestRoom(pt);
|
// Vector3 pt = pSpat->get_global_transform().origin;
|
||||||
//print_line("dob_teleport closest room " + itos(iRoomNum));
|
|
||||||
|
|
||||||
if (iRoomNum == -1)
|
// int iRoomNum = FindClosestRoom(pt);
|
||||||
return false;
|
// //print_line("dob_teleport closest room " + itos(iRoomNum));
|
||||||
|
|
||||||
return DobTeleport(pSpat, iRoomNum);
|
// if (iRoomNum == -1)
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
// return DobTeleport(pSpat, iRoomNum);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
bool LRoomManager::dob_unregister(int dob_id)
|
||||||
bool LRoomManager::dob_unregister(Node * pDOB)
|
|
||||||
{
|
{
|
||||||
CHECK_ROOM_LIST
|
CHECK_ROOM_LIST
|
||||||
|
|
||||||
LRoom * pRoom = GetRoomFromDOB(pDOB);
|
// LRoom * pRoom = GetRoomFromDOB(pDOB);
|
||||||
|
|
||||||
// change the meta data on the DOB .. this will catch trying to update an unregistered DOB
|
// // change the meta data on the DOB .. this will catch trying to update an unregistered DOB
|
||||||
Meta_SetRoomNum(pDOB, -2);
|
// Meta_SetRoomNum(pDOB, -2);
|
||||||
|
|
||||||
if (pRoom)
|
// if (pRoom)
|
||||||
{
|
// {
|
||||||
unsigned int dob_id = pRoom->DOB_Find(pDOB);
|
// unsigned int dob_id = pRoom->DOB_Find(pDOB);
|
||||||
return pRoom->DOB_Remove(dob_id);
|
// return pRoom->DOB_Remove(dob_id);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return false;
|
m_DobList.DeleteDob(dob_id);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -729,7 +791,13 @@ bool LRoomManager::Light_FindCasters(int lightID)
|
|||||||
|
|
||||||
void LRoomManager::Light_UpdateTransform(LLight &light, const Light &glight) const
|
void LRoomManager::Light_UpdateTransform(LLight &light, const Light &glight) const
|
||||||
{
|
{
|
||||||
// assert (glight.is_in_tree());
|
if (!glight.get_parent())
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("LRoomManager::Light_UpdateTransform Light is not in tree");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get global transform only works if glight is in the tree
|
||||||
Transform tr = glight.get_global_transform();
|
Transform tr = glight.get_global_transform();
|
||||||
light.m_Source.m_ptPos = tr.origin;
|
light.m_Source.m_ptPos = tr.origin;
|
||||||
light.m_Source.m_ptDir = -tr.basis.get_axis(2); // or possibly get_axis .. z is what we want
|
light.m_Source.m_ptDir = -tr.basis.get_axis(2); // or possibly get_axis .. z is what we want
|
||||||
@ -815,14 +883,13 @@ bool LRoomManager::LightCreate(Light * pLight, int roomID, String szArea)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LRoomManager::dynamic_light_register(Node * pLightNode, float radius)
|
int LRoomManager::dynamic_light_register(Node * pLightNode, float radius)
|
||||||
{
|
{
|
||||||
CHECK_ROOM_LIST
|
CHECK_ROOM_LIST
|
||||||
|
|
||||||
if (!pLightNode)
|
if (!pLightNode)
|
||||||
{
|
{
|
||||||
WARN_PRINT_ONCE("dynamic_light_register : pLightNode is NULL");
|
WARN_PRINT_ONCE("dynamic_light_register : pLightNode is NULL");
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectID light_id = pLightNode->get_instance_id();
|
ObjectID light_id = pLightNode->get_instance_id();
|
||||||
@ -834,31 +901,85 @@ bool LRoomManager::dynamic_light_register(Node * pLightNode, float radius)
|
|||||||
{
|
{
|
||||||
m_Lights[n].m_Source.m_eClass = LSource::SC_DYNAMIC;
|
m_Lights[n].m_Source.m_eClass = LSource::SC_DYNAMIC;
|
||||||
|
|
||||||
|
|
||||||
|
// do an update on the light
|
||||||
|
//dynamic_light_update(n, pos, dir);
|
||||||
|
|
||||||
// store the light ID in the metadata for the node
|
// store the light ID in the metadata for the node
|
||||||
Meta_SetLightID(pLightNode, n);
|
//Meta_SetLightID(pLightNode, n);
|
||||||
return true;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
bool LRoomManager::dynamic_light_register_hint(Node * pLightNode, float radius, Node * pRoom)
|
|
||||||
{
|
|
||||||
// NYI
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LRoomManager::dynamic_light_unregister(Node * pLightNode)
|
bool LRoomManager::dynamic_light_unregister(int light_id)
|
||||||
{
|
{
|
||||||
// NYI
|
// NYI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LRoomManager::dynamic_light_update(Node * pLightNode) // returns room within
|
// returns room within or -1 if no dob
|
||||||
|
int LRoomManager::dynamic_light_update(int light_id, const Vector3 &pos, const Vector3 &dir) // returns room within
|
||||||
{
|
{
|
||||||
|
// doesn't now matter if not in tree as position and dir are passed directly
|
||||||
|
if ((unsigned int) light_id >= (unsigned int) m_Lights.size())
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("dynamic_light_update : meta light ID out of range");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLight &light = m_Lights[light_id];
|
||||||
|
|
||||||
|
int iRoom = light.m_Source.m_RoomID;
|
||||||
|
if (iRoom == -1)
|
||||||
|
{
|
||||||
|
WARN_PRINT_ONCE("dynamic_light_update : can't update global light");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
light.m_Source.m_ptPos = pos;
|
||||||
|
light.m_Source.m_ptDir = dir.normalized();
|
||||||
|
|
||||||
|
// update dob
|
||||||
|
if (light.m_DOB_id != -1)
|
||||||
|
{
|
||||||
|
int iNewRoom = m_DobList.UpdateDob(*this, light.m_DOB_id, pos);
|
||||||
|
light.m_Source.m_RoomID = iNewRoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update with a new Trace (we are assuming update is only called if the light has moved)
|
||||||
|
// remove the old local lights
|
||||||
|
for (int n=0; n<light.m_NumAffectedRooms; n++)
|
||||||
|
{
|
||||||
|
int r = light.m_AffectedRooms[n];
|
||||||
|
GetRoom(r)->RemoveLocalLight(light_id);
|
||||||
|
}
|
||||||
|
light.ClearAffectedRooms();
|
||||||
|
|
||||||
|
|
||||||
|
// now do a new trace, and add all the rooms that are hit
|
||||||
|
m_Trace.Trace_Light(*this, light, LTrace::LR_ROOMS);
|
||||||
|
|
||||||
|
// we should now have a list of the rooms hit in m_LightRender.m_Temp_Visible_Rooms
|
||||||
|
for (int n=0; n<m_LightRender.m_Temp_Visible_Rooms.size(); n++)
|
||||||
|
{
|
||||||
|
int r = m_LightRender.m_Temp_Visible_Rooms[n];
|
||||||
|
|
||||||
|
// add to the list on the light
|
||||||
|
light.AddAffectedRoom(r);
|
||||||
|
|
||||||
|
// add to the list of local lights in the room
|
||||||
|
GetRoom(r)->AddLocalLight(light_id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// this may or may not have changed
|
||||||
|
return light.m_Source.m_RoomID;
|
||||||
|
|
||||||
|
/*
|
||||||
if (!pLightNode)
|
if (!pLightNode)
|
||||||
{
|
{
|
||||||
WARN_PRINT_ONCE("dynamic_light_update : pLightNode is NULL");
|
WARN_PRINT_ONCE("dynamic_light_update : pLightNode is NULL");
|
||||||
@ -949,6 +1070,8 @@ int LRoomManager::dynamic_light_update(Node * pLightNode) // returns room within
|
|||||||
|
|
||||||
// this may or may not have changed
|
// this may or may not have changed
|
||||||
return light.m_Source.m_RoomID;
|
return light.m_Source.m_RoomID;
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LRoomManager::DebugString_Light_AffectedRooms(int light_id)
|
void LRoomManager::DebugString_Light_AffectedRooms(int light_id)
|
||||||
@ -973,7 +1096,7 @@ void LRoomManager::DebugString_Light_AffectedRooms(int light_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LRoomManager::light_register(Node * pLightNode, String szArea)
|
bool LRoomManager::global_light_register(Node * pLightNode, String szArea)
|
||||||
{
|
{
|
||||||
//CHECK_ROOM_LIST
|
//CHECK_ROOM_LIST
|
||||||
|
|
||||||
@ -1002,33 +1125,39 @@ bool LRoomManager::light_register(Node * pLightNode, String szArea)
|
|||||||
return LightCreate(pLight, -1, szArea);
|
return LightCreate(pLight, -1, szArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void LRoomManager::DobChangeVisibility(Spatial * pDOB, const LRoom * pOld, const LRoom * pNew)
|
void LRoomManager::DobUpdateVisibility(int dob_id)
|
||||||
{
|
{
|
||||||
bool bVisOld = false;
|
LDob &dob = m_DobList.GetDob(dob_id);
|
||||||
bool bVisNew = false;
|
|
||||||
|
|
||||||
if (pOld)
|
// return;
|
||||||
bVisOld = pOld->IsVisible();
|
|
||||||
|
|
||||||
if (pNew)
|
bool bRoomVis = pRoom->IsVisible();
|
||||||
bVisNew = pNew->IsVisible();
|
bool bDobVis = pDOB->is_visible_in_tree();
|
||||||
|
|
||||||
|
if (bDobVis != bRoomVis)
|
||||||
if (bVisOld != bVisNew)
|
|
||||||
{
|
{
|
||||||
if (!bVisOld)
|
String sz = "DOB " + pDOB->get_name() + "\t";
|
||||||
|
|
||||||
|
if (bRoomVis)
|
||||||
|
{
|
||||||
pDOB->show();
|
pDOB->show();
|
||||||
|
sz += "coming into view";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
pDOB->hide();
|
pDOB->hide();
|
||||||
|
sz += "exiting view";
|
||||||
|
}
|
||||||
|
|
||||||
|
print_line(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int LRoomManager::dob_get_room_id(int dob_id)
|
||||||
int LRoomManager::dob_get_room_id(Node * pDOB)
|
|
||||||
{
|
{
|
||||||
return Meta_GetRoomNum(pDOB);
|
return m_DobList.GetDob(dob_id).m_iRoomID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// helpers to enable the client to manage switching on and off physics and AI
|
// helpers to enable the client to manage switching on and off physics and AI
|
||||||
@ -1192,15 +1321,14 @@ void LRoomManager::rooms_log_frame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LRoomManager::rooms_set_camera(Node * pCam)
|
bool LRoomManager::rooms_set_camera(int dob_id, Node * pCam)
|
||||||
{
|
{
|
||||||
CHECK_ROOM_LIST
|
CHECK_ROOM_LIST
|
||||||
|
|
||||||
// is it the first setting of the camera? if so hide all
|
// is it the first setting of the camera? if so hide all
|
||||||
if (m_ID_camera == 0)
|
if (m_DOB_id_camera == -1)
|
||||||
ShowAll(false);
|
ShowAll(false);
|
||||||
|
|
||||||
m_ID_camera = 0;
|
|
||||||
|
|
||||||
if (!pCam)
|
if (!pCam)
|
||||||
return false;
|
return false;
|
||||||
@ -1212,15 +1340,17 @@ bool LRoomManager::rooms_set_camera(Node * pCam)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = pCam->get_instance_id();
|
|
||||||
|
// int id = pCam->get_instance_id();
|
||||||
|
|
||||||
// was this a change in camera?
|
// was this a change in camera?
|
||||||
if (id != m_ID_camera)
|
if (m_DOB_id_camera != dob_id)
|
||||||
{
|
{
|
||||||
m_ID_camera = id;
|
m_DOB_id_camera = dob_id;
|
||||||
|
//m_ID_camera = id;
|
||||||
|
|
||||||
// make sure the camera room is correct by doing a teleport
|
// make sure the camera room is correct by doing a teleport
|
||||||
dob_teleport(pCam);
|
//dob_teleport(pCam);
|
||||||
}
|
}
|
||||||
|
|
||||||
// new .. select the cull layer
|
// new .. select the cull layer
|
||||||
@ -1458,17 +1588,18 @@ void LRoomManager::rooms_release()
|
|||||||
rooms_set_active(false);
|
rooms_set_active(false);
|
||||||
|
|
||||||
// unregister all the dobs
|
// unregister all the dobs
|
||||||
for (int n=0; n<m_Rooms.size(); n++)
|
// for (int n=0; n<m_Rooms.size(); n++)
|
||||||
{
|
// {
|
||||||
LRoom &lroom = m_Rooms[n];
|
// LRoom &lroom = m_Rooms[n];
|
||||||
lroom.Release(*this);
|
// lroom.Release(*this);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
ReleaseResources(false);
|
ReleaseResources(false);
|
||||||
|
|
||||||
|
|
||||||
m_ID_camera = 0;
|
m_DOB_id_camera = -1;
|
||||||
|
//m_ID_camera = 0;
|
||||||
m_ID_RoomList = 0;
|
m_ID_RoomList = 0;
|
||||||
|
|
||||||
m_uiFrameCounter = 0;
|
m_uiFrameCounter = 0;
|
||||||
@ -1577,6 +1708,11 @@ bool LRoomManager::FrameUpdate()
|
|||||||
|
|
||||||
CHECK_ROOM_LIST
|
CHECK_ROOM_LIST
|
||||||
|
|
||||||
|
#ifdef LPORTAL_DOBS_AUTO_UPDATE
|
||||||
|
DobsAutoUpdate();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (m_bFrustumOnly)
|
if (m_bFrustumOnly)
|
||||||
{
|
{
|
||||||
// debugging emulate view frustum
|
// debugging emulate view frustum
|
||||||
@ -1593,26 +1729,32 @@ bool LRoomManager::FrameUpdate()
|
|||||||
|
|
||||||
// get the camera desired and make into lcamera
|
// get the camera desired and make into lcamera
|
||||||
Camera * pCamera = 0;
|
Camera * pCamera = 0;
|
||||||
if (m_ID_camera)
|
if (m_DOB_id_camera == -1)
|
||||||
{
|
{
|
||||||
Object *pObj = ObjectDB::get_instance(m_ID_camera);
|
|
||||||
pCamera = Object::cast_to<Camera>(pObj);
|
|
||||||
|
|
||||||
// always doing dob update here for camera, this ensures it is not one frame behind
|
|
||||||
// depending on scene tree, which can cause camera lroom id to be the old one after crossing
|
|
||||||
// a portal plane, causing a flicker on changing room...
|
|
||||||
dob_update(pCamera);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// camera not set .. do nothing
|
// camera not set .. do nothing
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LDob &dob = m_DobList.GetDob(m_DOB_id_camera);
|
||||||
|
pCamera = Object::cast_to<Camera>(dob.GetSpatial());
|
||||||
|
|
||||||
// camera not a camera?? shouldn't happen but we'll check
|
// camera not a camera?? shouldn't happen but we'll check
|
||||||
if (!pCamera)
|
if (!pCamera)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
//Object *pObj = ObjectDB::get_instance(m_ID_camera);
|
||||||
|
//pCamera = Object::cast_to<Camera>(pObj);
|
||||||
|
|
||||||
|
// always doing dob update here for camera, this ensures it is not one frame behind
|
||||||
|
// depending on scene tree, which can cause camera lroom id to be the old one after crossing
|
||||||
|
// a portal plane, causing a flicker on changing room...
|
||||||
|
dob_update(m_DOB_id_camera, pCamera->get_global_transform().origin);
|
||||||
|
|
||||||
|
//dob_update(pCamera);
|
||||||
|
|
||||||
|
|
||||||
// Which room is the camera currently in?
|
// Which room is the camera currently in?
|
||||||
LRoom * pRoom = GetRoomFromDOB(pCamera);
|
LRoom * pRoom = GetRoom(dob.m_iRoomID);
|
||||||
|
|
||||||
if (!pRoom)
|
if (!pRoom)
|
||||||
{
|
{
|
||||||
@ -2073,21 +2215,21 @@ void LRoomManager::_bind_methods()
|
|||||||
// functions to add dynamic objects to the culling system
|
// 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
|
// 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
|
// so they can be held, e.g. in pools elsewhere in the scene graph
|
||||||
ClassDB::bind_method(D_METHOD("dob_register", "dob", "radius"), &LRoomManager::dob_register);
|
ClassDB::bind_method(D_METHOD("dob_register", "node", "pos", "radius"), &LRoomManager::dob_register);
|
||||||
ClassDB::bind_method(D_METHOD("dob_unregister", "dob"), &LRoomManager::dob_unregister);
|
ClassDB::bind_method(D_METHOD("dob_unregister", "dob_id"), &LRoomManager::dob_unregister);
|
||||||
ClassDB::bind_method(D_METHOD("dob_update", "dob"), &LRoomManager::dob_update);
|
ClassDB::bind_method(D_METHOD("dob_update", "dob_id", "pos"), &LRoomManager::dob_update);
|
||||||
ClassDB::bind_method(D_METHOD("dob_teleport", "dob"), &LRoomManager::dob_teleport);
|
// ClassDB::bind_method(D_METHOD("dob_teleport", "dob"), &LRoomManager::dob_teleport);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("dob_register_hint", "dob", "radius", "room"), &LRoomManager::dob_register_hint);
|
// ClassDB::bind_method(D_METHOD("dob_register_hint", "dob", "radius", "room"), &LRoomManager::dob_register_hint);
|
||||||
ClassDB::bind_method(D_METHOD("dob_teleport_hint", "dob", "room"), &LRoomManager::dob_teleport_hint);
|
// ClassDB::bind_method(D_METHOD("dob_teleport_hint", "dob", "room"), &LRoomManager::dob_teleport_hint);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("dob_get_room_id", "dob"), &LRoomManager::dob_get_room_id);
|
ClassDB::bind_method(D_METHOD("dob_get_room_id", "dob"), &LRoomManager::dob_get_room_id);
|
||||||
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("light_register", "light", "area"), &LRoomManager::light_register);
|
ClassDB::bind_method(D_METHOD("global_light_register", "light", "area"), &LRoomManager::global_light_register);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("dynamic_light_register", "light", "radius"), &LRoomManager::dynamic_light_register);
|
ClassDB::bind_method(D_METHOD("dynamic_light_register", "light", "radius"), &LRoomManager::dynamic_light_register);
|
||||||
ClassDB::bind_method(D_METHOD("dynamic_light_register_hint", "light", "radius", "room"), &LRoomManager::dynamic_light_register_hint);
|
// ClassDB::bind_method(D_METHOD("dynamic_light_register_hint", "light", "radius", "room"), &LRoomManager::dynamic_light_register_hint);
|
||||||
ClassDB::bind_method(D_METHOD("dynamic_light_unregister", "light"), &LRoomManager::dynamic_light_unregister);
|
ClassDB::bind_method(D_METHOD("dynamic_light_unregister", "light"), &LRoomManager::dynamic_light_unregister);
|
||||||
ClassDB::bind_method(D_METHOD("dynamic_light_update", "light"), &LRoomManager::dynamic_light_update);
|
ClassDB::bind_method(D_METHOD("dynamic_light_update", "light"), &LRoomManager::dynamic_light_update);
|
||||||
|
|
||||||
@ -2261,3 +2403,35 @@ void LRoomManager::rooms_set_debug_frame_string(bool bActive)
|
|||||||
{
|
{
|
||||||
m_bDebugFrameString = bActive;
|
m_bDebugFrameString = bActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//void LRoomManager::DobsAutoUpdate()
|
||||||
|
//{
|
||||||
|
// // go through each room, each dob
|
||||||
|
// for (int n=0; n<m_Rooms.size(); n++)
|
||||||
|
// {
|
||||||
|
// LRoom &lroom = m_Rooms[n];
|
||||||
|
// int iRoomNum = lroom.m_RoomID;
|
||||||
|
|
||||||
|
|
||||||
|
// for (int d=0; d<lroom.m_DOBs.size(); d++)
|
||||||
|
// {
|
||||||
|
// LDob &dob = lroom.m_DOBs[d];
|
||||||
|
// Spatial * pDOB_Spatial = dob.GetSpatial();
|
||||||
|
|
||||||
|
// if (!pDOB_Spatial)
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// int iNewRoom = DobUpdate(pDOB_Spatial, &lroom);
|
||||||
|
|
||||||
|
// // changed?
|
||||||
|
// if (iNewRoom != iRoomNum)
|
||||||
|
// {
|
||||||
|
// // very inefficient but will do for testing
|
||||||
|
// DobsAutoUpdate();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "lbitfield_dynamic.h"
|
#include "lbitfield_dynamic.h"
|
||||||
#include "lplanes_pool.h"
|
#include "lplanes_pool.h"
|
||||||
|
|
||||||
|
#include "ldoblist.h"
|
||||||
#include "lroom.h"
|
#include "lroom.h"
|
||||||
#include "lportal.h"
|
#include "lportal.h"
|
||||||
#include "larea.h"
|
#include "larea.h"
|
||||||
@ -44,6 +45,7 @@ class LRoomManager : public Spatial {
|
|||||||
friend class LHelper;
|
friend class LHelper;
|
||||||
friend class LTrace;
|
friend class LTrace;
|
||||||
friend class LMainCamera;
|
friend class LMainCamera;
|
||||||
|
friend class LDobList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// PUBLIC INTERFACE TO GDSCRIPT
|
// PUBLIC INTERFACE TO GDSCRIPT
|
||||||
@ -65,7 +67,7 @@ public:
|
|||||||
|
|
||||||
// choose which camera you want to use to determine visibility.
|
// choose which camera you want to use to determine visibility.
|
||||||
// normally this will be your main camera, but you can choose another for debugging
|
// normally this will be your main camera, but you can choose another for debugging
|
||||||
bool rooms_set_camera(Node * pCam);
|
bool rooms_set_camera(int dob_id, Node * pCam);
|
||||||
|
|
||||||
// get the Godot room that is associated with an LPortal room
|
// get the Godot room that is associated with an LPortal room
|
||||||
// (can be used to find the name etc of a room ID returned by dob_update)
|
// (can be used to find the name etc of a room ID returned by dob_update)
|
||||||
@ -81,30 +83,24 @@ public:
|
|||||||
// These are defined by their ability to move from room to room.
|
// 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)
|
// You can still move static objects within the same room (e.g. elevators, moving platforms)
|
||||||
// as these don't require checks for changing rooms.
|
// as these don't require checks for changing rooms.
|
||||||
bool dob_register(Node * pDOB, float radius);
|
|
||||||
// register but let LPortal know which room the dob should start in
|
|
||||||
bool dob_register_hint(Node * pDOB, float radius, Node * pRoom);
|
|
||||||
|
|
||||||
bool dob_unregister(Node * pDOB);
|
|
||||||
|
|
||||||
|
// returns DOB ID
|
||||||
|
int dob_register(Node * pDOB, const Vector3 &pos, float radius);
|
||||||
|
bool dob_unregister(int dob_id);
|
||||||
// returns the room ID within
|
// returns the room ID within
|
||||||
int dob_update(Node * pDOB);
|
int dob_update(int dob_id, const Vector3 &pos);
|
||||||
|
|
||||||
// if we are moving the DOB possibly through multiple rooms, then teleport rather than detect
|
|
||||||
// portal crossings
|
|
||||||
bool dob_teleport(Node * pDOB);
|
|
||||||
bool dob_teleport_hint(Node * pDOB, Node * pRoom);
|
|
||||||
|
|
||||||
//______________________________________________________________________________________
|
//______________________________________________________________________________________
|
||||||
// LIGHTS
|
// LIGHTS
|
||||||
// global directional lights that will apply to all rooms
|
// global directional lights that will apply to all rooms
|
||||||
bool light_register(Node * pLightNode, String szArea);
|
bool global_light_register(Node * pLightNode, String szArea);
|
||||||
|
|
||||||
// dynamic lights (spot or omni within rooms)
|
// dynamic lights (spot or omni within rooms)
|
||||||
bool dynamic_light_register(Node * pLightNode, float radius);
|
// returns light ID
|
||||||
bool dynamic_light_register_hint(Node * pLightNode, float radius, Node * pRoom);
|
// only lights within the rooms on conversion are supported so far
|
||||||
bool dynamic_light_unregister(Node * pLightNode);
|
int dynamic_light_register(Node * pLightNode, float radius);
|
||||||
int dynamic_light_update(Node * pLightNode); // returns room within
|
bool dynamic_light_unregister(int light_id);
|
||||||
|
int dynamic_light_update(int light_id, const Vector3 &pos, const Vector3 &dir); // returns room within
|
||||||
|
|
||||||
//______________________________________________________________________________________
|
//______________________________________________________________________________________
|
||||||
// LIGHTMAPS
|
// LIGHTMAPS
|
||||||
@ -130,7 +126,7 @@ public:
|
|||||||
bool rooms_is_room_visible(int room_id) const;
|
bool rooms_is_room_visible(int room_id) const;
|
||||||
Array rooms_get_visible_rooms() const;
|
Array rooms_get_visible_rooms() const;
|
||||||
// helper func, not needed usually as dob_update returns the room
|
// helper func, not needed usually as dob_update returns the room
|
||||||
int dob_get_room_id(Node * pDOB);
|
int dob_get_room_id(int dob_id);
|
||||||
bool export_scene_DAE(Node * pNode, String szFilename);
|
bool export_scene_DAE(Node * pNode, String szFilename);
|
||||||
|
|
||||||
|
|
||||||
@ -161,8 +157,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
// PER FRAME STUFF
|
// PER FRAME STUFF
|
||||||
|
|
||||||
// godot ID of the camera (which should be registered as a DOB to allow moving between rooms)
|
// camera
|
||||||
ObjectID m_ID_camera;
|
int m_DOB_id_camera;
|
||||||
|
|
||||||
// keep track of which rooms are visible, so we can hide ones that aren't hit that were previously on
|
// keep track of which rooms are visible, so we can hide ones that aren't hit that were previously on
|
||||||
Lawn::LBitField_Dynamic m_BF_visible_rooms;
|
Lawn::LBitField_Dynamic m_BF_visible_rooms;
|
||||||
@ -249,6 +245,7 @@ private:
|
|||||||
// We use a pool for this instead of allocating on the fly.
|
// We use a pool for this instead of allocating on the fly.
|
||||||
LPlanesPool m_Pool;
|
LPlanesPool m_Pool;
|
||||||
|
|
||||||
|
LDobList m_DobList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// whether debug planes is switched on
|
// whether debug planes is switched on
|
||||||
@ -325,10 +322,16 @@ private:
|
|||||||
bool RoomsConvert(bool bVerbose, bool bDeleteLights, bool bSingleRoomMode);
|
bool RoomsConvert(bool bVerbose, bool bDeleteLights, bool bSingleRoomMode);
|
||||||
|
|
||||||
// dobs
|
// dobs
|
||||||
bool DobRegister(Spatial * pDOB, float radius, int iRoom);
|
int DobRegister(Spatial * pDOB, const Vector3 &pos, float radius, int iRoom);
|
||||||
|
|
||||||
ObjectID DobRegister_FindVIRecursive(Node * pNode) const;
|
ObjectID DobRegister_FindVIRecursive(Node * pNode) const;
|
||||||
bool DobTeleport(Spatial * pDOB, int iNewRoomID);
|
// bool DobTeleport(Spatial * pDOB, int iNewRoomID);
|
||||||
void DobChangeVisibility(Spatial * pDOB, const LRoom * pOld, const LRoom * pNew);
|
|
||||||
|
//int DobUpdate(Spatial * pDOB_Spatial, LRoom * pRoom);
|
||||||
|
void DobUpdateVisibility(int dob_id);
|
||||||
|
|
||||||
|
// for debugging only have autoupdate mode where all dobs are updated
|
||||||
|
// void DobsAutoUpdate();
|
||||||
|
|
||||||
void CreateDebug();
|
void CreateDebug();
|
||||||
void ReleaseResources(bool bPrepareConvert);
|
void ReleaseResources(bool bPrepareConvert);
|
||||||
@ -351,15 +354,14 @@ private:
|
|||||||
const LRoom * GetRoom(int i) const;
|
const LRoom * GetRoom(int i) const;
|
||||||
LRoom * GetRoom(int i);
|
LRoom * GetRoom(int i);
|
||||||
|
|
||||||
LRoom * GetRoomFromDOB(Node * pNode);
|
|
||||||
int FindClosestRoom(const Vector3 &pt) const;
|
int FindClosestRoom(const Vector3 &pt) const;
|
||||||
|
|
||||||
LRoom &Portal_GetLinkedRoom(const LPortal &port);
|
LRoom &Portal_GetLinkedRoom(const LPortal &port);
|
||||||
|
|
||||||
// for DOBs, we need some way of storing the room ID on them, so we use metadata (currently)
|
// for DOBs, we need some way of storing the room ID on them, so we use metadata (currently)
|
||||||
// this is pretty gross but hey ho
|
// this is pretty gross but hey ho
|
||||||
int Meta_GetRoomNum(Node * pNode) const;
|
// int Meta_GetRoomNum(Node * pNode) const;
|
||||||
void Meta_SetRoomNum(Node * pNode, int num);
|
// void Meta_SetRoomNum(Node * pNode, int num);
|
||||||
|
|
||||||
// for lights we store the light ID in the metadata
|
// for lights we store the light ID in the metadata
|
||||||
void Meta_SetLightID(Node * pNode, int id);
|
void Meta_SetLightID(Node * pNode, int id);
|
||||||
|
@ -105,7 +105,7 @@ void LTrace::CullSOBs(LRoom &room, const LVector<Plane> &planes)
|
|||||||
void LTrace::CullDOBs(LRoom &room, const LVector<Plane> &planes)
|
void LTrace::CullDOBs(LRoom &room, const LVector<Plane> &planes)
|
||||||
{
|
{
|
||||||
// NYI this isn't efficient, there may be more than 1 portal to the same room
|
// NYI this isn't efficient, there may be more than 1 portal to the same room
|
||||||
|
/*
|
||||||
// cull DOBs
|
// cull DOBs
|
||||||
int nDOBs = room.m_DOBs.size();
|
int nDOBs = room.m_DOBs.size();
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ void LTrace::CullDOBs(LRoom &room, const LVector<Plane> &planes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // for through dobs
|
} // for through dobs
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -601,6 +601,8 @@ void LTrace::FirstTouch(LRoom &room)
|
|||||||
// m_pVisible_Rooms->push_back(room.m_RoomID);
|
// m_pVisible_Rooms->push_back(room.m_RoomID);
|
||||||
|
|
||||||
// hide all dobs
|
// hide all dobs
|
||||||
|
/*
|
||||||
for (int n=0; n<room.m_DOBs.size(); n++)
|
for (int n=0; n<room.m_DOBs.size(); n++)
|
||||||
room.m_DOBs[n].m_bVisible = false;
|
room.m_DOBs[n].m_bVisible = false;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user