|
FAQ Туториалы и часто задаваемые вопросы |
11.04.2012, 12:38
|
#1
|
Разработчик
Регистрация: 04.04.2012
Сообщений: 468
Написано 37 полезных сообщений (для 60 пользователей)
|
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, 13:18
|
#2
|
Нуждающийся
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 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)
|
|
Сообщение было полезно следующим пользователям:
|
|
11.04.2012, 16:21
|
#3
|
Разработчик
Регистрация: 04.04.2012
Сообщений: 468
Написано 37 полезных сообщений (для 60 пользователей)
|
Ответ: getMathElement()
Спасибо большое!
Я тоже изучал матрицы, но дело тов том, что в справках не расписывают в каком элементе матрицы что лежит, даже на blitz etc
Подскажите пожалуйста еще в каких ячейках находятся поворот и смещения, для полной информации
__________________
|
(Offline)
|
|
11.04.2012, 17:36
|
#4
|
Нуждающийся
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 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 пользователя(ей) сказали Спасибо Платон Александрович за это полезное сообщение:
|
|
31.05.2012, 22:37
|
#5
|
|
Ответ: getMathElement()
так я не понял... а какого фига они глобальны ? Ведь система обьектов предпологает, что вся инфа о трансформациях должна хранится в относительных координатах ( относительно родительских ). Тогда в чем вообще их смысл ?
Я же считал, что извлечение глобыльных параметров происходит за счет перебора всех родителей.
|
|
|
01.06.2012, 08:37
|
#6
|
Нуждающийся
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений (для 83 пользователей)
|
Ответ: getMathElement()
Сообщение от Diablo1909
так я не понял... а какого фига они глобальны ? Ведь система обьектов предпологает, что вся инфа о трансформациях должна хранится в относительных координатах ( относительно родительских ). Тогда в чем вообще их смысл ?
Я же считал, что извлечение глобыльных параметров происходит за счет перебора всех родителей.
|
Не совсем так. Когда меняется координаты\угол ентити, происходит отложенный перерасчет матриц его самого и его чайлдов. Т.е. там флажок который указывает что трансформации надо перерасчитать. Это делается либо по необходимости (например тем же самым вызовом GetMatElement) до рендера, либо непосредственно перед ним, чтобы получить глобальную матрицу для каждого ентити. Эта матрица и передается в Direct3D для трансформации вершин. GetMatElement возвращает элементы этой матрицы.
Подробнее можно посмотреть в исходниках miniB3D, там в файле geom.h почти вся 3д математика. А устройство иерархии (впрочем и geom.h там же) в исходниках sdk.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
01.06.2012, 12:03
|
#7
|
|
Ответ: 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
|
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 07:30.
|