Yurich » 04.12.2003 (Чт) 23:38
Считаю, что для *.х не имеет значения какая анимация делалась в максе. Результат преобразования будет покадровым, ДХ не понимает костей. Мне удалось анимировать несколько моделей, но анимация простая - поворот, наклон, изгиб. Костяшной не занимался. Как использовать знаю только для ДХ7. Ниже пример кода класса AnimDoor для анимации двери. *.х конвертить с опциями -Т -А. По просьбе кину пример готового *.х или *.max (версия 4.0)
Dim AnimFrame As Direct3DRMFrame3 ' фрейм анимации
Dim AnimSet As Direct3DRMAnimationSet2
Dim Anim As Direct3DRMAnimation2
Dim AnimArray As Direct3DRMAnimationArray
Public StartTime As Single ' номер первого кадра анимации
Public EndTime As Single ' номер последнего кадра анимации
Public CurrentTime As Single ' номер текущего кадра
Public RunAnimate As Boolean ' анимация включена
Public TimeMultiplier As Single ' множитель, определяет скорость
Public DoorOpening As Boolean ' дверь открыта
Dim AutoClosing As Boolean
Public AutoClosingInterval As Single
Dim CurrentInterval As Single
' переменные для звуковых эффектов
Dim OpeningSound As DirectSoundBuffer ' стартовый звук
Dim ClosingSound As DirectSoundBuffer ' звук окончания
' создать фрейм анимации
' все поверхности должны быть с текстурами, иначе завал!!!
Public Sub CreateDoor(xFileName As String)
Set AnimFrame = D3DRM.CreateFrame(Nothing)
Set AnimSet = D3DRM.CreateAnimationSet
AnimSet.LoadFromFile xFileName, 0, D3DRMLOAD_FROMFILE, Nothing, Nothing, AnimFrame
Set AnimArray = AnimSet.GetAnimations
Set Anim = AnimArray.GetElement(AnimArray.GetSize - 1)
Dim Frame As Direct3DRMFrame3
Dim Children As Direct3DRMFrameArray
Dim ChildFrame As Direct3DRMFrame3
Dim ChildSize As Long
Dim MeshBuild As Direct3DRMMeshBuilder3
Dim ChildFace As Direct3DRMFace2
Dim ChildTexture As Direct3DRMTexture3
Dim S As Long, i As Long, j As Long
Set Frame = Anim.GetFrame
Set Children = AnimFrame.GetChildren
ChildSize = Children.GetSize
For i = 0 To ChildSize - 1
Set ChildFrame = Children.GetElement(i)
Set MeshBuild = ChildFrame.GetVisual(0)
For j = 0 To MeshBuild.GetFaceCount - 1
Set ChildFace = MeshBuild.GetFace(j)
Set ChildTexture = ChildFace.GetTexture ' завал здесь!!!
ChildTexture.SetDecalTransparentColor 0
ChildTexture.SetDecalTransparency D_TRUE
Next j
Next i
End Sub
' добавить фрейм анимации в сцену
Public Sub AddDoorToScene(Parent As Direct3DRMFrame3)
Parent.AddVisual AnimFrame
End Sub
' убрать фрейм анимации из сцены
Public Sub DeleteDoorFromScene(Parent As Direct3DRMFrame3)
Parent.DeleteVisual AnimFrame
End Sub
' изменить положение фрейма с анимацией
Public Sub SetDoorPosition(x As Single, y As Single, z As Single)
AnimFrame.SetPosition Nothing, x, y, z
End Sub
' изменить ориентацию фрейма с анимацией
Public Sub SetDoorOrientation(dX As Single, dY As Single, dZ As Single, uX As Single, uY As Single, uZ As Single)
AnimFrame.SetOrientation Nothing, dX, dY, dZ, uX, uY, uZ
End Sub
' запустить анимацию
Public Sub OpenDoor(Optional AutoClos As Boolean = False)
If RunAnimate Or DoorOpening Then Exit Sub
CurrentTime = StartTime
RunAnimate = True
If AutoClos Then
AutoClosing = True
CurrentInterval = AutoClosingInterval
End If
If OpeningSound Is Nothing Then Exit Sub
AnimSoundPlay OpeningSound, False, True
End Sub
Public Sub CloseDoor()
If AutoClosing And CurrentInterval > 0 Then Exit Sub
If RunAnimate Or Not DoorOpening Then Exit Sub
CurrentTime = EndTime
RunAnimate = True
SetNewTime 0
If ClosingSound Is Nothing Then Exit Sub
AnimSoundPlay ClosingSound, False, True
End Sub
' вывести новый кадр
Public Sub SetNewTime(ByVal dTime As Single)
If Not RunAnimate Then Exit Sub
If dTime < 1 Then dTime = 1
If Not DoorOpening Then
CurrentTime = Fix(CurrentTime + dTime * TimeMultiplier)
If CurrentTime > EndTime Then
CurrentTime = EndTime
If Not AutoClosing Then RunAnimate = False
DoorOpening = True
End If
Else
If AutoClosing Then
CurrentInterval = Fix(CurrentInterval - dTime * TimeMultiplier)
If CurrentInterval <= 0 Then
AutoClosing = False
CurrentTime = EndTime
RunAnimate = True
If ClosingSound Is Nothing Then Exit Sub
AnimSoundPlay ClosingSound, False, True
Else
Exit Sub
End If
End If
CurrentTime = Fix(CurrentTime - dTime * TimeMultiplier)
If CurrentTime < StartTime Then
CurrentTime = StartTime
RunAnimate = False
DoorOpening = False
End If
End If
AnimSet.SetTime CurrentTime
End Sub
' загрузить звуки
Public Sub LoadOpenigSound(WavName As String)
If m_ds Is Nothing Then Exit Sub
' Загружаем в буфер Wav-файл
Set OpeningSound = m_ds.CreateSoundBufferFromFile(SoundPath & WavName, BufferDesc, WaveFormat)
' Установим "свойства" паннинга и громкости
OpeningSound.SetPan 0
OpeningSound.SetVolume SndVolume
End Sub
Public Sub LoadClosingSound(WavName As String)
If m_ds Is Nothing Then Exit Sub
Set ClosingSound = m_ds.CreateSoundBufferFromFile(SoundPath & WavName, BufferDesc, WaveFormat)
ClosingSound.SetPan 0
ClosingSound.SetVolume SndVolume
End Sub
' Код проигрывания музыки
Public Sub AnimSoundPlay(ByRef SoundBuffer As DirectSoundBuffer, Repeat As Integer, Optional Reset As Boolean = False)
If Reset = True Then
SoundBuffer.Stop
SoundBuffer.SetCurrentPosition 0
End If
SoundBuffer.Play Repeat
End Sub
Public Sub AnimSoundStop(ByRef SoundBuffer As DirectSoundBuffer, Optional Reset As Boolean = True)
If SoundBuffer Is Nothing Then Exit Sub ' Если буфер пуст, то выйдем из процедуры
SoundBuffer.Stop
If Reset = True Then
SoundBuffer.SetCurrentPosition 0
End If
End Sub
Последовательность создания:
Dim NumTime As Single ' интервал времени после вывода
' предыдущего кадра (стабилизирует
' анимацию во времени), можно задать
' константой
Dim Door As New AnimDoor
Dim Scene As Direct3DRMFrame3
With Door
.CreateDoor "HomeDoor.x"
.LoadOpenigSound "DoorOpn.wav"
.LoadClosingSound "DoorClos.wav"
.AddDoorToScene Scene
.SetDoorPosition 0, 0, 0
.EndTime = 90 ' номер последнего кадра, начальный
' по умолчанию = 0
.TimeMultiplier = 1.1 ' задает скорость движения
.AutoClosingInterval = 1000 ' интервал перед закрытием
End With
Door.OpenDoor True
' в цикле рендера
Door.SetNewTime NumTime