Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
Работать с прямыми и маркерами, оказалось куда легче и прозрачней

Include "xors3d.bb"
Global pivot,camera,mxs#,mys#,Light,ball
Global lefttop,leftdown,righttop,rightdown
Dim ScreenData#(4,3)
xGraphics3D(1024,600, 32,0, 0)
pivot=xCreatePivot()
camera = xCreateCamera(pivot)
light = xCreateLight()
For i=0 To 50
gg=xCreateCube()
xPositionEntity gg,Rnd(0,50),0,Rnd(0,50)
Next
SetMarkers(150,34,19)
bh0=xCreateCube()
xScaleEntity bh0,0.5,0.5,0.5
xEntityColor bh0,255,255,0
bh1=xCopyEntity(bh0)
bh2=xCopyEntity(bh0)
bh3=xCopyEntity(bh0)
While(Not (xKeyHit(KEY_ESCAPE) Or xWinMessage("WM_CLOSE")))
xPositionEntity bh0,ScreenData#(0,0),ScreenData#(0,1),ScreenData#(0,2)
xPositionEntity bh1,ScreenData#(1,0),ScreenData#(1,1),ScreenData#(1,2)
xPositionEntity bh2,ScreenData#(2,0),ScreenData#(2,1),ScreenData#(2,2)
xPositionEntity bh3,ScreenData#(3,0),ScreenData#(3,1),ScreenData#(3,2)
xUpdateWorld
xRenderWorld()
DrawLine()
Control(1.1,1)
xFlip()
Wend
End
Function DrawLine()
;входные значения
;камера это точка с индексом 1
x000#=xEntityX(camera,1)
y000#=xEntityY(camera,1)
z000#=xEntityZ(camera,1)
;нижний левый
x00#=xEntityX(leftdown,1)
y00#=xEntityY(leftdown,1)
z00#=xEntityZ(leftdown,1)
;верхний левый
x01#=xEntityX(lefttop,1)
y01#=xEntityY(lefttop,1)
z01#=xEntityZ(lefttop,1)
;верхний правый
x11#=xEntityX(righttop,1)
y11#=xEntityY(righttop,1)
z11#=xEntityZ(righttop,1)
;нижний правый
x10#=xEntityX(rightdown,1)
y10#=xEntityY(rightdown,1)
z10#=xEntityZ(rightdown,1)
; теперь построю четыре прямых по уравнению (x-x1)/(x2-x1)=(y-y1)/(y2-y1)=(z-z1)/(z2-z1)
; точка левого нижнего угла. Так как проецирую на xz то у=0
Mdly#=-y000/(y00-y000)
Mdlx#=mdly*(x00-x000)+x000
Mdlz#=mdly*(z00-z000)+z000
; точка левого верхнего угла. Так как проецирую на xz то у=0
Mtly#=-y000/(y01-y000)
Mtlx#=mtly*(x01-x000)+x000
Mtlz#=mtly*(z01-z000)+z000
; точка правого верхнего угла. Так как проецирую на xz то у=0
MtRy#=-y000/(y11-y000)
MtRx#=mtRy*(x11-x000)+x000
MtRz#=mtRy*(z11-z000)+z000
; точка правого нижнего угла. Так как проецирую на xz то у=0
MDRy#=-y000/(y10-y000)
MDRx#=mDRy*(x10-x000)+x000
MDRz#=mDRy*(z10-z000)+z000
;левый нижний
ScreenData#(0,0)=Mdlx#
ScreenData#(0,1)=0
ScreenData#(0,2)=Mdlz#
;левый верхний
ScreenData#(1,0)=Mtlx#
ScreenData#(1,1)=0
ScreenData#(1,2)=Mtlz#
;праввый верхний
ScreenData#(2,0)=MtRx#
ScreenData#(2,1)=0
ScreenData#(2,2)=MtRz#
;правый нижний
ScreenData#(3,0)=MDRx#
ScreenData#(3,1)=0
ScreenData#(3,2)=MDRz#
;теперь проверка на расстояние, что бы спроецированные точки не были дальше от камеры, чем маркеры
;в данных камеры это выполняется легко
;проверка левого нижнего угла
xTFormPoint ScreenData#(0,0),ScreenData#(0,1),ScreenData#(0,2),0,camera
If xTFormedZ()>xEntityZ(leftdown) Then
ScreenData#(0,0)=xEntityX(leftdown,1)
ScreenData#(0,2)=xEntityZ(leftdown,1)
EndIf
;проверка левого верхнего угла
xTFormPoint ScreenData#(1,0),ScreenData#(1,1),ScreenData#(1,2),0,camera
If xTFormedZ()>xEntityZ(lefttop) Then
ScreenData#(1,0)=xEntityX(lefttop,1)
ScreenData#(1,2)=xEntityZ(lefttop,1)
EndIf
;проверка правого верхнего угла
xTFormPoint ScreenData#(2,0),ScreenData#(2,1),ScreenData#(2,2),0,camera
If xTFormedZ()>xEntityZ(righttop) Then
ScreenData#(2,0)=xEntityX(righttop,1)
ScreenData#(2,2)=xEntityZ(righttop,1)
EndIf
;проверка левого верхнего угла
xTFormPoint ScreenData#(3,0),ScreenData#(3,1),ScreenData#(3,2),0,camera
If xTFormedZ()>xEntityZ(rightdown) Then
ScreenData#(3,0)=xEntityX(rightdown,1)
ScreenData#(3,2)=xEntityZ(rightdown,1)
EndIf
; теперь проверка ставящая точку в правильное место если она оказалась за позади камеры
;проверка левого нижнего угла
xTFormPoint ScreenData#(0,0),ScreenData#(0,1),ScreenData#(0,2),0,camera
If xTFormedZ()<0 Then
ScreenData#(0,0)=xEntityX(leftdown,1)
ScreenData#(0,2)=xEntityZ(leftdown,1)
EndIf
;проверка левого верхнего угла
xTFormPoint ScreenData#(1,0),ScreenData#(1,1),ScreenData#(1,2),0,camera
If xTFormedZ()<0 Then
ScreenData#(1,0)=xEntityX(lefttop,1)
ScreenData#(1,2)=xEntityZ(lefttop,1)
EndIf
;проверка правого верхнего угла
xTFormPoint ScreenData#(2,0),ScreenData#(2,1),ScreenData#(2,2),0,camera
If xTFormedZ()<0 Then
ScreenData#(2,0)=xEntityX(righttop,1)
ScreenData#(2,2)=xEntityZ(righttop,1)
EndIf
;проверка левого верхнего угла
xTFormPoint ScreenData#(3,0),ScreenData#(3,1),ScreenData#(3,2),0,camera
If xTFormedZ()<0 Then
ScreenData#(3,0)=xEntityX(rightdown,1)
ScreenData#(3,2)=xEntityZ(rightdown,1)
EndIf
End Function
Function SetMarkers(distance#,yaw#,pitch#)
;yaw#=34 ;36
;pitch#=19 ;19.5
lefttop=xCreateCube(camera)
xEntityColor lefttop,255,0,0
leftdown=xCopyEntity(lefttop,camera)
righttop=xCopyEntity(lefttop,camera)
rightdown=xCopyEntity(lefttop,camera)
xr#=-Sin(yaw)*distance
yr#=Cos(yaw)*distance
zbh#=Sin(pitch)*distance
zbd#=Sin(-pitch)*distance
xPositionEntity lefttop,xr,zbh,yr
xPositionEntity leftdown,xr,zbd,yr
xPositionEntity righttop,-xr,zbh,yr
xPositionEntity rightdown,-xr,zbd,yr
End Function
Function control(speed#,mousesensitivity#)
If xKeyDown(key_1) Then xWireframe(True) Else xWireframe(False)
xText(10, 10, "FPS: " + xGetFPS())
xText(10,30,"Trisinview: "+xTrisRendered ())
mxs#=mxs#+(xMouseXSpeed()/5.0)
mys#=mys#+(xMouseYSpeed()/5.0)
xRotateEntity (camera,mousesensitivity#*mys#,-mousesensitivity#*mxs#,0)
xMoveMouse xGraphicsWidth()/2,xGraphicsHeight()/2
If xKeyDown(17) Or xKeyDown(200) xMoveEntity camera,0,0,speed#
If xKeyDown(31) Or xKeyDown(208) xMoveEntity camera,0,0,-speed#
If xKeyDown(30) Or xKeyDown(203) xMoveEntity camera,-speed#,0,0
If xKeyDown(32) Or xKeyDown(205) xMoveEntity camera,speed#,0,0
xPositionEntity pivot,xEntityX#(camera,1),xEntityY#(camera,1),xEntityZ#(camera,1)
xPositionEntity camera,0,0,0
End Function
|