|
3D-программирование Вопросы, касающиеся программирования 3D мира |
18.07.2018, 01:09
|
#1
|
AnyKey`щик
Регистрация: 06.03.2015
Сообщений: 11
Написано 2 полезных сообщений (для 6 пользователей)
|
3D объект в 2D рамке - Делюсь кодом!
Итак, недавно меня мучил вопрос: "Как сделать простой HUD для простой игры?" - в голове пролетела идея сделать простые уголки вокруг объектов, с которыми можно будет взаимодействовать в игровой вселенной.
Потом я столкнулся с вопросом: "Как узнать координаты левого-верхнего и правого-нижнего угла 3D объекта на 2D скрине?" - все казалось просто - CameraProject. Но эта функция могла указывать лишь на средину меша, в то время, как мне нужны были углы, с учетом формы, размера меша и положения камеры относительно его.
Долго думая у меня зародилась альтернативная идея: запихнуть в объект квад, который постоянно смотрит вперед (в камеру) и сохраняет размеры меша объекта. Тут я решил использовать PointEntity(квад,камера) - но я не учел тот факт, что эта функция влияет на энтити, а не на меш. Поэтому когда я пытался получить координаты вершин квада (которые и должны были стать вершинами рамки), столкнулся с тем, что они не меняются.
Я решил написать собственную функцию-аналог РоintEntity, только чтобы она влияла на меш. Написать - не написал, зато благодаря архиву кода от LLI.T.A.L.K.E.R нашел какую-то набор функций для односюрфейсных частиц, в основе которых простые квады. Там использовался до сих пор не понятный для меня способ применения векторов TFormVector. Мне сложно было понять суть управления этой функцией, так как она часто выдавала непредсказуемый для меня результат. Но в конце концов сверив расположение точек квада и подогнав под них функцию я добился нужного результата.
Хоть порой эта рамка (скобочки) иногда ведет себя не так, как задумывалось, я рад результатом
Сначала сделал с FastImage, но потом переделал под чистый Блиц, чтобы можно было сразу скопировать в новый проект и проверить самому.
Вот код:
;Рамка вокруг объекта на 'чистом' (для удобства) Блитце!
AppTitle "B3D GUI/HUD test"
Graphics3D 800,600,32,2
Global FL_Pitch#,FL_Yaw#,FL_Roll#
Global FL_XSpeed#,FL_YSpeed#,FL_ZSpeed#
Global speed#=0.05
Global gw#=GraphicsWidth()
Global gh#=GraphicsHeight()
Global frame=CreateQuad(); Пока один глобальный квад.
HideEntity frame
;===Рисуем ГУЙ/ХУД/ХЗ===
outline=CreateImage(24,24)
SetBuffer ImageBuffer(outline)
Color 0,0,0
Rect 0,0,22,22,1
Color 255,0,255
Line 1,1,9,1
Line 1,1,1,9
Line 1,22,9,22
Line 1,22,1,14
Line 22,1,14,1
Line 22,1,22,9
Line 22,22,22,14
Line 22,22,14,22
cross=CreateImage(16,16)
SetBuffer ImageBuffer(cross)
Color 0,0,0
Rect 0,0,23,23,1
Color 255,0,0
Line 8,0,8,16
Line 0,8,16,8
;============
SetBuffer BackBuffer()
MaskImage outline,0,0,0
MaskImage cross,0,0,0
cam=CreateCamera()
CameraClsColor cam, 40, 40, 40
PositionEntity cam,0,0,-3
lit=CreateLight()
RotateEntity lit,60,45,0
cube=CreateCube()
EntityPickMode cube,2
fnt=LoadFont("courier new",20)
SetFont fnt
HidePointer
sx#=1
sy#=1
While Not KeyHit(1)
; Простое управление размерами меша, дабы проверить, будет ли это отслеживаться квадом и ХУДом.
If KeyHit(203) Then sx=2 Else sx=1
If KeyHit (205) Then sx=0.5
If KeyHit(200) Then sy=2 Else sy=1
If KeyHit (208) Then sy=0.5
ScaleMesh cube,sx,sy,1
CameraPick(cam,MouseX(),MouseY())
If MouseHit(2) Then MoveMouse gw,gh
If MouseDown(2)
FreeLook (cam)
EndIf
RenderWorld
If MouseDown (2)
DrawImage (cross,(gw/2)+8,(gh/2)+8)
Else
DrawImage (cross,MouseX()+8,MouseY()+8)
EndIf
UpdateFrame(cam,cube,outline)
Color 0,255,0
Text 5,10,"Entity Scale: "+MeshWidth(cube)
Text 5,30,"Use [ARROWS] to scale cube"
Text 5,50,"Hold [2nd MOUSE BUTTON]+[WASD] to rotate camera and fly"
Text 5,gh-20,"Mesh in HUD frame test on 'clean' Blitz3D"
UpdateWorld
FlushMouse
Flip
Wend
ClearWorld
End
;Эту ф-цию переписал и подогнал из примера 'SingleSurface particles'
;Она заставляет квад вести себя как спрайт.
Function SpriteMesh(ent,cam)
Local surf=GetSurface(ent,1)
Local x#=EntityX(ent)
Local y#=EntityY(ent)
Local z#=EntityZ(ent)
TFormPoint x,y,z,0,cam
If TFormedZ#()>0
; Вот, чесно говоря, до сих пор не умею пользоваться векторами. Благо, еще остались примеры.
;topleft
TFormVector -1,-1,0,cam,0
VertexCoords surf,0,x+TFormedX#(),y+TFormedY#(),z+TFormedZ#()
;topright
TFormVector -1,1,0,cam,0
VertexCoords surf,1,x+TFormedX#(),y+TFormedY#(),z+TFormedZ#()
;bottomright
TFormVector 1,-1,0,cam,0
VertexCoords surf,2,x+TFormedX#(),y+TFormedY#(),z+TFormedZ#()
;bottomleft
TFormVector 1,1,0,cam,0
VertexCoords surf,3,x+TFormedX#(),y+TFormedY#(),z+TFormedZ#()
EndIf
End Function
; Эта ф-ция регулирует размеры рамки и отрисовывает наши границы рамки
Function UpdateFrame(cam,ent,img)
Local surf=GetSurface(frame,CountSurfaces(frame))
Local vx1#,vy1#
Local vx2#,vy2#
; Тут благодаря CameraProject вытащил координаты вершин квада
CameraProject cam,VertexX(surf,0),VertexY(surf,0),VertexZ(surf,0)
vx1=ProjectedX():vy1=ProjectedY()
CameraProject cam,VertexX(surf,3),VertexY(surf,3),VertexZ(surf,3)
vx2=ProjectedX():vy2=ProjectedY()
DrawImageRect (img,vx1-12,vy2-12,0,0,12,12)
DrawImageRect (img,vx2,vy1,12,12,12,12)
DrawImageRect (img,vx1-12,vy1,0,12,12,12)
DrawImageRect (img,vx2,vy2-12,12,0,12,12)
PositionEntity frame,EntityX(ent),EntityY(ent),EntityZ(ent)
SpriteMesh (frame,cam); Изначально использовал PointEntity, но это была большая ошибка
If MeshWidth(ent)<>MeshWidth(frame) Then ScaleMesh frame,MeshWidth(ent)/2,MeshHeight(ent)/2,MeshDepth(ent)/2
End Function
; Собсна квад.
Function CreateQuad(x#=0,y#=0,z#=0,scale#=1)
mesh=CreateMesh()
Local surf=CreateSurface(mesh)
AddVertex (surf, -1,0,1,0,0,0)
AddVertex (surf,1,0,1,1,0,1)
AddVertex (surf,-1,0,-1,0,1,1)
AddVertex (surf,1,0,-1,1,1,1)
AddTriangle (surf,0,1,2)
AddTriangle (surf,3,2,1)
UpdateNormals(mesh)
PositionEntity mesh,x#,y#,z#
ScaleEntity mesh, scale#,scale#,scale#
Return mesh
End Function
; Весьма распрастраненная ф-ция свободного перемещения камеры (WASD+МЫШЬ)
Function FreeLook(FL_Cam)
FL_Pitch#=FL_Pitch#+(MouseYSpeed()*0.02)
FL_Pitch#=FL_Pitch#/1.2
FL_Yaw#=FL_Yaw#+-(MouseXSpeed()*0.02)
FL_Yaw#=FL_Yaw#/1.2
MoveMouse (GraphicsWidth()/2,GraphicsHeight()/2)
FL_ZSpeed#=FL_ZSpeed#+Float(KeyDown(17)-KeyDown(31))*speed# ; W & S
FL_ZSpeed#=FL_ZSpeed#/1.14
FL_XSpeed#=FL_XSpeed#+Float(KeyDown(32)-KeyDown(30))*speed# ; A & D
FL_XSpeed#=FL_XSpeed#/1.14
FL_YSpeed#=FL_YSpeed#+Float(KeyDown(19)-KeyDown(33))*speed# ; R & F
FL_YSpeed#=FL_YSpeed#/1.14
FL_Roll#=(FL_Yaw#*speed#)-(FL_XSpeed#*1.7)
MoveEntity FL_Cam,FL_XSpeed#,FL_YSpeed#+Abs(FL_Roll#*FL_XSpeed#)/50,FL_ZSpeed#
Local cp#=EntityPitch(FL_Cam,True)+FL_Pitch#
If cp<-89 Then cp=-89
If cp>89 Then cp=89
RotateEntity FL_Cam,cp,EntityYaw(FL_Cam)+FL_Yaw#,FL_Roll#
End Function
Функции еще можно сто раз переделать под любые нужды и под любые библиотеки для большей производительности и графония.
Это еще не все! Продолжу использовать вместе с FastImage или Xors3D. Хочу добавить плавное появление с увеличением и плавным изменением цвета (чтобы покрасивее было), при наведении курсора на нужный объект, плюс режимы взаимодействия с объектом (игровая механика, основана на физике).
__________________
В этом мире нет ничего невозможного.
|
(Offline)
|
|
Эти 5 пользователя(ей) сказали Спасибо FlameSword за это полезное сообщение:
|
|
13.08.2018, 07:11
|
#2
|
Разработчик
Регистрация: 11.10.2017
Сообщений: 390
Написано 74 полезных сообщений (для 117 пользователей)
|
Ответ: 3D объект в 2D рамке - Делюсь кодом!
Не споря, статья хорошая, автору +++.
Но что мешает использовать спрайты с текстурой уголков и виртуальные точки? Я так делал.
__________________
Человек это или баг, или заложенное специально программное яйцо.
|
(Offline)
|
|
13.08.2018, 21:48
|
#3
|
Быдлокодер
Регистрация: 05.07.2009
Адрес: Проспит
Сообщений: 5,024
Написано 2,312 полезных сообщений (для 5,349 пользователей)
|
Ответ: 3D объект в 2D рамке - Делюсь кодом!
Сообщение от Tiranas
Не споря, статья хорошая, автору +++.
Но что мешает использовать спрайты с текстурой уголков и виртуальные точки? Я так делал.
|
Если именно спрайты, то в Blitz3D лучше не надо, а так надо свой огород городить.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 23:36.
|