; ; ------------------------------------------------------------ ; ; PureBasic - CameraTrack ; ; (c) Fantaisie Software ; ; ------------------------------------------------------------ ; ; Код адаптирован из этого урока ; http://www.ogre3d.org/tikiwiki/3rd+person+camera+system+tutorial IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb" #PlayerSpeed = 2 Enumeration #MainWindow #StMode #StFPS #Editor EndEnumeration Enumeration #ThirdPersonChase #ThirdPersonFixed #FirstPerson EndEnumeration Structure Vector3 x.f y.f z.f EndStructure Structure s_Key Up.i Down.i Left.i Right.i EndStructure Structure s_Entity Entity.i elapsedTime.f Key.s_Key SightNode.i CameraNode.i DirectionNode.i Offset.Vector3 ; если необходимо для FirstPerson EndStructure Structure s_Camera Camera.i Mode.i Tightness.f CameraNode.i TargetNode.i EndStructure Macro GetNodePosition(Position, Node) Position\x = NodeX(Node) Position\y = NodeY(Node) Position\z = NodeZ(Node) EndMacro Macro GetEntityPosition(Position, Node) Position\x = EntityX(Node) Position\y = EntityY(Node) Position\z = EntityZ(Node) EndMacro Macro SetVector3(V, xx, yy, zz) V\x = xx V\y = yy V\z = zz EndMacro Macro AddVector3(V, V1, V2) V\x = V1\x + V2\x V\y = V1\y + V2\y V\z = V1\z + V2\z EndMacro Macro SubVector3(V, V1, V2) V\x = V1\x - V2\x V\y = V1\y - V2\y V\z = V1\z - V2\z EndMacro ; Объявления Declare HandleEntity(*Entity.s_Entity) Declare CameraMode(*Camera.s_Camera, *Entity.s_Entity) Declare CameraTrack(*Camera.s_Camera, *Entity.s_Entity) Declare CameraInstantUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3) Declare CameraUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3) Define.f RatioX, RatioY Define Robot.s_Entity Define Camera.s_Camera If InitEngine3D() InitSprite() InitKeyboard() InitMouse() If Screen3DRequester() Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures" , #PB_3DArchive_FileSystem) Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models" , #PB_3DArchive_FileSystem) Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI" , #PB_3DArchive_FileSystem) Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip) WorldShadows(#PB_Shadow_Modulative) ; Изменить режим фильтрации текстур для всех материалов MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8) CreateTexture(1, 256, 256) StartDrawing(TextureOutput(1)) Box(0, 0, 256, 256, RGB(0, 34, 85)) DrawingMode(#PB_2DDrawing_Outlined) Box(0, 0, 256, 256, RGB(255, 255, 255)) Box(10, 10, 236, 236, RGB(0, 255, 255)) StopDrawing() CreateMaterial(0, LoadTexture(0, "r2skin.jpg")) CreateMaterial(1, TextureID(1)) ; робот LoadMesh (0, "robot.mesh") CreateEntity (0, MeshID(0), MaterialID(0)); StartEntityAnimation(0, "Walk") ; Земля CreatePlane(1, 5000, 5000, 100, 100, 100,100) CreateEntity(1, MeshID(1), MaterialID(1)) With Robot \Entity = 0 \Key\Down = #PB_Key_Down \Key\Left = #PB_Key_Left \Key\Right = #PB_Key_Right \Key\Up = #PB_Key_Up \Offset\x = 0 \Offset\y = 50 ; Offset could be needed for FirstPerson \Offset\z = 0 ; Сущность (Entity) use 3 nodes \SightNode=CreateNode(#PB_Any, 120, 20, 0) ; For cameraLookAt \CameraNode=CreateNode(#PB_Any, -140, 100, 0) ; Камера position \DirectionNode=CreateNode(#PB_Any, 1, 0, 0) ; Direction normalized AttachEntityObject(\Entity, "", NodeID(\SightNode)) AttachEntityObject(\Entity, "", NodeID(\CameraNode)) AttachEntityObject(\Entity, "", NodeID(\DirectionNode)) EndWith ; - Камера CreateCamera(0, 0, 0, 100, 100) With Camera \Camera = 0 \Mode = #ThirdPersonChase \Tightness = 0.01 ; Камера use 2 nodes \CameraNode = CreateNode(#PB_Any, -3000, 700, 0) ; Камера position \TargetNode = CreateNode(#PB_Any) ; For cameraLookAt AttachNodeObject(\CameraNode, CameraID(\Camera)) EndWith ; - Свет CreateLight(0,RGB(125,125,125),700,500,0) AmbientColor(RGB(85,85,85)) SkyBox("desert07.jpg") ;-GUI RatioX = CameraViewWidth(0) / 800 RatioY = CameraViewHeight(0) / 600 OpenWindow3D(#MainWindow, 0, 0, 280 * RatioX, 170 * RatioY, "Camera Track") StringGadget3D(#StFPS , 10 * RatioX, 10 * RatioY, 240 * RatioX, 30 * RatioY, "FPS") StringGadget3D(#StMode, 10 * RatioX, 45 * RatioY, 240 * RatioX, 30 * RatioY, "ThirdPersonChase") EditorGadget3D(#Editor, 10 * RatioX, 85 * RatioY, 240 * RatioX, 30 * RatioY, #PB_Editor3D_ReadOnly) SetGadgetText3D(#Editor, "Use F2, F3 or F4 to change Mode") ShowGUI(128, 1) ; Отображение GUI, полу-прозрачность и и отображение курсора мыши Repeat Screen3DEvents() If Engine3DStatus(#PB_Engine3D_CurrentFPS) Robot\elapsedTime = 40/Engine3DStatus(#PB_Engine3D_CurrentFPS) EndIf If ExamineMouse() InputEvent3D(MouseX(), MouseY(), MouseButton(#PB_MouseButton_Left), "", 0) EndIf If ExamineKeyboard() CameraMode(@Camera, @robot) HandleEntity(@Robot) EndIf Repeat Event3D = WindowEvent3D() Until Event3D = 0 CameraTrack(@Camera, @Robot) SetGadgetText3D(#StFPS, "FPS = " + Str(Engine3DStatus(#PB_Engine3D_CurrentFPS))) RenderWorld() FlipBuffers() Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1 EndIf Else MessageRequester("Ошибка", "3D Движок не может быть инициализирован",0) EndIf End Procedure HandleEntity(*Entity.s_Entity) Protected Direction.Vector3, PosMain.Vector3, PosDir.Vector3 Protected Speed.f, Speed2.f With *Entity GetEntityPosition(PosMain, \Entity) GetNodePosition(PosDir, \DirectionNode) SubVector3(Direction, PosDir, PosMain) Speed = #PlayerSpeed * \elapsedTime Speed2 = -Speed / 2 If KeyboardPushed(\Key\Up) MoveEntity(\Entity, Direction\x * Speed, Direction\y * Speed, Direction\z * Speed) ElseIf KeyboardPushed(\Key\Down) MoveEntity(\Entity, Direction\x * Speed2, Direction\y * Speed2, Direction\z * Speed2) EndIf If KeyboardPushed(\Key\Left) RotateEntity(\Entity, 0,#PlayerSpeed/2 * \elapsedTime, 0, #PB_Relative) ElseIf KeyboardPushed(\Key\Right) RotateEntity(\Entity, 0, -#PlayerSpeed/2 * \elapsedTime, 0, #PB_Relative) EndIf EndWith EndProcedure Procedure CameraMode(*Camera.s_Camera, *Entity.s_Entity) Protected CameraPosition.Vector3, TargetPosition.Vector3, Temp.Vector3 If KeyboardReleased(#PB_Key_F2) *Camera\Mode = #ThirdPersonChase HideEntity(*Entity\Entity, #False) GetNodePosition(CameraPosition, *Entity\CameraNode) GetNodePosition(TargetPosition, *Entity\SightNode) CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition) *Camera\Tightness = 0.01 SetGadgetText3D(#StMode, "ThirdPersonChase") ElseIf KeyboardReleased(#PB_Key_F3) *Camera\Mode = #ThirdPersonFixed HideEntity(*Entity\Entity, #False) SetVector3(CameraPosition, 0, 200, 0) GetNodePosition(TargetPosition, *Entity\SightNode) CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition) *Camera\Tightness = 0.01 SetGadgetText3D(#StMode, "ThirdPersonFixed") ElseIf KeyboardReleased(#PB_Key_F4) *Camera\Mode = #FirstPerson HideEntity(*Entity\Entity, #True) GetEntityPosition(Temp, *Entity\Entity) AddVector3(CameraPosition, Temp, *Entity\Offset) GetNodePosition(TargetPosition, *Entity\SightNode) CameraInstantUpdate(*Camera, @CameraPosition, @TargetPosition) *Camera\Tightness = 1 SetGadgetText3D(#StMode, "FirstPerson") EndIf EndProcedure Procedure CameraTrack(*Camera.s_Camera, *Entity.s_Entity) Protected CameraPosition.Vector3, TargetPosition.Vector3, Temp.Vector3 Select *Camera\Mode Case #ThirdPersonChase GetNodePosition(CameraPosition, *Entity\CameraNode) GetNodePosition(TargetPosition, *Entity\SightNode) CameraUpDate(*Camera, @CameraPosition, @TargetPosition) Case #ThirdPersonFixed SetVector3(CameraPosition, 0, 200, 0) GetNodePosition(TargetPosition, *Entity\SightNode) CameraUpDate(*Camera, @CameraPosition, @TargetPosition) Case #FirstPerson GetEntityPosition(Temp, *Entity\Entity) AddVector3(CameraPosition, Temp, *Entity\Offset) GetNodePosition(TargetPosition, *Entity\SightNode) CameraUpDate(*Camera, @CameraPosition, @TargetPosition) EndSelect EndProcedure Procedure CameraInstantUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3) Protected V1.Vector3, V2.Vector3 MoveNode(*Camera\CameraNode, *CameraPosition\x, *CameraPosition\y, *CameraPosition\z, #PB_Absolute) MoveNode(*Camera\TargetNode, *TargetPosition\x, *TargetPosition\y, *TargetPosition\z, #PB_Absolute) CameraLookAt(*Camera\Camera, NodeX(*Camera\TargetNode), NodeY(*Camera\TargetNode), NodeZ(*Camera\TargetNode)) EndProcedure Procedure CameraUpdate(*Camera.s_Camera, *CameraPosition.Vector3, *TargetPosition.Vector3) Protected V1.Vector3, V2.Vector3 V1\x = (*CameraPosition\x - NodeX(*Camera\CameraNode)) * *Camera\Tightness V1\y = (*CameraPosition\y - NodeY(*Camera\CameraNode)) * *Camera\Tightness v1\z = (*CameraPosition\z - NodeZ(*Camera\CameraNode)) * *Camera\Tightness MoveNode(*Camera\CameraNode, V1\x, V1\y, V1\z) V2\x = (*TargetPosition\x - NodeX(*Camera\TargetNode)) * *Camera\Tightness V2\y = (*TargetPosition\y - NodeY(*Camera\TargetNode)) * *Camera\Tightness V2\z = (*TargetPosition\z - NodeZ(*Camera\TargetNode)) * *Camera\Tightness MoveNode(*Camera\TargetNode, V2\x, V2\y, V2\z) CameraLookAt(*Camera\Camera, NodeX(*Camera\TargetNode), NodeY(*Camera\TargetNode), NodeZ(*Camera\TargetNode)) EndProcedure