Author Topic: Библиотека Newton  (Read 1269 times)

0 Members and 1 Guest are viewing this topic.

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 865
  • Reputation 32
  • Game making is my hobby for life!
Библиотека Newton
« on: November 25, 2014, 10:46:42 AM »
Newton - это хорошая физическая библиотека, которая подходит для симулирования/моделирования многих физических явлений - столкновений, гравитации и многого другого.

Эта библиотека подключена к WS3D и есть один пример, показывающий работу с ней. (Newton была раньше подключена к предшественнику WS3D, но из-за одного критического бага была отключена; недавно этот баг был исправлен). Также недавно было исправлено 2 бага в примере использования библиотеки.

В данной теме можно выкладывать примеры использования Newton.
Офицмальный сайт Newton -> перейти.

Актульная библиотека Newton для ФБ (Newton.dll, WS3D_Newton.bi и пример) -> скачать
« Last Edit: November 25, 2014, 06:54:56 PM by Alec - WS3D Developer »
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 865
  • Reputation 32
  • Game making is my hobby for life!
Re: Библиотека Newton
« Reply #1 on: November 25, 2014, 06:42:22 PM »
Пример: Физика Newton: проверка столкновения и гравитация

В этом примере был баг: цилиндр и капсула, сталкиваясь с другими физическими телами, немного "проваливались" в них, особенно это было видно, когда "шапки", т.е. концы капсулы частично "утопали в полу", как бы проходя в него. Проблема не в самой библиотеке и не в заголовочных файлах, а в самом примере.

Вот в чём была проблема:
1) вместо функции для создания физического объекта "цилиндр" (PhysicsCreateCylinder( PrimNode(3), physPrim(3) )) стояла функция для создания капсулы (PhysicsCreateCapsule( PrimNode(4), physPrim(4) )). Я это исправил;
2) Для капсулы и цилиндра использовались 3D модели, расположенные вдоль оси Y (cylinderY.obj и capsuleY.obj), а необходимо для этих объектов использовать 3D модели, расположенные вдоль оси X. В папке Media есть и те и другие. Я просто заменил ссылки на модели, расположенные по оси X и всё заработало. То, что это необходимо, написано в справке на офиц. сайте Newton ("Capsule is aligned with the x axis after creation").
Вот так правильно:
Code: [Select]
PrimMesh(1) = wGetMesh( "../media/Models/cylinderX.obj" )
PrimMesh(2) = wGetMesh( "../media/Models/capsuleX.obj" )

Также я убрал подключение заголовочного файла "WorldSim3D.bi" из этого примера, так как я включил его в "WS3D_Newton.bi"

Code: [Select]
'' ----------------------------------------------------------------------------
'' Пример сделал Frank Dodd
'' Изменил и исправил: nikolas и Alec Artifex (WorldSim3D developer)
'' Благодарность Julio Herez и Alain Suero (Newton Dinamics developers)
'' Благодарность siskinedge (портировал Newton Dinamics на FreeBASIC)
'' ----------------------------------------------------------------------------
'' Пример 114: Физика Newton: проверка столкновения и гравитация
'' Этот пример показывает как работает проверка столкновения и гравитация в физике
'' Newton. Несколько геометрических примитивов падают на пол и друг на друга.
'' Обратите внимание, что функции для работы с физикой Newton начинаются с префикса 'Physics'
'' В корневой папке проекта должен быть файл 'newton.dll'
'' ----------------------------------------------------------------------------

'' Includes for extension libraries
#Include "WS3D_Newton.bi"


'' global variables

' WorldSim3D objects
DIM CubeMesh as wMesh
DIM CubeTexture as wTexture
DIM Shared HitTexture as wTexture
DIM MapTexture as wTexture
DIM FloorNode as wNode
DIM PrimMesh(4) as wMesh
DIM PrimNode(6) as wNode
DIM OurCamera as wCamera
DIM Light as wNode

' physics objects
DIM physFloor as physics_obj
DIM physPrim(6) as physics_obj


' -----------------------------------------------------------------------------
'' callback function for collisions
Sub PhysicsReported( p1 as physics_obj ptr, p2 as physics_obj ptr)

    if NOT p1 = 0 then if NOT p1->node = 0 then wSetNodeMaterialTexture( p1->node, HitTexture, 0 )
    if NOT p2 = 0 then if NOT p2->node = 0 then wSetNodeMaterialTexture( p2->node, HitTexture, 0 )

End Sub

' -----------------------------------------------------------------------------
' start the WorldSim3D interface
wStart( wDT_OPENGL, 800, 600, wBITS_PER_PIXEL_32, wWINDOWED, _
          wSHADOWS, wCAPTURE_EVENTS, wVERTICAL_SYNC_ON )

' set the window caption
wSetWindowCaption( "Example 114: Newton Physics: Collision and gravity" )

' load texture resources for texturing the scene nodes
CubeTexture = wGetTexture( "../media/Textures/default_texture.png" )
HitTexture = wGetTexture( "../media/Textures/cross.bmp" )
wSetTextureCreationFlag( wTCF_CREATE_MIP_MAPS, wOFF )
MapTexture = wGetTexture( "../media/Textures/maplightmap.jpg" )

' load resource for the primitive shapes
PrimMesh(1) = wGetMesh( "../media/Models/cylinderX.obj" )
PrimMesh(2) = wGetMesh( "../media/Models/capsuleX.obj" )
PrimMesh(3) = wGetMesh( "../media/Models/wedge.obj" )
PrimMesh(4) = wGetMesh( "../media/Models/simplemap.obj" )

' scale the map mesh up instead of the node to preserve lighting effects
wScaleMesh( PrimMesh(4), 250.0 )

' add nodes to represent the physical objects
PrimNode(1) = wAddTestSceneNode
PrimNode(2) = wAddSphereSceneNode( 5.0, 8 )
PrimNode(3) = wAddMeshToScene( PrimMesh(1) )
PrimNode(4) = wAddMeshToScene( PrimMesh(2) )
PrimNode(5) = wAddMeshToScene( PrimMesh(3) )

' scale up the primitive meshes
wSetNodeScale( PrimNode(3), 5.0, 5.0, 5.0 )
wSetNodeScale( PrimNode(4), 5.0, 5.0, 5.0 )
wSetNodeScale( PrimNode(5), 5.0, 5.0, 5.0 )

' apply a material to the node to give its surface color
wSetNodeMaterialTexture( PrimNode(1), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(2), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(3), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(4), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(5), CubeTexture, 0 )

PrimNode(6) = wAddMeshToScene( PrimMesh(4) )
wSetNodeMaterialTexture( PrimNode(6), MapTexture, 0 )

' add a simple light into the scene
wAddLight( wNO_PARENT, 100,100,-100, 1.9,0.9,0.9, 2600.0 )

' add a camera into the scene,
OurCamera = wAddCamera( 50,50,50, 0,0,0 )

' initialise the physics environment
PhysicsInit

' create an physics world box from the bounding box of a node
PhysicsCreateBox( PrimNode(1), physPrim(1) )
PhysicsCreateSphere( PrimNode(2), physPrim(2) )
PhysicsCreateCylinder( PrimNode(3), physPrim(3) )
PhysicsCreateCapsule( PrimNode(4), physPrim(4) )
PhysicsCreateConvexHull( PrimNode(5), physPrim(5) )

PhysicsCreateTriMesh( PrimNode(6), physPrim(6) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(1), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(1), 0.0, 40.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(1) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(2), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(2), 0.0, 60.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(2) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(3), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(3), 0.0, 80.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(3) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(4), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(4), 0.0, 100.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(4) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(5), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(5), 0.0, 120.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(5) )

' -----------------------------------------------------------------------------
' while the WorldSim3D environment is still running
Dim as Single timeElapsed, currentTime, frameTime = timer
WHILE wRunning
    ' is it time for another frame
    currentTime = timer
    timeElapsed = currentTime - frameTime
    if timeElapsed > 0.0167 then
        ' record the start time of this frame
        frameTime = currentTime

        ' begin the scene, erasing the canvas with sky-blue before rendering
        wBeginScene( 240, 255, 255 )

        ' Update the physics environment
        PhysicsUpdate( timeElapsed )

        ' make the camera track the first box
        Dim as single x,y,z
        wGetNodePosition( PrimNode(1), x,y,z)
        wSetNodePosition( OurCamera, cos(currentTime/5) * 80.0, 30.0, Sin(currentTime/5) * 80.0 )
        wSetCameraTarget( OurCamera,x,y,z)

        ' draw the scene
        wDrawScene
       
        ' end drawing the scene and render it
        wEndScene
    End If
    wCloseEsc()
WEND

' -----------------------------------------------------------------------------
' Stop the WorldSim3D engine and release resources
wStop

' release Physics resources
PhysicsStop

« Last Edit: November 25, 2014, 06:44:33 PM by Alec - WS3D Developer »
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 865
  • Reputation 32
  • Game making is my hobby for life!
Re: Библиотека Newton
« Reply #2 on: December 05, 2014, 10:18:10 PM »
Изменение гравитации

Этот пример показывает как работает гравитация, а также как её менять в физике Newton. Это делается функцией PhysicsSetGravity(axisX, axisY, axisZ).

Где это может понадобиться? Установить разную гравитацию на разных планетах (смотрите астрономические справочники). Например, на Земле, у поверхности гравитация составляет 9.81 (в каких единицах измеряется, смотрите справочники по физике). Также например, можно сделать отсутствие или слабую, или наоборот очень сильную гравитацию на космическом корабле или станции, так что персонажу будет неудобно или трудно перемещаться.

Можно также сделать казуальные игры, меняя гравитацию не только по оси Y, но и по другим осям.
Code: [Select]
'' ----------------------------------------------------------------------------
'' Пример сделал Alec Artifex (WorldSim3D developer)
'' на основе примера от Frank Dodd
'' ----------------------------------------------------------------------------
'' Пример: Физика Newton: изменение гравитации
'' Этот пример показывает как работает гравитация, а также как её менять в физике
'' Newton. Это делается функцией PhysicsSetGravity(axisX, axisY, axisZ).
'' Несколько геометрических примитивов падают на пол и друг на друга.
'' Обратите внимание, что функции для работы с физикой Newton начинаются с префикса 'Physics'
'' В корневой папке проекта должен быть файл 'newton.dll'
'' ----------------------------------------------------------------------------

'' Includes for extension libraries
#Include "WS3D_Newton.bi"


'' global variables
Dim BitmapFont as wFont
Dim BitmapFont_2 as wFont

' WorldSim3D objects
DIM CubeMesh as wMesh
DIM CubeTexture as wTexture
DIM Shared HitTexture as wTexture
DIM MapTexture as wTexture
DIM FloorNode as wNode
DIM PrimMesh(1 To 4) as wMesh
DIM PrimNode(1 To 6) as wNode
DIM OurCamera as wCamera
DIM Light as wNode

' physics objects
DIM physFloor as physics_obj
DIM physPrim(1 To 6) as physics_obj

' Переменная для значения гравитации. При отрицательные значениях (конечно, не в реальной физике, а здесь
' в физике Ньютон) сила гравитации направлена вниз, как на какой-либо планете (для Земли это  -9.81).
' Меняйте это значение для установки разной гравитации.
Dim g As Single = -9.81


' -----------------------------------------------------------------------------
'' callback function for collisions
Sub PhysicsReported( p1 as physics_obj ptr, p2 as physics_obj ptr)

    if NOT p1 = 0 then if NOT p1->node = 0 then wSetNodeMaterialTexture( p1->node, HitTexture, 0 )
    if NOT p2 = 0 then if NOT p2->node = 0 then wSetNodeMaterialTexture( p2->node, HitTexture, 0 )

End Sub

' -----------------------------------------------------------------------------
' start the WorldSim3D interface
wStart( wDT_OPENGL, 800, 600, wBITS_PER_PIXEL_32, wWINDOWED, _
          wSHADOWS, wCAPTURE_EVENTS, wVERTICAL_SYNC_ON )

' set the window caption
wSetWindowCaption( "Example: Newton Physics: Adjusting gravity" )
BitmapFont = wGetFont ( "../media/Fonts/4.png" )
BitmapFont_2 = wGetFont ( "../media/Fonts/3.png" )

' load texture resources for texturing the scene nodes
CubeTexture = wGetTexture( "../media/Textures/default_texture.png" )
HitTexture = wGetTexture( "../media/Textures/cross.bmp" )
MapTexture = wGetTexture( "../media/Textures/Cross.bmp" )

' load resource for the primitive shapes
PrimMesh(1) = wGetMesh( "../media/Models/cylinderX.obj" )
PrimMesh(2) = wGetMesh( "../media/Models/capsuleX.obj" )
PrimMesh(3) = wGetMesh( "../media/Models/wedge.obj" )
PrimMesh(4) = wGetMesh( "../media/Models/Sci-fi_floor2.obj" )

' add nodes to represent the physical objects
PrimNode(1) = wAddTestSceneNode
PrimNode(2) = wAddSphereSceneNode( 5.0, 8 )
PrimNode(3) = wAddMeshToScene( PrimMesh(1) )
PrimNode(4) = wAddMeshToScene( PrimMesh(2) )
PrimNode(5) = wAddMeshToScene( PrimMesh(3) )

' scale up the primitive meshes
wSetNodeScale( PrimNode(3), 5.0, 5.0, 5.0 )
wSetNodeScale( PrimNode(4), 5.0, 5.0, 5.0 )
wSetNodeScale( PrimNode(5), 5.0, 5.0, 5.0 )

' apply a material to the node to give its surface color
wSetNodeMaterialTexture( PrimNode(1), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(2), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(3), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(4), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(5), CubeTexture, 0 )

PrimNode(6) = wAddMeshToScene( PrimMesh(4) )
wSetNodeScale ( PrimNode(6), 3.0,1.0,3.0 )
wSetNodeMaterialTexture( PrimNode(6), MapTexture, 0 )

' add a simple light into the scene
wAddLight( wNO_PARENT, 100,100,-100, 0.9,0.9,0.9, 2600.0 )
wSetAmbientLight ( 0.9, 0.9, 0.9 )


' add a camera into the scene,
OurCamera = wAddCamera( 40,40,40, 0,0,0 )

'====================================================================================
' ИНИЦИАЛИЗАЦИЯ ФИЗИЧЕСКОГО ОКРУЖЕНИЯ
PhysicsInit

' ЗДЕСЬ УСТАНАВЛИВАЕТСЯ ГРАВИТАЦИЯ
' 3 значения по соответствующим осям.
' В данном примере меняется только по оси Y, т.е. сила гравитации направлена
' прямо вниз (как на планете), но можно и направить вверх, если это нужно для каких-то целей
PhysicsSetGravity(0,g,0)

' create an physics world box from the bounding box of a node
PhysicsCreateBox( PrimNode(1), physPrim(1) )
PhysicsCreateSphere( PrimNode(2), physPrim(2) )
PhysicsCreateCylinder( PrimNode(3), physPrim(3) )
PhysicsCreateCapsule( PrimNode(4), physPrim(4) )
PhysicsCreateConvexHull( PrimNode(5), physPrim(5) )

PhysicsCreateTriMesh( PrimNode(6), physPrim(6) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(1), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(1), 0.0, 40.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(1) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(2), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(2), 0.0, 60.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(2) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(3), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(3), 0.0, 80.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(3) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(4), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(4), 0.0, 100.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(4) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(5), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(5), 0.0, 120.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(5) )

' -----------------------------------------------------------------------------
' while the WorldSim3D environment is still running
Dim as Single currentTime
Dim as single x,y,z
WHILE wRunning
    currentTime = Timer
   
        ' begin the scene, erasing the canvas with sky-blue before rendering
        wBeginScene( 20, 25, 25 )

        ' Update the physics environment every frame (1/60 sec)
        PhysicsUpdate( 0.0167 )

        ' make the camera track the first box
       
        wGetNodePosition( PrimNode(1), x,y,z)
        wSetNodePosition( OurCamera, cos(currentTime/5) * 80.0, 30.0, Sin(currentTime/5) * 80.0 )
        wSetCameraTarget( OurCamera,x,y,z)

        ' draw the scene
        wDrawScene
       
      w2DFontDraw ( BitmapFont_2, "Gravity: "+Str(g), 10, 10, 100, 25 )
      w2DFontDraw ( BitmapFont, "The distance between the cube and the floor is 40 meters ", 250, 15, 750, 25 )
        ' end drawing the scene and render it
        wEndScene
    wCloseEsc()
    wSetFPS
WEND

' -----------------------------------------------------------------------------
' Stop the WorldSim3D engine and release resources
wStop

' release Physics resources
PhysicsStop
WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Alec - WS3D Developer

  • Producer
  • Administrator
  • Marquess
  • *
  • Posts: 865
  • Reputation 32
  • Game making is my hobby for life!
Re: Библиотека Newton
« Reply #3 on: March 22, 2015, 03:52:32 PM »
Пример: Физика Newton: определение контакта между 2-мя телами
В этом примере показано, как определить, что происходит контакт между 2-мя физическими телами. В данном примере между сферой и плоскостью. Когда между ними происходит контакт,то выводится сообщение: "Контакт между сферой и плоскостью: Да" (сначала контакта нет, так как сфера несколько секунд падает с высоты, поэтому сообщение о контакте: "... Нет").

Для этой цели используется функция PhysicsCheckCollision ( тело_1, тело_2 )
Сначала я создал пустой проект с помощью инструмента 'Wizard' с выбором опции "использовать физику Ньютон". Если вы сделаете так же и потом просто вставите код, то пример сразу запустится.

Code: [Select]
#include "MyFunctions.bi"
'' ----------------------------------------------------------------------------
'' Пример сделал Alec Artifex (WorldSim3D developer)
'' ----------------------------------------------------------------------------
'' Пример: Физика Newton: определение контакта между 2-мя телами
'' В этом примере показано, как определить, что происходит контакт между 2-мя
'' физическими телами. В данном примере между сферой и плоскостью. Когда между
'' ними происходит контакт,то выводится сообщение:
'' "Контакт между сферой и плоскостью: Да".
'' ----------------------------------------------------------------------------

'' Includes for extension libraries

'' global variables
Dim BitmapFont as wFont
Dim BitmapFont_2 as wFont

' WorldSim3D objects
DIM CubeMesh as wMesh
DIM CubeTexture as wTexture
DIM Shared HitTexture as wTexture
DIM MapTexture as wTexture
DIM FloorNode as wNode
DIM PrimMesh(1 To 4) as wMesh
DIM PrimNode(1 To 6) as wNode
DIM OurCamera as wCamera
DIM Light as wNode
DIM KeyEvent as wKEY_EVENT Ptr

' physics objects
DIM physFloor as physics_obj
DIM physPrim(1 To 6) as physics_obj

' Переменная для значения гравитации. При отрицательные значениях (конечно, не в реальной физике, а здесь
' в физике Ньютон) сила гравитации направлена вниз, как на какой-либо планете (для Земли это  -9.81).
' Меняйте это значение для установки разной гравитации.
Dim g As Single = -9.81
Dim as Single currentTime
Dim as single x,y,z
Dim coll As Integer = 0  ' сначала плоскость и сфера не соприкасаются. Когда между ними будет
' контакт, то значение переменной coll станет равно 1.
Dim coll_mes As String = "Нет" 'сначала на экране сообщение о том, что контакта нет между ними

' -----------------------------------------------------------------------------
'' callback function for collisions
Sub PhysicsReported( p1 as physics_obj ptr, p2 as physics_obj ptr)

    if NOT p1 = 0 then if NOT p1->node = 0 then wSetNodeMaterialTexture( p1->node, HitTexture, 0 )
    if NOT p2 = 0 then if NOT p2->node = 0 then wSetNodeMaterialTexture( p2->node, HitTexture, 0 )

End Sub

' -----------------------------------------------------------------------------
' start the WorldSim3D interface
wStart( wDT_OPENGL, 800, 600, wBITS_PER_PIXEL_32, wWINDOWED, _
          wSHADOWS, wCAPTURE_EVENTS, wVERTICAL_SYNC_ON )

' set the window caption
wSetWindowCaption( "Пример: физика Ньютон - определение контакта" )
BitmapFont = wGetFont ( "media/3.png" )
BitmapFont_2 = wGetFont ( "media/Cyr.xml" )

' load texture resources for texturing the scene nodes
CubeTexture = wGetTexture( "media/default_texture.png" )
HitTexture = wGetTexture( "media/Cross.bmp" )
MapTexture = wGetTexture( "media/Cross.bmp" )

' load resource for the primitive shapes
PrimMesh(1) = wGetMesh( "media/cylinderX.obj" )
PrimMesh(2) = wGetMesh( "media/capsuleX.obj" )
PrimMesh(3) = wGetMesh( "media/wedge.obj" )
PrimMesh(4) = wGetMesh( "media/Sci-fi_floor2.obj" )

' add nodes to represent the physical objects
PrimNode(1) = wAddTestSceneNode
PrimNode(2) = wAddSphereSceneNode( 5.0, 8 )
PrimNode(3) = wAddMeshToScene( PrimMesh(1) )
PrimNode(4) = wAddMeshToScene( PrimMesh(2) )
PrimNode(5) = wAddMeshToScene( PrimMesh(3) )

' scale up the primitive meshes
wSetNodeScale( PrimNode(3), 5.0, 5.0, 5.0 )
wSetNodeScale( PrimNode(4), 5.0, 5.0, 5.0 )
wSetNodeScale( PrimNode(5), 5.0, 5.0, 5.0 )

' apply a material to the node to give its surface color
wSetNodeMaterialTexture( PrimNode(1), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(2), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(3), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(4), CubeTexture, 0 )
wSetNodeMaterialTexture( PrimNode(5), CubeTexture, 0 )

' Floor
PrimNode(6) = wAddMeshToScene( PrimMesh(4) )
wSetNodeScale ( PrimNode(6), 3.0,1.0,3.0 )
wSetNodeMaterialTexture( PrimNode(6), MapTexture, 0 )

' add a simple light into the scene
wAddLight( wNO_PARENT, 100,100,-100, 0.9,0.9,0.9, 2600.0 )
wSetAmbientLight ( 0.9, 0.9, 0.9 )


' add a camera into the scene,
OurCamera = wAddCamera( 40,40,40, 0,0,0 )

'====================================================================================
' ИНИЦИАЛИЗАЦИЯ ФИЗИЧЕСКОГО ОКРУЖЕНИЯ
PhysicsInit

' ЗДЕСЬ УСТАНАВЛИВАЕТСЯ ГРАВИТАЦИЯ
' 3 значения по соответствующим осям.
' В данном примере меняется только по оси Y, т.е. сила гравитации направлена
' прямо вниз (как на планете), но можно и направить вверх, если это нужно для каких-то целей
PhysicsSetGravity(0,g,0)

' create an physics world box from the bounding box of a node
PhysicsCreateBox( PrimNode(1), physPrim(1) )
PhysicsCreateSphere( PrimNode(2), physPrim(2) )
PhysicsCreateCylinder( PrimNode(3), physPrim(3) )
PhysicsCreateCapsule( PrimNode(4), physPrim(4) )
PhysicsCreateConvexHull( PrimNode(5), physPrim(5) )

' Floor
PhysicsCreateTriMesh( PrimNode(6), physPrim(6) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(1), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(1), 0.0, 40.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(1) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(2), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(2), 0.0, 60.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(2) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(3), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(3), 0.0, 80.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(3) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(4), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(4), 0.0, 100.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(4) )

' create a random rotation for the node and update the associated physics object
wSetNodeRotation( PrimNode(5), Rnd*360, Rnd*360, Rnd*360 )
wSetNodePosition( PrimNode(5), 0.0, 120.0, 0.0 )
PhysicsGetNodePositionAndRotation( physPrim(5) )

' -----------------------------------------------------------------------------
' while the WorldSim3D environment is still running
WHILE wRunning
    currentTime = Timer
   
        ' begin the scene, erasing the canvas with sky-blue before rendering
        wBeginScene( 20, 25, 25 )

        ' Update the physics environment every frame (1/60 sec)
        PhysicsUpdate( 0.0167 )

        ' make the camera track the first box
       
        wGetNodePosition( PrimNode(1), x,y,z)
        wSetNodePosition( OurCamera, cos(currentTime/5) * 80.0, 30.0, Sin(currentTime/5) * 80.0 )
        wSetCameraTarget( OurCamera,x,y,z)
       
        If PhysicsCheckCollision( physPrim(6), physPrim(2) ) = 1 Then
              coll = 1: coll_mes = "Да"
        Else coll = 0: coll_mes = "Нет"
        EndIf
       
'PhysicsSetGravity(0,g,0)
While wKeyEventAvailable
   
            ' read the key event out. the key event has three parameters the key
            ' scan code, the direction of the key and flags that indicate whether
            ' the control key or the shift keys were also pressed
            KeyEvent = wReadKeyEvent
   
            ' arbitrate based on the key that was pressed
            select case as const KeyEvent->key
                case KEY_KEY_D     ' Right Arrow
                ' if the key is going down
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                endif
   
                   
                case KEY_KEY_A     ' Left Arrow
                ' if the key is going down
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                endif
           
            case KEY_KEY_W     ' Up Arrow
                ' if the key is going down
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                endif
                   
            case KEY_KEY_S     ' Down Arrow
                ' if the key is going down
                if KeyEvent->direction = wKEY_DOWN then
                   
                else
                   
                endif
            wCloseKEY_ESC()
   
            end Select
Wend
        ' draw the scene
        wDrawScene
       
          w2DFontDraw ( BitmapFont_2, "Гравитация: "+Str(g), 10, 10, 100, 25 )
          w2DFontDraw ( BitmapFont_2, "Контакт между сферой и плоскостью:  " + coll_mes, 10, 50, 200, 70 )
          w2DFontDraw ( BitmapFont_2, "Расстояние между кубом и плоскостью 40 метров ", 150, 570, 750, 590 )
        ' end drawing the scene and render it
        wEndScene
    wCloseEsc()
    wSetFPS
WEND

' -----------------------------------------------------------------------------
' Stop the WorldSim3D engine and release resources
wStop

' release Physics resources
PhysicsStop

WorldSim3D = 3D + FreeBasic. Программируй в удовольствие, а не "в тягость"! Make your project with pleasure, not with strain!

Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Viscount
  • *
  • Posts: 768
  • Reputation 51
Re: Библиотека Newton
« Reply #4 on: August 31, 2015, 12:57:31 PM »
ПРИМЕР: УПРАВЛЕНИЕ ПЕРСОНАЖЕМ ОТ ПЕРВОГО ЛИЦА (ИГРОВОЙ КОНТРОЛЛЕР)
Привет всем. Предлагается к рассмотрению черновой вариант контроллера управления персонажем от первого лица.
Задействован Ньютон, поэтому сообщение в данном топике.
Конечно, он далек от совершенства, но основную функцию выполняет: повороты и передвижение камеры (невидимая физическая капсула), прыжок, гравитация и взаимодействие (коллизии) с окружающими предметами. Реализована плавная остановка камеры.
Пришлось дописать и подредактировать заголовочный файл WS3D_Newton.bi
Template3.bas => Examples/
WS3D_Newton_VER2.bi => Libs/Newton/
« Last Edit: September 02, 2015, 06:38:41 PM by nikolas »
Под лежачий камень мы всегда успеем...

Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Viscount
  • *
  • Posts: 768
  • Reputation 51
Re: Библиотека Newton
« Reply #5 on: September 01, 2015, 10:27:22 PM »
Привет всем.
Немного изменил настройки контроллера: убрал часть кода (закомментировано с 320 по341) -лишнего, как оказалось.
А именно: убрал повороты куба (типо персонаж), которые повторяли повороты камеры в плоскости XOZ- все равно куб невидим.
Это могло-бы пригодиться, если бы был реальный персонаж/модель. Но в таком случае управление было бы не от 1-го лица  (от 3-го), настройки были бы совершенно другие. Убрал одну недоработку: скорость движения камеры была неравномерной, сразу не обратил внимания, думал, Ньютон "подтормаживает". Оказалось, причина в коде. Дабы не разводить кучу ссылок, обновил ссылку на файл Template3.bas в предыдущем посте.

PS. Если камера не реагирует на WASD, попробуйте сначала прыгнуть (SPACE).
« Last Edit: September 02, 2015, 06:40:12 PM by nikolas »
Под лежачий камень мы всегда успеем...

Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Viscount
  • *
  • Posts: 768
  • Reputation 51
Re: Библиотека Newton
« Reply #6 on: September 10, 2015, 11:09:28 PM »
ПРИМЕР: ЛУЧИ (RayCast) в NEWTON.
Пример сделан на основе игрового физ. контроллера из предыдущего примера.
Демонстрация работы процедуры PhysicsCastRay( p1 as wVECTOR, p2 as wVECTOR,Byref obj As physics_obj Ptr)
Использовано два луча: 1) вертикальный луч (длина=6) для отслеживания соприкосновения с поверхностью "земли";
2) луч, идущий от положения игрока в направление "взгляда".
В примере есть недоработки, со временем отшлифуем.
Как обычно:
Template3.bas => Examples/
WS3D_Newton_VER2.bi => Libs/Newton/
« Last Edit: September 10, 2015, 11:21:35 PM by nikolas »
Под лежачий камень мы всегда успеем...