QodotPlugin / qodot-plugin

(LEGACY) Quake .map support for Godot 3.x
MIT License
960 stars 70 forks source link

Room support #144

Closed m-decoster closed 2 years ago

m-decoster commented 2 years ago

In Godot 3.4, you can create rooms and portals for occlusion culling purposes.

Rooms require that any objects inside them are placed as children of them in the scene tree. As far as I can tell, this is not possible with the current Qodotmap node. The entire level is turned into one mesh and the rest is simply collision shapes.

Is it possible to automatically generate rooms and portals when importing .map files? Perhaps with special brushes in Trenchbroom that still would require manual placement?

Sleggie commented 2 years ago

It would be great if Qodot made use of Trenchbroom's layer system for this.

Shfty commented 2 years ago

Rooms require that any objects inside them are placed as children of them in the scene tree. As far as I can tell, this is not possible with the current Qodotmap node. The entire level is turned into one mesh and the rest is simply collision shapes.

Qodot builds each entity as a single mesh, with one surface per material. What you're seeing is the singleton 'worldspawn' entity that represents the structural brushes in your map (i.e. brushes without a custom classname).

By using the group class that ships inside the default FGD, you can split brushes out into separate entities that will spawn with their own MeshInstance.

(Note that this is not the same as TrenchBroom groups or layers - those are both TB-specific extensions to the base map format that encode as func_group meta entities, which you are free to parse post-build in godot if you want to access and act upon their metadata.)

This mesh-splitting functionality isn't exclusive to the group class - you can define your own custom brush class, optionally with some associated script logic, in order to create independent mesh objects.

Taking rooms and portals as an example, you could define a room brush class to divide your map up into rooms, a portal class to represent the portal node (with some logic to convert a brush into a portal poly with a given depth), and use some post-build logic to sweep through the tree and attach point entities (such as enemies, pickups, and so forth) to the appropriate parent using point-in-hull checks against the room entities.

Implementing this as first-class functionality is beyond Qodot's scope, as there are various different ways to encode the room and portal abstraction via the existing entity system. Which approach is best will depend on the needs of your project, so defining that superset of functionality is left as an exercise for the user.