Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для компьютеров > Blitz3D > FAQ

FAQ Туториалы и часто задаваемые вопросы

Ответ
 
Опции темы
Старый 11.04.2012, 08:38   #1
burovalex
Разработчик
 
Аватар для burovalex
 
Регистрация: 04.04.2012
Сообщений: 468
Написано 36 полезных сообщений
(для 59 пользователей)
getMathElement()

Взял пример с хелпа

Graphics3D 640,480 
SetBuffer BackBuffer() 

camera=CreateCamera() 
PositionEntity camera,0,0,-5 

light=CreateLight() 
RotateEntity light,90,0,0 

sphere=CreateSphere() 

PositionEntity sphere,0,0,0 
ScaleEntity sphere,1,2,3 
RotateEntity sphere,0,0,0 

While Not KeyDown(1) 
RenderWorld 

Text 0,0,GetMatElement#(sphere,1,1) 

Flip 
Wend 
End
Выводит двойку масштаба
Перебла все комбинации от 0-3, все остальные ноль
Помогите чайнику
__________________
(Offline)
 
Ответить с цитированием
Старый 11.04.2012, 09:18   #2
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 65
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: getMathElement()

Сообщение от burovalex Посмотреть сообщение
Взял пример с хелпа

Graphics3D 640,480 
SetBuffer BackBuffer() 

camera=CreateCamera() 
PositionEntity camera,0,0,-5 

light=CreateLight() 
RotateEntity light,90,0,0 

sphere=CreateSphere() 

PositionEntity sphere,0,0,0 
ScaleEntity sphere,1,2,3 
RotateEntity sphere,0,0,0 

While Not KeyDown(1) 
RenderWorld 

Text 0,0,GetMatElement#(sphere,1,1) 

Flip 
Wend 
End
Выводит двойку масштаба
Перебла все комбинации от 0-3, все остальные ноль
Помогите чайнику
Чайнику надо почитать про матрицы и вектора.

GetMatElement возвращает элемент матрицы трансформации энтити. Матрица квадратная порядка 4. Т.е. 4х4 - четыре 4-хмерных вектора.

Т.к. эта матрица трансформации комбинирует в себе масштаб, поворот и смещение, то просто так извлечь какую-то трансформацию нельзя.
В твоем случае, чтобы извлечь масштаб, надо взять длины векторов по каждой оси:

;   | 0 1 2 3
; ------------
; 0 | X Y Z W
; 1 | X Y Z W
; 2 | X Y Z W
; 3 | X Y Z W

; чистая матрица масштаба выглядит так:
; X 0 0 0
; 0 Y 0 0
; 0 0 Z 0
; 0 0 0 1

XAxisX# = GetMatElement ( Entity, 0, 0 )
XAxisY# = GetMatElement ( Entity, 0, 1 )
XAxisZ# = GetMatElement ( Entity, 0, 2 )

YAxisX# = GetMatElement ( Entity, 1, 0 )
YAxisY# = GetMatElement ( Entity, 1, 1 )
YAxisZ# = GetMatElement ( Entity, 1, 2 )

ZAxisX# = GetMatElement ( Entity, 2, 0 )
ZAxisY# = GetMatElement ( Entity, 2, 1 )
ZAxisZ# = GetMatElement ( Entity, 2, 2 )

ScaleX# = Sqr ( XAxisX * XAxisX + XAxisY * XAxisY + XAxisZ * XAxisZ )
ScaleY# = Sqr ( YAxisX * YAxisX + YAxisY * YAxisY + YAxisZ * YAxisZ )
ScaleZ# = Sqr ( ZAxisX * ZAxisX + ZAxisY * ZAxisY + ZAxisZ * ZAxisZ )
ЗЫ
В университетах на линейно алгебре преподают вектора и матрицы, но это мало применимо к геймдеву (хотя знать определения и как перемножаются матрицы надо обязательно), так что доки читать надо, а вот про кватернионы там не учат (по крайней мере в мое время не было), так что по этому тоже доки читай, пригодится.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
burovalex (11.04.2012)
Старый 11.04.2012, 12:21   #3
burovalex
Разработчик
 
Аватар для burovalex
 
Регистрация: 04.04.2012
Сообщений: 468
Написано 36 полезных сообщений
(для 59 пользователей)
Ответ: getMathElement()

Спасибо большое!
Я тоже изучал матрицы, но дело тов том, что в справках не расписывают в каком элементе матрицы что лежит, даже на blitz etc
Подскажите пожалуйста еще в каких ячейках находятся поворот и смещения, для полной информации
__________________
(Offline)
 
Ответить с цитированием
Старый 11.04.2012, 13:36   #4
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 65
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: getMathElement()

Сообщение от burovalex Посмотреть сообщение
Подскажите пожалуйста еще в каких ячейках находятся поворот и смещения, для полной информации
смещение тут:
1 0 0 0
0 1 0 0
0 0 1 0
X Y Z 1
т.е.
X# = GetMatElement ( Entity, 3, 0 )
Y# = GetMatElement ( Entity, 3, 1 )
Z# = GetMatElement ( Entity, 3, 2 )
матрица вращения это вот эта 3x3 часть:
X Y Z 0
X Y Z 0
X Y Z 0
0 0 0 1
извлечь из нее углы Эйлера можно так:
XAxisY# = GetMatElement ( Entity, 0, 1 )

YAxisY# = GetMatElement ( Entity, 1, 1 )

ZAxisX# = GetMatElement ( Entity, 2, 0 )
ZAxisY# = GetMatElement ( Entity, 2, 1 )
ZAxisZ# = GetMatElement ( Entity, 2, 2 )

Pitch# = ATan2 ( ZAxisY, Sqr ( ZAxisX * ZAxisX + ZAxisZ * ZAxisZ ) )
Yaw# = ATan2 ( ZAxisX, ZAxisZ )
Roll# = ATan2 ( XAxisY, YAxisY )
Но для блица это не практично, т.к. встроеные EntityPitch|Yaw|Roll будут производительнее, к тому-же эти углы и смещения глобальны, т.е. с учетом трансформации всех предков энтити.
(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо Платон Александрович за это полезное сообщение:
burovalex (11.04.2012), HolyDel (11.04.2012), Randomize (12.04.2012), Черный крыс (31.05.2012)
Старый 31.05.2012, 18:37   #5
Черный крыс
 
Сообщений: n/a
Ответ: getMathElement()

так я не понял... а какого фига они глобальны ? Ведь система обьектов предпологает, что вся инфа о трансформациях должна хранится в относительных координатах ( относительно родительских ). Тогда в чем вообще их смысл ?

Я же считал, что извлечение глобыльных параметров происходит за счет перебора всех родителей.
 
Ответить с цитированием
Старый 01.06.2012, 04:37   #6
Платон Александрович
Нуждающийся
 
Аватар для Платон Александрович
 
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 65
Написано 42 полезных сообщений
(для 83 пользователей)
Ответ: getMathElement()

Сообщение от Diablo1909 Посмотреть сообщение
так я не понял... а какого фига они глобальны ? Ведь система обьектов предпологает, что вся инфа о трансформациях должна хранится в относительных координатах ( относительно родительских ). Тогда в чем вообще их смысл ?

Я же считал, что извлечение глобыльных параметров происходит за счет перебора всех родителей.
Не совсем так. Когда меняется координаты\угол ентити, происходит отложенный перерасчет матриц его самого и его чайлдов. Т.е. там флажок который указывает что трансформации надо перерасчитать. Это делается либо по необходимости (например тем же самым вызовом GetMatElement) до рендера, либо непосредственно перед ним, чтобы получить глобальную матрицу для каждого ентити. Эта матрица и передается в Direct3D для трансформации вершин. GetMatElement возвращает элементы этой матрицы.
Подробнее можно посмотреть в исходниках miniB3D, там в файле geom.h почти вся 3д математика. А устройство иерархии (впрочем и geom.h там же) в исходниках sdk.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Черный крыс (01.06.2012)
Старый 01.06.2012, 08:03   #7
Черный крыс
 
Сообщений: n/a
Ответ: getMathElement()

Мой вариант системы энтити - правда он 2Д и на БМаксе, но тут исповедуется моя религия.

Private
Type TPivot Extends TEntity
 Field _parent:TPivot {no_save = 1}
 Field _childs:TListEx = New TListEx
 
 Field _ang:Float
 Field _pos:Float2 = New Float2
 Field _scl:Float2 = New Float2.Create(1.0, 1.0)
 
 Field _tps:Float2 = New Float2
 
 Field _call(entity:TEntity, dt:Float) = NullCallBack {no_save = 1}
 
 Function NullCallBack(entity:TEntity, dt:Float)
 End Function
 
 Method SetCallBack(func(entity:TEntity, dt:Float) = Null, isGlobal:Byte = False) Final
  Super.SetCallBack(func, isGlobal)
  If func = Null Then func = NullCallBack
  _call = func
 End Method
 
 Method New()
  world.AddLast(Self)
 End Method
 
 Method Free()
  Super.Free()
  _pos = Null
  _scl = Null
  _tps = Null
  _ang = Null
  _childs = Null
  GetParentList().Remove(Self)
  _parent = Null
 End Method
 
 Method Copy:TEntity(parent:TEntity = Null)
  Local pivot:TPivot = New TPivot
  pivot.name = "copy_" + name
  pivot.hide = hide
  'pivot.data = data
  pivot._pos = _pos.Copy()
  pivot._scl = _scl.Copy()
  pivot._tps = _tps.Copy()
  pivot._ang = _ang
  pivot.SetParent(parent)
  If parent Then pivot.SetPosition(New Float2)
  Return pivot
 End Method
 
 Method ToString:String()
  Return "Pivot"
 End Method
 
 Method SetPosition(position:Float2, isGlobal:Byte = False) Final
  If isGlobal And _parent
   _tps = position.Sub(_parent.GetGlobalTransformedPosition())
   _pos = _tps.UnRotate(New Float2.ForAngle(_parent._ang))
   _pos = _pos.Div(_parent._scl)
  Else
   _pos = position.Copy()
   Transform()
  End If
  'TranslateChilds()
 End Method
 
 Method GetPosition:Float2(isGlobal:Byte = False) Final
  If isGlobal
   Return GetGlobalTransformedPosition()
  Else
   Return _pos.Copy()
  End If
 End Method
 
 Method SetRotation(angle:Float, isGlobal:Byte = False) Final
  Local da:Float = _ang
  If isGlobal
   _ang = angle
  Else
   _ang = angle + GetParentAngle()
  End If
  RotateChilds(_ang - da)
 End Method
 
 Method GetRotation:Float(isGlobal:Byte = False) Final
  If isGlobal Then Return _ang
  Return _ang - GetParentAngle()
 End Method
 
 Method SetScale(scale:Float2, isGlobal:Byte = False) Final
  Local ds:Float2 = _scl.Copy()
  If isGlobal
   _scl = scale.Copy()
  Else
   _scl = scale.Mul(GetParentScale())
  End If
  ScaleChilds(_scl.Div(ds))
 End Method
 
 Method GetScale:Float2(isGlobal:Byte = False) Final
  If isGlobal Then Return _scl.Copy()
  Return _scl.Div(GetParentScale())
 End Method
 
 Method SetTransform(angle:Float, scale:Float2, isGlobal:Byte = False) Final
  Local da:Float = _ang
  Local ds:Float2 = _scl.Copy()
  If isGlobal
   _ang = angle
   _scl = scale.Copy()
  Else
   _ang = angle + GetParentAngle()
   _scl = _scl.Mul(GetParentScale())
  End If
  TransformChilds(_scl.Div(ds), _ang - da)
 End Method
 
 Method SetParent(parent:TEntity) Final
  If _parent = parent Then Return
  GetParentList().Remove(Self)
  _parent = TPivot(parent)
  GetParentList().AddLast(Self)
  If _parent
   _ang = _parent._ang
   _scl = _parent._scl.Copy()
   SetPosition(New Float2)
  End If
 End Method
 
 Method GetParent:TEntity() Final
  Return _parent
 End Method
 
 Method CountChildren:Int() Final
  Return _childs.Count()
 End Method
 
 Method GetChild:TEntity(index:Int) Final
  Return TEntity(_childs.ValueAtIndex(index))
 End Method
 
 Method ObjectEnumerator:TListEnum() Final
  Return _childs.ObjectEnumerator()
 End Method
 
 Method Intersect:Byte(entity:TEntity)
  Select entity.ToString()
   Case "Pivot" Return False
  End Select
  
 End Method
 
 Method SetOrder(order:Int) Final
  Local list:TListEx = GetParentList()
  Select Sgn(order)
   Case 1 list.MoveDown(Self, order)
   Case - 1 list.MoveUp(Self, - order)
  End Select
 End Method
 
 'PRIVATE
 
 Method Build(parent:TPivot)
  'If _parent = parent Then Return
  For Local child:TPivot = EachIn _childs
   child.Build(Self)
  Next
  _parent = parent
  If Not GetParentList().Contains(Self) Then GetParentList().AddLast(Self)
 End Method
 
 Method Update(dt:Float)
  If hide Then Return
  _call(Self, dt)
  For Local child:TPivot = EachIn _childs
   child.Update(dt)
  Next
 End Method
 
 Method Draw(position:Float2)
  If hide Then Return
  Local mypos:Float2 = position.Add(_tps)
  If Debug
   .SetTransform()
   .SetColor(255, 255, 255)
   .SetAlpha(1.0)
   .SetBlend(ALPHABLEND)
   DrawOval(mypos.x - 3, mypos.y - 3, 6, 6)
  End If
  For Local child:TPivot = EachIn _childs
   child.Draw(mypos)
  Next
 End Method
 
 Method GetParentList:TListEx() Final
  If _parent Then Return _parent._childs
  Return world
 End Method
 
 Method GetParentScale:Float2() Final
  If _parent Then Return _parent._scl
  Return New Float2.Create(1.0, 1.0)
 End Method
 
 Method GetParentAngle:Float() Final
  If _parent Then Return _parent._ang
  Return 0.0
 End Method
 
 Method ScaleChilds(ds:Float2) Final
  For Local child:TPivot = EachIn _childs
   child._scl = child._scl.Mul(ds)
   child.Transform()
   child.ScaleChilds(ds)
  Next
 End Method
 
 Method RotateChilds(da:Float) Final
  For Local child:TPivot = EachIn _childs
   child._ang:+da
   child.Transform()
   child.RotateChilds(da)
  Next
 End Method
 
 'Method TranslateChilds()
 ' For Local child:TPivot = EachIn _childs
 '  'Calc BBox
 '  child.TranslateChilds()
 ' Next
 'End Method
 
 Method TransformChilds(ds:Float2, da:Float) Final
  For Local child:TPivot = EachIn _childs
   child._scl = child._scl.Mul(ds)
   child._ang:+da
   child.Transform()
   child.TransformChilds(ds, da)
  Next
 End Method
 
 Method Transform() Final
  _tps = _pos.Mul(GetParentScale())
  _tps = _tps.Rotate(New Float2.ForAngle(GetParentAngle()))
 End Method
 
 Method GetGlobalTransformedPosition:Float2() Final
  Local pos:Float2 = _tps.Copy()
  Local pivot:TPivot = _parent
  While pivot
   pos = pos.Add(pivot._tps)
   pivot = pivot._parent
  Wend
  Return pos
 End Method
 
 '*******************
 
 Method GetPick:Byte()
 End Method
 
 Method GetAlpha:Float()
 End Method
 
 Method GetBlend:Byte()
 End Method
 
 Method GetColor:TColor()
 End Method
 
 Method Align(vector:Float2) Final
  SetRotation(vector.ToAngle() + 90.0, True)
 End Method
 
 Method Point(target:TEntity) Final
  Align(TPivot(target).GetGlobalTransformedPosition().Sub(GetGlobalTransformedPosition()))
 End Method
 
 Method Delta:Float(target:TEntity) Final
  Return (target.GetRotation(True) - _ang)
 End Method
 
 Method Distance:Float(target:TEntity) Final
  Return GetGlobalTransformedPosition().Sub(TPivot(target).GetGlobalTransformedPosition()).Length()
 End Method
 
 Method Move(speed:Float2) Final
  _pos = _pos.Add(speed.Rotate(New Float2.ForAngle(_ang)))
  Transform()
 End Method
 
 Method Turn(speed:Float) Final
  _ang:+speed
  RotateChilds(speed)
 End Method
 
 Method Translate(speed:Float2) Final
  _pos = _pos.Add(speed)
  _tps = _tps.Add(speed)
  Transform()
 End Method
End Type
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 19:59.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com