[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 3123»
Форум Panda3D - по русски » Panda3D » Примеры кода » Procedural geometry (процедурная генерация примитивов)
Procedural geometry
soosДата: Пятница, 08.07.2011, 15:44 | Сообщение # 1
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Модуль для процедурной генерации примитивов.

Последнюю версию panda-procedural можно скачать с этого публичного репозитория

Реализовано:

  • Icosasphere (Icosahedron based sphere)
  • TorusKnot (есть непоборотый баг)
  • Torus
  • Tetrahedron
  • Octahedron
  • Icosahedron
  • Dodecahedron


В планах:

  • Hexahedron (cube)
  • Hexasphere (Cube based sphere)
  • Uvsphere
  • Sea shell
  • Limpet Torus
  • Dini's Surface or Twisted Pseudosphere
  • Elliptic Torus


UPD: В связи с тем, что bitbucket стал поддерживать git (чему я очень рад) репозиторий переехал на использование git. Адрес всё тот же.


Сообщение отредактировал soos - Вторник, 11.10.2011, 23:20
 
serg-kkzДата: Пятница, 08.07.2011, 16:49 | Сообщение # 2
Генерал-лейтенант
Группа: Модераторы
Сообщений: 689
Награды: 3
Репутация: 16
Статус: Offline
А чё прям в панде и приспичило генерить))) ведь есть блендер+плагины, шестеренки можно генерить. Да и не про это ли терли мы в топике "Tilemap rendering"? Где то в мануале было, как создать плоский-круг, может ты видел? А дальше формулы используй.

ООП  -  
 
serg-kkzДата: Пятница, 08.07.2011, 17:30 | Сообщение # 3
Генерал-лейтенант
Группа: Модераторы
Сообщений: 689
Награды: 3
Репутация: 16
Статус: Offline
Вот ещё с оф форума панды стырил с топика, модуль для визуализации примитивов ODE, думаю алгоритмы построения фигур можно взять от туда.
Прикрепления: ODEWireGeom.rar(3Kb)


ООП  -  
 
soosДата: Пятница, 08.07.2011, 18:43 | Сообщение # 4
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Quote (serg-kkz)
Да и не про это ли терли мы в топике "Tilemap rendering"?

Нет, не про это. Вернее не совсем про это. Геометрические примитивы и тайловый движок - это разные вещи. Общее только то, что генерация процедурная.
Попробую, в целях самообразования, сделать класс процедурного генератора. Выложу в "примеры кода"
 
serg-kkzДата: Пятница, 08.07.2011, 18:52 | Сообщение # 5
Генерал-лейтенант
Группа: Модераторы
Сообщений: 689
Награды: 3
Репутация: 16
Статус: Offline
Хм... Все таки геометрия, хоть обьёмный примитив - хоть плоский примитив. Хоть так, хоть сяк.

ООП  -  
 
soosДата: Четверг, 14.07.2011, 18:43 | Сообщение # 6
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Меня интересует Ico-сфера, поэтому, в первую очередь, портировал из ogre-procedural именно её построение:

Code

import direct.directbase.DirectStart
from pandac.PandaModules import *
from math import sqrt

def IcoSphere(radius, subdivisions):
  ico_path = NodePath('ico_path')
  ico_node = GeomNode('ico_node')
  ico_path.attachNewNode(ico_node)
  gvd = GeomVertexData('gvd', GeomVertexFormat.getV3(), Geom.UHStatic)
  geom = Geom(gvd)
  gvw = GeomVertexWriter(gvd, 'vertex')
  ico_node.addGeom(geom)
  prim = GeomTriangles(Geom.UHStatic)
  verts = []
  phi = .5*(1.+sqrt(5.))
  invnorm = 1/sqrt(phi*phi+1)
  verts.append(Vec3(-1,  phi, 0) * invnorm)
  verts.append(Vec3( 1,  phi, 0) * invnorm)
  verts.append(Vec3(0,   1,  -phi) * invnorm)
  verts.append(Vec3(0,   1,   phi) * invnorm)
  verts.append(Vec3(-phi,0,  -1) * invnorm)
  verts.append(Vec3(-phi,0,   1) * invnorm)
  verts.append(Vec3( phi,0,  -1) * invnorm)
  verts.append(Vec3( phi,0,   1) * invnorm)
  verts.append(Vec3(0,   -1, -phi) * invnorm)
  verts.append(Vec3(0,   -1,  phi) * invnorm)
  verts.append(Vec3(-1,  -phi,0) * invnorm)
  verts.append(Vec3( 1,  -phi,0) * invnorm)

  faces = [
   0,1,2,
   0,3,1,
   0,4,5,
   1,7,6,
   1,6,2,
   1,3,7,
   0,2,4,
   0,5,3,
   2,6,8,
   2,8,4,
   3,5,9,
   3,9,7,
   11,6,7,
   10,5, 4,
   10,4,8,
   10,9,5,
   11,8,6,
   11,7,9,
   10,8,11,
   10,11,9
  ]

  size = 60

  for subdivision in range(0,subdivisions):
   size*=4;
   newFaces = []
   for i in range(0,size/12):
    i1 = faces[i*3]
    i2 = faces[i*3+1]
    i3 = faces[i*3+2]
    i12 = len(verts)
    i23 = i12+1
    i13 = i12+2
    v1 = verts[i1]
    v2 = verts[i2]
    v3 = verts[i3]
    vt = v1+v2
    vt.normalize()
    verts.append(vt)
    vt = v2+v3
    vt.normalize()
    verts.append(vt)
    vt = v1+v3
    vt.normalize()
    verts.append(vt)
    newFaces.append(i1)
    newFaces.append(i12)
    newFaces.append(i13)
    newFaces.append( i2)
    newFaces.append(i23)
    newFaces.append(i12)
    newFaces.append(i3)
    newFaces.append(i13)
    newFaces.append(i23)
    newFaces .append(i12)
    newFaces.append(i23)
    newFaces.append(i13)
   faces = newFaces
   
  for i in range(0,len(verts)):
   gvw.addData3f(VBase3(verts[i]))
  for i in range(0, len(faces)/3):
   prim.addVertices(faces[i*3],faces[i*3+1],faces[i*3+2])

  prim.closePrimitive()
  geom.addPrimitive(prim)
   
  return ico_path

ico = IcoSphere(1,6)
ico.reparentTo(render)
ico.setRenderModeWireframe()
ico.analyze()
base.setFrameRateMeter(True)
run()


Когда сделаю приличный класс-генератор перенесу в примеры кода.

Долго парился, но так и смог понять почему такой код:

Code

vt = v1+v2
vt.normalize()
verts.append(vt)

работает, а вот такой код:

Code

verts.append((v1+v2).normalize())

не работает. Может кто из опытных питонистов подскажет?
 
serg-kkzДата: Четверг, 14.07.2011, 19:57 | Сообщение # 7
Генерал-лейтенант
Группа: Модераторы
Сообщений: 689
Награды: 3
Репутация: 16
Статус: Offline
(Point3(0, 1, 2)+Point3(0, 1, 3)).normalize(), а как по твоему это будет работать?

v = Point3(0, 1, 2)+Point3(0, 1, 3) вот это будет работать.
v.normalize()

методы применяются к переменной, но не являются математическими функциями.


ООП  -  

Сообщение отредактировал serg-kkz - Четверг, 14.07.2011, 20:03
 
soosДата: Четверг, 14.07.2011, 20:48 | Сообщение # 8
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Code
(Point3(0, 1, 2)+Point3(0, 1, 3)).normalize()

должно работать точно также как и

Code
v = Point3(0, 1, 2)+Point3(0, 1, 3)
v.normalize()

потому что в обоих случаях сначала происходит сложение векторов, а затем нормализация результата.
 
serg-kkzДата: Четверг, 14.07.2011, 21:03 | Сообщение # 9
Генерал-лейтенант
Группа: Модераторы
Сообщений: 689
Награды: 3
Репутация: 16
Статус: Offline
Но результат находиться в памяти, а получить его можно через присвоение переменной(ссылки) - к переменной и применяется метод т.е. нормализация.

Вот короткая запись, что ты делаешь.

print Vec3().normalize()

print Vec3(1).normalize()


ООП  -  
 
ninthДата: Четверг, 14.07.2011, 21:30 | Сообщение # 10
Admin
Группа: Администраторы
Сообщений: 1555
Награды: 5
Репутация: 46
Статус: Offline
Тут не столько питон, сколько особенность метода normalize - он не возвращает вектор, а применяется к вектору
 
serg-kkzДата: Четверг, 14.07.2011, 21:45 | Сообщение # 11
Генерал-лейтенант
Группа: Модераторы
Сообщений: 689
Награды: 3
Репутация: 16
Статус: Offline
soos вертел твой генератор, впечатляет.

ООП  -  
 
soosДата: Четверг, 14.07.2011, 22:12 | Сообщение # 12
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Quote (ninth)
не возвращает вектор, а применяется к вектору

да, всё верно, я понял. я бы даже сказал, что он применяется, но, непонятно почему, не возвращает результат. по итогу цепочку вызовов сделать нельзя sad а было бы неплохо.
тест:

Code
class vec3:
  def __init__(self, x, y, z):
   self.x = x
   self.y = y
   self.z = z
  def __add__(self, other):
   v = vec3(self.x, self.y, self.z)
   v.x += other.x
   v.y += other.y
   v.z += other.z
   return v
  def normalize_1(self):
   self.x = 1
   self.y = 1
   self.z = 1
  def normalize_2(self):
   self.x = 1
   self.y = 1
   self.z = 1
   return self
  def __str__(self):
   return "vec3({0}, {1}, {2})".format(self.x, self.y, self.z)

v1 = (vec3(2,3,4)+vec3(5,6,7)).normalize_1()
print "v1 = {0}".format(v1)
v2 = (vec3(2,3,4)+vec3(5,6,7)).normalize_2()
print "v2 = {0}".format(v2)

я бы назвал это багой, но разработчики, наверняка, скажут что это фича smile
 
ninthДата: Вторник, 19.07.2011, 01:01 | Сообщение # 13
Admin
Группа: Администраторы
Сообщений: 1555
Награды: 5
Репутация: 46
Статус: Offline
Перенёс тему сюда. Кстати, раз пошла такая пьянка, неплохо было бы добавить другие стандартные примитивы - бокс, конус, цилиндр и кинуть это всё на оффсайт, авось в очередной релиз добавят - часто бывает довольно удобно использовать такую геометрию вместо заглушек.
 
soosДата: Среда, 20.07.2011, 10:51 | Сообщение # 14
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Quote (ninth)
неплохо было бы добавить другие стандартные примитивы

Сейчас пытаюсь добавить генерацию Torus Knot, уж больно сложно он генерится, с кучей кватернионов и прочей алгебры, видимо, придётся пока отложить. Остальные примитивы добавлю довольно быстро.

Quote (serg-kkz)
ведь есть блендер+плагины

Пытался делать экспорт/импорт икосферы различными способами из блендера в .egg или .bam - нехватает памяти, а процедурно:

Code
ico = procedural.IcoSphere(1,8)
ico.writeBamFile("icosphere.bam")

И никакого геморроя smile


Сообщение отредактировал soos - Среда, 20.07.2011, 10:52
 
serg-kkzДата: Среда, 20.07.2011, 11:34 | Сообщение # 15
Генерал-лейтенант
Группа: Модераторы
Сообщений: 689
Награды: 3
Репутация: 16
Статус: Offline
Quote (soos)
Пытался делать экспорт/импорт икосферы различными способами из блендера в .egg или .bam - нехватает памяти


Хм... но куда столько уровней подразделений - 8? я 5 нормально экспортировал размер egg 1.6 m, в pz 169 kb. И ещё я не догоняю где можно эту геометрию использовать?!?!


ООП  -  
 
Форум Panda3D - по русски » Panda3D » Примеры кода » Procedural geometry (процедурная генерация примитивов)
Страница 1 из 3123»
Поиск: