Author Topic: Как удалить все ноды со сцены?  (Read 814 times)

0 Members and 1 Guest are viewing this topic.

Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Marquess
  • *
  • Posts: 889
  • Reputation 63
Как удалить все ноды со сцены?
« on: September 06, 2015, 09:12:04 PM »
Предлагаю сюда помещать все возможные варианты решения.

Вопрос, казалось бы, простейший: как удалить все ноды со сцены?

1) У нас есть  замечательная команда:
Code: [Select]
wRemoveAllNodes()
А как быть, если требуется удалить все ноды, КРОМЕ одной, определенной (или группы нод с заданным ID).
Например, с четко заданным ID=25.
Причем заранее неизвестно, сколько нод задействовано в сцене.

Вот один вариант решения, думаю, есть и другие:
Code: [Select]
Dim As wNode root=wGetRootSceneNode ( )
Dim As Any ptr position
Dim As wNode node= wGetNodeFirstChild ( root, position )
cls
        While wIsNodeLastChild ( root, position ) <>1
node=wGetNodeNextChild ( root,position )
If node<>0 Then
Print Str(wGetNodeID(node))
If wGetNodeID(node)<>25 Then
wRemoveNode(node)
EndIf
EndIf
Wend

Продолжение следует...
« Last Edit: September 07, 2015, 08:30:55 AM by nikolas »
Под лежачий камень мы всегда успеем...

Offline it_is_good

  • Friends
  • Baron (-ess)
  • *
  • Posts: 308
  • Reputation 13
  • I'm a newbie.
Re: Как удалить все ноды со сцены?
« Reply #1 on: September 06, 2015, 10:15:30 PM »
Предполагаю, что если ноды создавать объектами, т.е. ООП, то там просто отслеживать команду на удаление и игнорирование ID'ов сделать... Но это моё мнение и ещё не реализованное в коде  ::)

Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Marquess
  • *
  • Posts: 889
  • Reputation 63
Re: Как удалить все ноды со сцены?
« Reply #2 on: September 07, 2015, 10:24:46 AM »
Попутно рассмотрим вопрос: как удалить все меши, прикрепленные к удаляемым нодам.
Способ вручную, конечно, никто не отменял.
Кроме того, у нас есть волшебная функция:
Code: [Select]
wClearUnusedMeshes ()
Нужно уточнить вопрос: какие меши движок считает за "неиспользуемые".
Если это меши, у которых нет нод, благодаря которым они отображаются на экране, тогда эту команду нужно применять ПОСЛЕ цикла, удаляющего все ноды, кроме заданных (см. выше).

Можно попробовать автоматизировать процесс по другому:
В цикле удаления нод вставить это:
Code: [Select]
If wGetNodeID(node)=100 Then
Dim As wMesh mesh=wGetNodeMesh(node)
If mesh<>0 Then
wRemoveMesh(mesh)
EndIf
EndIf
Здесь предлагается удалять все меши у нод с ID=100
Дело в том, что в WS3D нет функции для определения ТИПА ноды (частица, меш, селектор и пр.).
Значит, при вызове функции wGetNodeMesh(node) для нода, у которого НЕТ МЕША и быть не должно, программа "упадет". Это же относится к нодам wAddSphereSceneNode , wAddCubeSceneNode и подобным.

Если же сразу задать для всех нод, имеющих свой меш, ID=100 (к примеру), то очистка пройдет гладко без участия пользователя.
Под лежачий камень мы всегда успеем...

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 911
  • Reputation 36
  • Game making is my hobby for life!
Re: Как удалить все ноды со сцены?
« Reply #3 on: September 07, 2015, 04:19:16 PM »
Очень хорошая тема с объяснением.

А что за 'cls' в коде? Это же только в консоли?
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Marquess
  • *
  • Posts: 889
  • Reputation 63
Re: Как удалить все ноды со сцены?
« Reply #4 on: September 07, 2015, 05:53:37 PM »
Quote
А что за 'cls' в коде? Это же только в консоли?
Ну да, очистка консоли перед выводом id. Там ниже еще и Print есть.
В ходе загрузки/выгрузки сцены проверялась работоспособность кода путем вывода  ID"оставшихся" нод.
Это для наглядности.
Под лежачий камень мы всегда успеем...

Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Marquess
  • *
  • Posts: 889
  • Reputation 63
Re: Как удалить все ноды со сцены?
« Reply #5 on: September 07, 2015, 06:37:54 PM »
Продолжим.
Заметим сразу, что в движке процесс обслуживания нод автоматизирован, мы рассматриваем случай "ручного" управления.
Для тотального контроля за нодами можно пойти еще проще:
1)При создании дать всем нодам свой ID согласно какому-то правилу,
например так:
Code: [Select]
Dim shared as integer NodesCount=0
...................................
Далее- код создания нода.
Затем:
wSetNodeID(node, NodesCount)
NodesCount+=1

2) В нужный момент организовать цикл, в котором можно удалить нужные или что-то другое:
Code: [Select]
dim i as integer
for i=0 to NodesCount-1
dim as wNode tempNode=wGetSceneNodeFromID(i)
if tempNode<>0 then
     .........
     wRemoveNode(tempNode)
     .........
endif
next

Аналогично можно поступить, используя ИМЕНА нод, задаваемые с помощью
Code: [Select]
wSetNodeName ( node as wNode, name as zstring ptr )а для возвращения значений использовать:
Code: [Select]
const zstring ptr = wGetNodeName ( node as wNode )

ну и соответственно
Code: [Select]
wGetSceneNodeFromName ( name as zstring ptr )

Следует только иметь ввиду нюанс, который касается только совсем начинающих (остальные могут не читать).

Для задания имени не обязательно объявлять указатель типа ZString, высвобождать для него память и прочее,
достаточно написать что-нибудь типа:
Code: [Select]
wSetNodeName(node,"Node "+str(NodesCount))
(Впрочем, никто не запрещает делать как положено:
Code: [Select]
Dim as ZString * 25 name =>"Node "+str(NodesCount)
wSetNodeName(node,name)
)
25- максимальное число символов в имени. Если будет длиннее, произойдет отсечение.

НО, для получения имени нода лучше перестраховаться, так как этот момент может быть КЛЮЧЕВЫМ в некоторых случаях.

Code: [Select]
dim as ZString ptr nodeName
nodeName=Allocate(25)
nodeName=wGetNodeName(node)
print (*nodeName)

Или короче:
Code: [Select]
print (*wGetNodeName(node))
Если будет ТАК:
Code: [Select]
print (str(wGetNodeName(node))),
то распечатается 8-значный набор цифр- числовое представление УКАЗАТЕЛЯ на переменную, хранящую имя нода, но никак не само имя.
« Last Edit: September 07, 2015, 08:02:26 PM by nikolas »
Под лежачий камень мы всегда успеем...