-
June 10th, 2020, 03:41 PM
#1
how avoiding hidded drawed parts?
i'm learning how create a 3D world just using Math.
until here i can draw lines and a plane.
now i'm moving the player(nothing, just moving) and the plane is moved. when i get far the plane is drawed incorrectly.
for resolve the problem i must draw just what is showed on camera.
see the camera size:
Code:
Private Sub Form_Load() ScaleMode = vbPixels
AutoRedraw = True
FillPosition3D Player1.Position, Me.ScaleWidth / 2, Me.ScaleHeight / 2, -1000 'Camera Position
camera1.Position.X = 0
camera1.Position.Y = 0
camera1.Position.Z = 0
camera1.Size.Height = Me.ScaleHeight
camera1.Size.Width = Me.ScaleWidth
camera1.Size.ZDepth = 20000
camera1.Size.Distance = 100
ScrollChanged
End Sub
Private Sub Form_Resize()
camera1.Size.Height = Me.ScaleHeight
camera1.Size.Width = Me.ScaleWidth
camera1.Position.X = 0
camera1.Position.Y = 0
camera1.Position.Z = 0
ScrollChanged
End Sub
now heres how i draw the pane:
Code:
Sub ScrollChanged() Me.Cls
'Angletest.X = HScroll1.Value
'Angletest.Y = VScroll1.Value
'Angletest.Z = HScroll2.Value
Label1.Caption = Angletest.X & ", " & Angletest.Y & ", " & Angletest.Z
Label1.Caption = Label1.Caption & vbNewLine & Player1.Position.X & ", " & Player1.Position.Y & ", " & Player1.Position.Z
Dim RecPosition As Position3D
FillPosition3D RecPosition, Player1.Position.X, Player1.Position.Y, Player1.Position.Z + 2000
Dim RecSize As Size3D
FillSize3D RecSize, 6000, 0, 8000
DrawPlane RecPosition, RecSize, Angletest, camera1.Size
Me.Refresh
End Sub
Private Sub DrawPlane(Position As Position3D, Size As Size3D, Rotation As Angle3D, WorldSize As Size3D)
Dim Points(4) As POINTAPI
Dim NewPoint As POINTAPI
Dim NewPosition3D As Position3D
Dim RotatedPosition As Position3D
Dim DestinyPosition As Position3D
Static FixedPoint0(4) As Position3D
Dim sizeD As Size3D
Dim temp As Double
FillSize3D sizeD, 0, 0, 0
'FillPosition3D RotatedPosition, Position.X + Size.Width / 2, Position.Y + Size.Height / 2, Position.Z + Size.ZDepth / 2
With Player1.Position
FillPosition3D RotatedPosition, .X, .Y, .Z 'Camera Position
End With
If (IsCollision3D(camera1.Position, camera1.Size, Position, Size) = False) Then Exit Sub
'Floor:
'Vector1
FillPosition3D NewPosition3D, Position.X, Position.Y, Position.Z
NewPosition3D = Rotate(NewPosition3D, Rotation, RotatedPosition)
If (IsOnCamera(NewPosition3D, sizeD, camera1.Position, camera1.Size) = True) Then
FixedPoint0(0) = NewPosition3D
Else
NewPosition3D = FixedPoint0(0)
End If
NewPoint = ConvertPositon3DTo2D(NewPosition3D, camera1.Size)
Points(0) = NewPoint
'Vector2
FillPosition3D NewPosition3D, Position.X, Position.Y, Position.Z + Size.ZDepth
NewPosition3D = Rotate(NewPosition3D, Rotation, RotatedPosition)
If (IsOnCamera(NewPosition3D, sizeD, camera1.Position, camera1.Size) = True) Then
FixedPoint0(1) = NewPosition3D
Else
NewPosition3D = FixedPoint0(1)
End If
NewPoint = ConvertPositon3DTo2D(NewPosition3D, camera1.Size)
Points(1) = NewPoint
'Vector3
FillPosition3D NewPosition3D, Position.X + Size.Width, Position.Y, Position.Z + Size.ZDepth
NewPosition3D = Rotate(NewPosition3D, Rotation, RotatedPosition)
If (IsOnCamera(NewPosition3D, sizeD, camera1.Position, camera1.Size) = True) Then
FixedPoint0(2) = NewPosition3D
Else
NewPosition3D = FixedPoint0(2)
End If
NewPoint = ConvertPositon3DTo2D(NewPosition3D, camera1.Size)
Points(2) = NewPoint
'Vector4
FillPosition3D NewPosition3D, Position.X + Size.Width, Position.Y + Size.Height, Position.Z
NewPosition3D = Rotate(NewPosition3D, Rotation, RotatedPosition)
If (IsOnCamera(NewPosition3D, sizeD, camera1.Position, camera1.Size) = True) Then
FixedPoint0(3) = NewPosition3D
Else
NewPosition3D = FixedPoint0(3)
End If
NewPoint = ConvertPositon3DTo2D(NewPosition3D, camera1.Size)
Points(3) = NewPoint
FillStyle = vbFSSolid
FillColor = vbRed
Polygon Me.hdc, Points(0), 4
End Sub
Private Function IsOnCamera(VerticePosition As Position3D, VerticeSize As Size3D, CameraPosition As Position3D, CameraSize As Size3D) As Boolean
If ((VerticePosition.Z) >= CameraPosition.Z And VerticePosition.Z <= (CameraPosition.Z + CameraSize.ZDepth) _
And ((VerticePosition.Y) >= CameraPosition.Y And VerticePosition.Y <= (CameraPosition.Y + CameraSize.Height))) Then
'And ((VerticePosition.X) >= CameraPosition.X And VerticePosition.X <= (CameraPosition.X + CameraSize.Width))) Then
Me.Caption = CStr(CameraPosition.X)
IsOnCamera = True
Else
IsOnCamera = False
End If
End Function
Private Function ConvertPositon3DTo2D(Position As Position3D, World3DSize As Size3D) As POINTAPI
Dim ConvertedPosition As POINTAPI
Dim PosZZDepth As Long
PosZZDepth = Position.Z + World3DSize.Distance
If (PosZZDepth = 0) Then PosZZDepth = 1 'avoiding division by zero
Dim Width As Double
Dim Height As Double
Width = World3DSize.Width / 2
If (Width = 0) Then Width = 0
Height = World3DSize.Height / 2
If (Height = 0) Then Height = 0
ConvertedPosition.X = (Position.X * World3DSize.Distance / PosZZDepth) + Width
ConvertedPosition.Y = (Position.Y * World3DSize.Distance / PosZZDepth) + Height
ConvertPositon3DTo2D = ConvertedPosition
End Function
Code:
Private Function Rotate(Position As Position3D, Rotation As Angle3D, PositionRotated As Position3D) As Position3D Dim ConvertedPosition As Position3D
Dim RotationInRads As Angle3D
'Convert degrees to Radians
'Rotation works on Radians
RotationInRads = ConvertDegreesToRadians(Rotation)
'Convert the actual position to zero, using the rotation position:
ConvertedPosition = Position
ConvertedPosition.X = Position.X - PositionRotated.X
ConvertedPosition.Y = -(PositionRotated.Y - Position.Y) 'reversed because Y increments down
ConvertedPosition.Z = Position.Z - PositionRotated.Z
'Rotate the position, but the Z axis must be the 1st:
Dim T As Position3D
'Z axis (Roll)
T = ConvertedPosition
ConvertedPosition.X = T.X * Cos(RotationInRads.Z) - T.Y * Sin(RotationInRads.Z)
ConvertedPosition.Y = T.X * Sin(RotationInRads.Z) + T.Y * Cos(RotationInRads.Z)
'X axis (Pitch)
T = ConvertedPosition
ConvertedPosition.Y = T.Y * Cos(RotationInRads.X) - T.Z * Sin(RotationInRads.X)
ConvertedPosition.Z = T.Y * Sin(RotationInRads.X) + T.Z * Cos(RotationInRads.X)
'Y axis (Yaw)
T = ConvertedPosition
ConvertedPosition.X = T.Z * Sin(RotationInRads.Y) + T.X * Cos(RotationInRads.Y)
ConvertedPosition.Z = T.Z * Cos(RotationInRads.Y) - T.X * Sin(RotationInRads.Y)
'Convert to the rotated original position:
ConvertedPosition.X = ConvertedPosition.X + PositionRotated.X
ConvertedPosition.Y = ConvertedPosition.Y + PositionRotated.Y
ConvertedPosition.Z = ConvertedPosition.Z + PositionRotated.Z
'Convert to Camera Coordinates\Position:
'ConvertedPosition.X = ConvertedPosition.X - Player1.Position.X
'ConvertedPosition.Y = ConvertedPosition.Y - Player1.Position.Y
'ConvertedPosition.Z = ConvertedPosition.Z - Player1.Position.Z
Rotate = ConvertedPosition
End Function
by some reason i can't control the camera.position.x
that's why it's commented.
the IsOnCamera() test if the line(of plane) is inside the camera view. if isn't then the last vector\point is saved and used on next drawed.
honestly i don't understand why i can't compare the 'X'(the plane isn't drawed, but it's inside the camera view).
can anyone explain to me what i'm doing wrong?
doing these test for all planes, cube(6 planes), for walls and more, isn't too much for the CPU?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|