Room Networks

Blitz3D Forums/Blitz3D Programming/Room Networks

ClayPigeon(Posted 2010) [#1]
Hello. I noticed a really useful technique in "Metroid: Prime Hunters" for the DS? If you've played it, you probably wondered why when you shoot a door, sometimes you have to wait for 10 seconds or so until the door finally opens. Then, you might have figured out that each room is a separate model and when you shoot a door, it loads the next room model "on the fly" and when it's finished, it opens the door and displays it. When you go in the next room, the previous room is still visible until you get far enough away from the door for it to close automatically. The instant the door closes, the previous room is unloaded. This is a really useful method to save memory, and stay within your polygon quota with speed and detail in a large building or world. I'm trying to figure out how to reproduce this technique in B3D, but I don't know how to go about it. I know that model children can be taken advantage of in B3D. (can you give children names in modelers?) So, could I make each room with its doors and somehow associate the name of the model each door load with the door child? I thought of using an array, and just say "show current room, +1, and -1", but that would only work if the rooms were in a linear path with no branch-offs. So, any suggestions?


ClayPigeon(Posted 2010) [#2]
Also, comments in the settings of child objects (in DeleD). Just in case that might be useful..


_PJ_(Posted 2010) [#3]
I've sseen many sugegstions to this kind of "portalling" done by having various 'rooms'* (*and their contents) parented to a pivot, the pivots can be hidden, to remove the rooms* from collision/rendering.

Modellers do allow for naming, though I'm not sure precisely whihc formats retain the information when loaded into B3D.
-----------------------
Perhaps giving the spearate doors a name or tracking them in a Type/array structure can allow for the specific 'rooms' to be identified according to the door 'chosen'?


ClayPigeon(Posted 2010) [#4]
Thanks. I'm going to have the doors open when the distance between the camera and the door is smaller than a value. How would I have it detect which side of the door I'm on? It somehow needs to know which room to hide when it shuts. I'm very reluctant to make a separate model with boxes to tell what room it's in. Is there another way??


GIB3D(Posted 2010) [#5]
I think your right except for the previous room doesn't unload until you go through a different door. If you walk from Room1 to Room2 and the door shuts, Room1 is still there because you can open the door again and there's no delay. But if you go from Room2 to Room3, Room1 is unloaded.


ClayPigeon(Posted 2010) [#6]
Are you saying I should keep Room1 loaded, or let Room1 keep being rendered? Aside from memory usage, I'm also trying to keep the polygon count down so I can make individual rooms very high quality. There's no need to render the rooms the camera can't see. Just use HideEntity, because you're no longer in the room - no need for collisions, and there's a closed door blocking the room - no need to render. Just don't unload it until you're two rooms away.


Matty(Posted 2010) [#7]
Use Tformnormal/vector/point to determine if you are in front of or behind the door.

ie TformPoint myx,myx,myz,0,door

where myx-myz are the coordinates of the player or other creature to be checked

"0" indicated world space

"door" indicates door local space

if tformedz()>0 then you are on one side of the door
if tformedz()<0 then you are on the other side of the door
(assuming forward facing for your door is along the z-axis)


GIB3D(Posted 2010) [#8]
Just don't unload it until you're two rooms away.

Exactly.

Another two ways you could check which side of the door you are on.
1. Make a trigger inside the door that checks if your Mesh Intersects with it. If so, it toggles a variable that decides which side you are on.
Ex. Variable1 = 0 in Room1
When you touch the trigger Variable1 = 1 meaning you're in the next room.

2. You could place a pivot on either side of the door and get the distance from the player to each pivot and decide which one you are closer to.


ClayPigeon(Posted 2010) [#9]
OK. I've got SOME stuff so that it works right. Now all I need to know is how to do the door opening and closing stuff. I have everything in the same model with names and I'm just using model children to call things. Unfortunately, the model childrens' XYZ coordinates aren't stored properly or something, so it returns all of their coordinates as 0,0,0. So, does this mean I'll have to use a dropper? I actually think it would be better because then I could put the code in a door type instead of tediously retyping code for each one.


_PJ_(Posted 2010) [#10]
Sounds to me like a global/local issue.

The local coordinates of any children will be relative to their parent which is at 0,0,0 whilst the Global coords will be relative to the 'world'

Functions such as PositionEntity or EntityX() etc have an optional flag to specify whether to use the Global coordinates.

For example:

Graphics3D 800,600,32,6
SetBuffer BackBuffer()


Camera=CreateCamera()

;just create some entities, note, they're not yet parent/child related, so both act as global
;By default EVERYTHING is positioned at 0,0,0 when no parent is specified in Creation

ParentCube=CreateCube()
ChildSphere=CreateSphere()

;The PARENT is going to be at Z=5 (world coords - global)
PositionEntity ParentCube,0,0,5
;The CHILD is still at Z=0 (world coords -global)

;Let's make sure the camera can see the objects
MoveEntity Camera,0,2,-5
PointEntity Camera,ParentCube

; Now the relationship is formed
EntityParent ChildSphere,ParentCube

RenderWorld
Flip

Print "Local Coords of child (local relative to Parent): "+Str(EntityX(ChildSPhere))+" x "+Str(EntityY(ChildSPhere))+" x "+Str(EntityZ(ChildSPhere))
Print "Global Coords of child (local relative to World): "+Str(EntityX(ChildSPhere,True))+" x "+Str(EntityY(ChildSPhere,True))+" x "+Str(EntityZ(ChildSPhere,True))
WaitKey()


In the above code, although GLOBALLY the Cube is at +5 on the Z axis and the Sphere is at 0, the LOCAL coordinates display the relationship between the two, so the child Sphere is shown to be at -5
as 0 is 5 -5


ClayPigeon(Posted 2010) [#11]
Yeah, thanks.. I tried that too. It still thinks that every door is at 0,0,0. Thanks for trying but I think it would be more intelligent to use a dropper. Thanks!


_PJ_(Posted 2010) [#12]
Sorry to hesar that doesn;'t solve theproblm - not sure what it might be then, unless yyou're not referring to the correct entity?

Good luck, I think some of the ideas in this thread are really useful.
Out of curiosity, what is a dropper?


ClayPigeon(Posted 2010) [#13]
I'm not sure if I'm using the right term, but from what I've heard, a "dropper" is a program that makes allows you place objects visually instead of trial and error with coordinates. It's easy enough to make a primitive dropper specifically for the development of your game.


GIB3D(Posted 2010) [#14]
So you basically mean Map Editor. About the door.. when you export it is the model at 0,0,0 in the 3D Modelling Program? When Blitz loads a mesh, it starts at the center so if your vertices aren't there, then it will seem as if the programs are against you and want nothing but to confuse you.


ClayPigeon(Posted 2010) [#15]
I really don't think it can be a relative positioning problem, because no matter where the door is, it always reads as 0,0,0.


ClayPigeon(Posted 2010) [#16]
OK, so here is what I've gotten so far from this:

http://host-a.net/ClayPigeon/RoomEngine.zip

You can uncomment the Wireframe True part to see the problem.
In the CreateDoor function, you specify the two neighboring rooms on either side of the door. But, the way I have it set up, two or more doors won't mix in the same level correctly. How would I fix this??

EDIT: Sorry about that! I wondered why no one was saying anything. I forgot I have a widescreen, and I had it for 1440x900, sorry. Link fixed, also doors are thicker..


ClayPigeon(Posted 2010) [#17]
Okay, never mind, people. I FINALLY got it figured out. Thanks for your tremendous help!

P.S. - Have fun with the non-functional demo!


GIB3D(Posted 2010) [#18]
Just now checked back to this thread, glad you got it figured out ;)


ClayPigeon(Posted 2010) [#19]
Unfortunately, I have a new problem now. The way I have it set up is:
-I have a door type
-Each frame, it goes through and finds out if you're close enough to a door to open it.
-If there is, then show both of the rooms associated with that door.
-Else, if there isn't, find the closest door to you and use TFormPoint to find out what side of it you're on.

This works fine for cubic rooms, but what if I have a chunk of room protruding past a door? When you go into the protruding section, *POOF!!* the room you're in is gone, and you fall into the cold, black void. So, what if I found out what side of a door whose face extruded to infinity the camera is on and colliding with? That would work fine, but what if I didn't intersect with one at all... what?? - I don't know..


_PJ_(Posted 2010) [#20]
I'm glad you got the door oords wokrking.

From what I understand from your new post, the problem arises since the progeam detects which room the player is in (therefore, which rooms should shown or hidden) only by which side of the nearest door the player is on.

I can foresee a way around this is to keep a variable or counter that records which room the player is in. This is only updated ONCE THE PLAYER ACTUALLY ENTERS A DOORWAY.

The checks made on opening a door can then decide which rooms to show, always maintaining the current room is not hidden.

- In the current setup, I imagine errors might arise if doors are opened on opposite sides of a single room too?


ClayPigeon(Posted 2010) [#21]
Here, I'll give you an example.
The way I've got it set up now, doors work at any angle and any height as long as there are no protrusions. In Room03 I put a protrusion in the wall to demonstrate the problem. (look for the oddly dark polygon).

http://host-a.net/ClayPigeon/ProtrusionError.zip


ClayPigeon(Posted 2010) [#22]
Is there some way it could detect when I collide with the inside of the door?