Es ermittelt die CameraProjection, und wenn diese -1 ergibt, rechnet er mit Matrizen.
ExamineCameraProjection() muss dabei die Camera, die Koordinaten und die Bildschirmgröße bekommen.
Außerdem kann ein Padding angegeben werden, jenachdem, wie viel Abstand zum Bildschirmrand sein soll.
Sry, für den CodeStil, aber ich hab das eben aus meinem Projekt rausgerissen.
Code: Alles auswählen
;- Vector3D und Matrix3D
Structure Vector3
X.f
Y.f
Z.f
EndStructure
Structure Matrix3
A11.f : A12.f : A13.f
A21.f : A22.f : A23.f
A31.f : A32.f : A33.f
EndStructure
Procedure.i V3_Set(*Use.Vector3, X.f, Y.f, Z.f)
*Use\X = X
*Use\Y = Y
*Use\Z = Z
ProcedureReturn *Use
EndProcedure
Procedure.f V3_Length(*Source.Vector3)
ProcedureReturn Sqr(*Source\X * *Source\X + *Source\Y * *Source\Y + *Source\Z * *Source\Z)
EndProcedure
Procedure.i V3_Multiply(*Use.Vector3, Value.f)
*Use\X * Value
*Use\Y * Value
*Use\Z * Value
ProcedureReturn *Use
EndProcedure
Procedure.i V3_Subtraction(*Use.Vector3, *Source1.Vector3, *Source2.Vector3)
*Use\X = *Source1\X - *Source2\X
*Use\Y = *Source1\Y - *Source2\Y
*Use\Z = *Source1\Z - *Source2\Z
ProcedureReturn *Use
EndProcedure
Procedure.i V3_Normalize(*Use.Vector3)
Protected Length.f = V3_Length(*Use)
If Length
*Use\X / Length
*Use\Y / Length
*Use\Z / Length
EndIf
ProcedureReturn *Use
EndProcedure
Procedure.i V3_SetLength(*Use.Vector3, Length.f)
V3_Normalize(*Use)
V3_Multiply(*Use, Length)
ProcedureReturn *Use
EndProcedure
Procedure.i V3_Rotate(*Use.Vector3, *Source.Matrix3)
Protected Buffer.Vector3
CopyMemory(*Use, @Buffer, SizeOf(Vector3))
*Use\X = Buffer\X**Source\A11 + Buffer\Y**Source\A12 + Buffer\Z**Source\A13
*Use\Y = Buffer\X**Source\A21 + Buffer\Y**Source\A22 + Buffer\Z**Source\A23
*Use\Z = Buffer\X**Source\A31 + Buffer\Y**Source\A32 + Buffer\Z**Source\A33
ProcedureReturn *Use
EndProcedure
Procedure M3_Inverse(*Use.Matrix3, *Source.Matrix3)
Protected Factor.f
With *Source
Factor.f = 1 / (\A11*\A22*\A33-\A13*\A22*\A31+\A12*\A23*\A31+\A13*\A21*\A32-\A11*\A23*\A32-\A12*\A21*\A33)
*Use\A11 = (\A22*\A33-\A23*\A32) * Factor
*Use\A12 = (\A13*\A32-\A12*\A33) * Factor
*Use\A13 = (\A12*\A23-\A13*\A22) * Factor
*Use\A21 = (\A23*\A31-\A21*\A33) * Factor
*Use\A22 = (\A11*\A33-\A13*\A31) * Factor
*Use\A23 = (\A13*\A21-\A11*\A23) * Factor
*Use\A31 = (\A21*\A32-\A22*\A31) * Factor
*Use\A32 = (\A12*\A31-\A11*\A32) * Factor
*Use\A33 = (\A11*\A22-\A12*\A21) * Factor
EndWith
EndProcedure
Procedure M3_Orientation(*Use.Matrix3, X.f, Y.f, Z.f, W.f)
With *Use
\A11 = W*W+X*X-Y*Y-Z*Z
\A12 = 2*X*Y-2*W*Z
\A13 = 2*X*Z+2*W*Y
\A21 = 2*X*Y+2*W*Z
\A22 = W*W-X*X+Y*Y-Z*Z
\A23 = 2*Y*Z-2*W*X
\A31 = 2*X*Z-2*W*Y
\A32 = 2*Y*Z+2*W*X
\A33 = W*W-X*X-Y*Y+Z*Z
EndWith
EndProcedure
;- Camera Projection
Structure CameraProjection
X.f
Y.f
Distance.f
Direction.f
EndStructure
Global CameraProjection.CameraProjection
Procedure ExamineCameraProjection(Camera.i, X.f, Y.f, Z.f, Width.i, Height.i, Padding.f=0.0)
Protected ProjectionX.f = CameraProjectionX(Camera, X, Y, Z)
Protected ProjectionY.f = CameraProjectionY(Camera, X, Y, Z)
Protected Direction.Vector3, CameraDirection.Vector3
Protected Projection.Vector3, Length.f, Inverse.Matrix3, Orientation.Matrix3
V3_Set(Direction, X-CameraX(Camera), Y-CameraY(Camera), Z-CameraZ(Camera))
CameraProjection\Distance = V3_Length(Direction)
If ProjectionX = -1 Or ProjectionY = -1
V3_Normalize(Direction)
V3_Set(CameraDirection, CameraDirectionX(Camera), CameraDirectionY(Camera), CameraDirectionZ(Camera))
V3_Subtraction(Projection, CameraDirection, Direction)
FetchOrientation(CameraID(Camera))
M3_Orientation(Orientation, GetX(), GetY(), GetZ(), GetW())
M3_Inverse(Inverse, Orientation)
V3_Rotate(Projection, Inverse)
Projection\Z = 0
Projection\X = -Projection\X
Length = Sqr(Width*Width/4+Height*Height/4) - Sqr(Padding*Padding*2)
V3_SetLength(Projection, Length)
If Projection\X < -(Width/2-Padding)
CameraProjection\X = Padding
CameraProjection\Y = Projection\Y * Abs((Width/2-Padding)/Projection\X) + Height/2
ElseIf Projection\X > Width/2-Padding
CameraProjection\X = Width-Padding
CameraProjection\Y = Projection\Y * Abs((Width/2-Padding)/Projection\X) + Height/2
ElseIf Projection\Y < -(Height/2-Padding)
CameraProjection\X = Projection\X * Abs((Height/2-Padding)/Projection\Y) + Width/2
CameraProjection\Y = Padding
ElseIf Projection\Y > Height/2-Padding
CameraProjection\X = Projection\X * Abs((Height/2-Padding)/Projection\Y) + Width/2
CameraProjection\Y = Height-Padding
Else
CameraProjection\X = Projection\X + Width/2
CameraProjection\Y = Projection\Y + Height/2
EndIf
Else
CameraProjection\X = ProjectionX
CameraProjection\Y = ProjectionY
EndIf
EndProcedure
;- Demo
InitEngine3D()
InitSprite()
UsePNGImageDecoder()
InitMouse()
Enumeration
#Window
#Camera
#Sprite
#Light
#Entity
EndEnumeration
OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)
CatchSprite(#Sprite, ?cross, #PB_Sprite_AlphaBlending)
CreateCamera(#Camera, 0, 0, 100, 100)
MoveCamera(#Camera, 0, 0, 4)
CameraLookAt(#Camera, 0, 0, 0)
CreateLight(#Light, $FFFFFF, 5, 0, 5)
CreateEntity(#Entity, MeshID(CreateCube(#PB_Any, 1)), #PB_Material_None, 1, 0, 0)
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
End
Case #PB_Event_None
Break
EndSelect
ForEver
RenderWorld()
ExamineMouse()
RotateCamera(#Camera, -MouseDeltaY()/10, -MouseDeltaX()/10, 0, #PB_Relative)
ExamineCameraProjection(#Camera, EntityX(#Entity), EntityY(#Entity), EntityZ(#Entity), 800, 600, 20)
DisplayTransparentSprite(#Sprite, CameraProjection\X-16, CameraProjection\Y-16)
FlipBuffers()
ForEver
DataSection
cross:
Data.q $0A1A0A0D474E5089,$524448490D000000,$2000000020000000,$7A7A730000000608,$58457419000000F4
Data.q $72617774666F5374,$2065626F64410065,$6165526567616D49,$00003C65C9717964,$DA7854414449BB03
Data.q $3E145114486B57AC,$607CAFADADBAAE3B,$2432528F96AE618A,$C922C2148928CD4B,$A20A230485032908
Data.q $814487E920CBF91F,$05945191FC0F4245,$928888A4A9A26519,$956CB528B335DDCF,$EE3BDDAEE1F75D5D
Data.q $70BD59DDEF663EC8,$7DDF7DF39CCEE776,$674F9BF80067B9CC,$379E0D7C360AEA4E,$6B0B674D20D8708F
Data.q $EB506ACE11E110EB,$6BE1AC09B99F95FB,$1B1DD9A9C708440F,$E20B59BE3FE61D86,$8E0847C22013DF0C
Data.q $866784C72754FF08,$3B8584AB5F274C04,$E0C1572F9BA8BC95,$5D45F7EB6CC82AED,$05C4470420DC8123
Data.q $C49BDABA0EB95D25,$B54D50C06FCB49A1,$87EFA830E11E112B,$88BC62204C98AE6F,$055C562416E0F4B6
Data.q $867E392C1CB0E44C,$F0FCDACB9838687D,$89DD00478B21040C,$91751EFEA1812F17,$6E5DFEF8602B8B7D
Data.q $5D43EEC41E415826,$08316430923AC885,$1FCF4C1CB4A13DA8,$5D48C1974FBC8152,$A3679106342D7B2D
Data.q $6D0A6E223FB204EE,$A7C6E60A5F3CEC45,$FBFBFEC2D18D4054,$FA307382AF5F5430,$2BC084DB9C8ECEA4
Data.q $23601AEF2C04B8A2,$9D8FF5A3045F931A,$9C762257435ED7C8,$DCF63EB57E680629,$4F9C979EACF63093
Data.q $373E6022C288B380,$2F630798396DC479,$2224E012BB925C1A,$44127D771029C4FE,$125FAF1404719CBE
Data.q $002F1C459C0249C9,$B37B4DC8B776DEEF,$989B8E4A91B6F141,$B31C26AE06B46380,$6D6BE4356E224D99
Data.q $70CB5819B4E448BF,$D04FA464818F4771,$7BC3F280F613E812,$7F1E4C025E41D9DA,$426D1E43E3241738
Data.q $22899A5A28126C7D,$0FE9021CE791C444,$281C745D42DEBAE5,$05D5F1108A5D5ADB,$F02CACB899B2C1E9
Data.q $B118B44490DC9A9B,$04EC22BC1D1D940D,$FEC83F633C817570,$1FFB2D1AD581514D,$8044B76AFAA32FEC
Data.q $3C89C608938BEBAA,$678ED066E7FC1D3D,$59E9C9850C0DA688,$6C62631FCD35F0D6,$06969E476C5CA3C7
Data.q $6EBF20E4E8F38B81,$42E07A7AA81912F3,$13B1696162A158EF,$1871896BD58D89A0,$244553837F21FB1B
Data.q $953A9EB320854D4F,$ACA00606A82F8C73,$5AE18DD1AC3F914F,$1494F2564E245906,$50125E18E818B208
Data.q $222AE621CBB3F7F5,$B222DA8D13532F30,$8C02AC66B7441F25,$2577CBB591A1EB38,$6BCB544942B33043
Data.q $FAA2757007BB1115,$E21AE5D9936A083A,$319360DC81C7D867,$1115AC717708B027,$910838F8F2445538
Data.q $52A0756ACF04ED49,$1C241D9E5DC8F928,$C1A10EDD8F24456A,$8D5079EABF83EC81,$078E38BB8391A37F
Data.q $D03BC0F4F8E8B714,$6F80416374FBE8F4,$147A4B7404936489,$5AB74E1DB92EE134,$71C5B59CC24072D3
Data.q $C596428823C474E7,$3F50F34BFA26547D,$0C70CD3E42B4171A,$22BAFC7289C0758E,$18DDBFE7D6914455
Data.q $56D91C2C8E056F39,$C7E445484679A39B,$104CC6EA71D272A5,$53B45600300BFE71,$000000AF4D4CDE60
Data.q $6042AE444E454900,$0000000000000082
EndDataSection