Code archives/3D Graphics - Misc/Connected-AABB Occlusion System
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
This code requires these two libraries: 3D Math Functions Stack Functions This library is used to occlude 'blocks' of rooms. What it does is check to see if the player/camera is inside of a node, and then shows connected nodes within a certain 'range'. Pseudo-documentation: CreateSceneNode Creates a scene node. AddEntityToNode Node, Entity Like the name suggests, it adds an entity to a node's list of meshes/entities. This updates the node's AABB so that it can be checked properly. AddAdjacentNode NodeA, NodeB This connects two nodes together. On update, if Camera is in NodeA, NodeB is set to visible if it's in range of NodeA (range would have to be 1 or more). SetNodeBoudnaries Node, MinX, MinY, MinZ, MaxX, MaxY, MaxZ Sets a node's AABB. This most likely does not need to be used, but in the case that you're having trouble you can set custom values. EntityInsideNode Entity, Node Returns true if Entity is inside of Node. UpdateSceneNodes Camera Does what it says. It updates the scene nodes accordingly. NodeVisible Node Returns whether or not a node is visible (after update). GetNodeRoot Node Returns the pivot used by a node. SetNodesVisible Internal. | |||||
;#Region DESCRIPTION ;; Scene node culling system ;#End Region ;#Region CLASSES Type SceneNode Field MinCube.Vector Field MaxCube.Vector Field Cube Field Adjacent Field Root Field Visible End Type Global NodeRange = 2 ;#End Region ;#Region PROCEDURES Function CreateSceneNode() s.SceneNode = New SceneNode s\MinCube = Vector(9999,9999,9999) s\MaxCube = Vector(-9999,-9999,-9999) s\Root = CreatePivot() NameEntity(CreateCube(s\Root),"_NODEOCCLUDER") s\Adjacent = CreateStack() NameEntity s\Root,Handle(s) Return s\Root End Function Function AddEntityToNode(Node,Entity) s.SceneNode = Object.SceneNode(EntityName(Node)) If Upper(EntityClass(Entity)) = "MESH" Then For n = 1 To CountSurfaces(Entity) surf = GetSurface(Entity,n) For i = 0 To CountVertices(surf)-1 x# = VertexX(surf,i) y# = VertexY(surf,i) z# = VertexZ(surf,i) TFormPoint x,y,z,Entity,0 If x < s\MinCube\X Then s\MinCube\X = x If x > s\MaxCube\X Then s\MaxCube\X = x If y < s\MinCube\y Then s\MinCube\y = y If y > s\MaxCube\y Then s\MaxCube\y = y If z < s\MinCube\z Then s\MinCube\z = z If z > s\MaxCube\z Then s\MaxCube\z = z Next Next CreateMeshBox(Entity) Else x# = EntityX(Entity,1) y# = EntityY(Entity,1) z# = EntityZ(Entity,1) If x < s\MinCube\X Then s\MinCube\X = x If x > s\MaxCube\X Then s\MaxCube\X = x If y < s\MinCube\y Then s\MinCube\y = y If y > s\MaxCube\y Then s\MaxCube\y = y If z < s\MinCube\z Then s\MinCube\z = z If z > s\MaxCube\z Then s\MaxCube\z = z EndIf EntityBox FindChild(s\Root,"_NODEOCCLUDER"),s\MaxCube\X,s\MaxCube\Y,s\MaxCube\Z,s\MinCube\X-s\MaxCube\X,s\MinCube\Y-s\MaxCube\Y,s\MinCube\Z-s\MaxCube\Z EntityParent Entity,s\Root End Function Function AddAdjacentNode(NodeA,NodeB) a.SceneNode = Object.SceneNode(EntityName(NodeA)) b.SceneNode = Object.SceneNode(EntityName(NodeB)) PushObject b\Adjacent,NodeA PushObject a\Adjacent,NodeB End Function Function SetNodeBoundaries(Node,MinX#,MinY#,MinZ#,MaxX#,MaxY#,MaxZ#) s.SceneNode = Object.SceneNode(EntityName(Node)) If s = Null Then Return 0 Delete s\MinCube Delete s\MaxCube s\MinCube = Vector(MinX,MinY,MinZ) s\MaxCube = Vector(MaxX,MaxY,MaxZ) Return 1 End Function Function EntityInsideNode(Entity,Node) s.SceneNode = Object.SceneNode(EntityName(Node)) If s = Null Then Return 0 TFormPoint 0,0,0,Entity,s\Root x# = TFormedX() y# = TFormedY() z# = TFormedZ() Return ( x > s\MinCube\X And x < s\MaxCube\X And y > s\MinCube\Y And y < s\MaxCube\Y And z > s\MinCube\Z And z < s\MaxCube\Z ) End Function Function UpdateSceneNodes(Camera) For s.SceneNode = Each SceneNode HideEntity s\Root s\Visible = 0 Next For s.SceneNode = Each SceneNode If EntityInsideNode(Camera,s\Root) Cube = FindChild(s\Root,"_NODEOCCLUDER") For c = 1 To CountChildren(s\Root) child = GetChild(s\Root,c) If Child <> Cube Then If EntityInView(Child,Camera)=0 Then HideEntity child EndIf Next SetNodesVisible(Camera,s\Root,NodeRange) Return EndIf Next For s.SceneNode = Each SceneNode ShowEntity s\Root HideEntity FindChild(s\Root,"_NODEOCCLUDER") Next End Function Function NodeVisible(Node) s.SceneNode = Object.SceneNode(EntityName(Node)) If s = Null Then Return 0 Return s\Visible End Function Function GetNodeRoot(Node) s.SceneNode = Object.SceneNode(EntityName(Node)) If s = Null Then Return 0 Return s\Root End Function Function SetNodesVisible(Camera,Node,Range=2) s.SceneNode = Object.SceneNode(EntityName(Node)) If s = Null Then Return 0 Cube = FindChild(Node,"_NODEOCCLUDER") If Cube = 0 Then rt$ = "ERROR: _NODEOCCLUDER was not found in child list"+Chr(10)+Chr(10)+"Children:" For c = 1 To CountChildren(Node) name$ = EntityName(GetChild(Node,c)) If name$ = "" Then name$ = "NONAME" rt$ = rt$ + Chr(10) + name$ + " : " + GetChild(Node,c) Next If CountChildren(Node) = 0 Then rt$ = rt$ + Chr(10) + "None" RuntimeError rt$ EndIf EntityParent Cube,0 ShowEntity Cube If EntityInView(Cube,Camera) = 1 Or Range=NodeRange Then ShowEntity s\Root s\Visible = 1 HideEntity Cube EntityParent Cube,s\Root For i = 0 To (Objects(s\Adjacent)*(Range-1 > 0))-1 SetNodesVisible(Camera,GetObjectI(s\Adjacent,i),Range-1) Next Return EndIf HideEntity Cube EntityParent Cube,s\Root Return End Function ;#End Region |
Comments
None.
Code Archives Forum