1. Пользоваться форумом на планшетах и телефонах стало удобнее благодаря Tapatalk

Попытка создания снега maxscript'ом

Тема в разделе "MAXScript", создана пользователем Александр Якушев, 7 фев 2014.

Модераторы: Savin Denis
  1. Александр Якушев

    Александр Якушев Активный участник

    С нами с:
    13.08.2009
    Сообщения:
    77
    Симпатии:
    1
    Баллы:
    7
    Пытаюсь автоматизировать создание снега с помощью максскрипта. Что-то получается, но очень долго обсчитывает. Посмотрите код, пожалуйста, может удастся как-то ускорить.

    Сам код состоит из двух частей - сам скрипт и BirthScript для PF Source

    скрипт:
    Создает массив лучей(с произвольными позиция по плоскости XY) над поверхностью, направленных вниз, затем находит пересечение с поверхностью и если уклон меньше 20 градусов, то точка пересечения записывается в глобальную переменную global ArrayPoints, которую потом использует скриптовой оператор BirthScript в PF Source

    Код:
    (
    --vvedem funkciy polucheniya ugla mejdu vectorami:
    	fn GetVectorsAngle v1 v2 = (  theAngle = acos(dot (normalize v1) (normalize v2))  )	
    
    	theGeomObj = snapshot $   -- snimok geometrii kak mesh objekta
    
    	global ArrayPoints = #() -- globalnaya peremennaya dlya sozdaniya chasticw
    	
    	ArrayRay = #() -- massiv dlya luchey
    	RayCount = 1000000 -- kolichestvo luchikov ili "snejinok"
    	Uklon = 20.0 -- uklon poverhnosti zaderjanoya snejinok 
    		
    	progressstart "Generating snowflakes..."  -- add progress
    		
    -- sozdanie massiva luchey po razmera objecta 	
    	for i = 1 to RayCount do
    	(
    		local rayX = random theGeomObj.min.x theGeomObj.max.x
    		local rayY = random theGeomObj.min.y theGeomObj.max.y
    		local rayZ = theGeomObj.max.z + 100.0
    		local ThePosRay = [rayX, rayY, rayZ]
    		local TheDirRay = [0.0, 0.0, -1.0]
    		local TheRay = ray ThePosRay TheDirRay
    		append  ArrayRay TheRay
    		)	
    --dlya kajdogo luchika naydem peresechenie s geometriey i vichislim ugol 
    -- esli ugol > 170 to zapisat point v massiv 	ArrayPoints dlya  Birth Scripts
    for i = 1 to RayCount do
    (
    	theIntRay = intersectRay theGeomObj ArrayRay[i]	-- intersection ray with geom Obj
    	
    	progressupdate (i as float /RayCount *100) -- update progressbar
    	
    	if theIntRay != undefined do
    	(
    		local theAngle = GetVectorsAngle theIntRay.dir ArrayRay[i].dir -- ugol mejdu vektorami
    		if theAngle >= (180.0 - Uklon) do  append ArrayPoints  theIntRay.pos
    		)		
    	)
    	progressend () -- end progressbar
    	
    	delete theGeomObj
    	)
    
    -------------------------------------
    скрипт для BirthScript оператора:
    Использует глобальную переменную global ArrayPoints для создания частиц

    Код:
    on ChannelsUsed pCont do
    (
    pCont.useTime = true
    pCont.useAge = true
    pCont.usePosition = true
    pCont.useSpeed = true
    )
    
    on Init pCont do
    (
    
    )
    
    on Proceed pCont do
    (
    t1 = pCont.getTimeEnd() as float
    
    if t1 == 0 do
    (
    		 for i in ArrayPoints do
    		(
    			pCont.AddParticle()
    			pCont.particleIndex = pCont.NumParticles() -- last particle that was added
    			pCont.particlePosition = i
    		) 
    )
    
    )
    
    Порядок теста был таков:
    1. Создаеть plane 500x500 сегметнов 100x100 сверху нойз с силой ~100 по оси Z
    2. При выделенном плэйне запустить скрипт - будет создана глобальная переменная с массивом точек для PF Source
    3. Создать, соответственно, PF Source, - вместо оператора Birth - оператор BirthScript с вышеприведенным вторым скриптом. Из остальных операторов оставить только Display (не забудьте в свойствах PF Source поднять Upper Limit хотя бы до миллиона)
    Для создания геометрии снега на частицы применяется PWrapper.

    Собственно, суть проблемы:
    1. Если параметр RayCount (количество лучиков) увеличить допустим до 5 000 000, очень замедляется процесс.
    2. Также если согментов Plane поднять до 1000х1000 (2 000 000 треугольников, что очень даже может быть, особенно на деревьях) при RayCount = 100 000 - процесс опять надолго зависает.
    3. Ну и если и RayCount увеличить и использовать высокополигональный объект , то вообще улетает.

    Можно ли как-то упростить, ускорить весь процесс? Уж больно долго считает, проще ручками повыделять полики и посадить на них частицы.
     

    Вложения:

    • 3280935.jpg
      3280935.jpg
      Размер файла:
      28,7 КБ
      Просмотров:
      77
  2. maiden666

    maiden666 Знаток

    С нами с:
    06.04.2010
    Сообщения:
    3.092
    Симпатии:
    87
    Баллы:
    74
    я не понимаю в скриптах, но занимаюсь частицами и алгоритмами
    Если я правильно понял мысль, идея в том, чтобы частицы образовывались на склонах определённой крутизны?
    В SoftimageICE я бы реализовал это так: у вертексов и поверхностей имеется атрибут Tangent ( касательная), если он меньше или больше определённого значения, то... ( по вашему выбору)
    Думаю, в МаксСкрипт должен быть доступ к подобноиу атрибуту
     
  3. Александр Якушев

    Александр Якушев Активный участник

    С нами с:
    13.08.2009
    Сообщения:
    77
    Симпатии:
    1
    Баллы:
    7
    В принципе почти правильно, за небольшим исключением. Если у нас, к примеру, елка или сложное дерево - одним склоном определенной крутизны не отделаетесь). Тут важно еще учитывать пересечение траектории снежинки (произвольного вектора) именно с первым полигоном. На нижние ярусы снег не должен проникать. Грубо говоря, если просто крутизну полика учитывать, то внутри елки тоже снега насыпет.
     
Модераторы: Savin Denis

Поделиться этой страницей