Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник по GLScene.doc
Скачиваний:
255
Добавлен:
16.12.2018
Размер:
7.18 Mб
Скачать

Глава 32. Физика Newton.

Сразу скажу: “Физический движок Ньютон совсем не сложен в изучении. Даже имея, скудный мануал из NewtonSDK изучить его можно за полторы недели”. Для работы с ньютоном необходимы Newton.dll и NewtonImport.pas Как и любой нормальный физический движок, Ньютон имеет мир, который создается так: NewtonWorld : PNewtonWorld; NewtonWorld := NewtonCreate(nil, nil); В конце работы программы, для освобождения памяти, следует вызвать: NewtonDestroy (NewtonWorld); Симулируется мир командой (ее необходимо прописать в коденсере): NewtonUpdate(NewtonWorld, DeltaTime); Твердое тело в ньютоне имеет тип PNewtonBody. При создании, указывается мир, в который оно вставляется, и коллизия (геометрическая оболочка тела, по которой определяются столкновения). Существует 10 типов коллизий: Null – прозрачная коллизия Box – параллелепипед Sphere – шар Cone – конус Capsule – капсула Cylinder – цилиндр ChamferCylinder – скошенный цилиндр ConvexHull – выпуклая оболочка TreeCollision – полигональная коллизия произвольной сложности (только для статических объектов) CompoundCollision – составная коллизия Создается коллизия функцией NewtonCreateXXX, где XXX - тип коллизии. Масса в ньютоне задается процедурой NewtonBodySetMassMatrix(NewtonBody, mass, Ixx, Iyy, Izz); Здесь Ixx, Iyy, Izz – моменты инерции для каждой оси. Для изменения положения тела в пространстве, необходимо изменить матрицу трансформации: Matrix : TMatrix4f; NewtonBodyGetMatrix(NewtonBody, @Matrix[0,0]); Matrix[3,0] :=x; Matrix[3,1] :=y; Matrix[3,2] :=z; NewtonBodySetMatrix(NewtonBody, @Matrix[0,0]); Имитация силы тяжести реализуется callback функцией: procedure ForceAndTorqueCallback(const body : PNewtonBody); cdecl; var Mass : Single; Inertia : TVector3f; Force : TVector3f; begin NewtonBodyGetMassMatrix(Body, @Mass, @Inertia.x, @Inertia.y, @Inertia.z); Force := V3(0, -9.8 * Mass, 0); NewtonBodyAddForce(Body, @Force.x); end; NewtonBodySetForceAndTorqueCallBack(NewtonBody, ForceAndTorqueCallBack); Например, создать куб можно так: procedure NewCube; var NewtonBody : PNewtonBody; Collision : PNewtonCollision; Matrix : TMatrix4f; Begin Collision := NewtonCreateBox(NewtonWorld, 1, 1, 1, nil); NewtonBody := NewtonCreateBody(NewtonWorld, Collision); NewtonReleaseCollision(NewtonWorld, Collision); NewtonBodySetMassMatrix(NewtonBody, 3, 0.5, 0.5, 0.5); NewtonBodySetForceAndTorqueCallBack(NewtonBody, ForceAndTorqueCallBack); end; Чтобы увидеть, что получилось, в коденсер, к NewtonUpdate’у добавляем: NewtonBodyGetMatrix(FNewtonBody, @Matrix[0,0]); GLCube.Matrix:=Matrix; В принципе, этого достаточно, чтобы понять, как работает ньютон.

Глава 33. Ручная проверка коллизий.

Коллизия – это событие столкновения двух объектов. В принципе, организовать проверку коллизии можно и сомостоятельно, тем неменее, для проверки коллизий в GLScene есть компонент CollisionManager из вкладки GLScene Utils.

1). CollisionManager

Поместите его на вашу форму. Установка проверки коллизий в режиме design time:

1. Щелкните по свойству Behaviours у объекта, который вы хотите проверять на коллизии.

2. Нажмите на кнопку со знаком плюс и выберите пункт Collision.

3. У созданной коллизии установите в свойстве Manager имя вашего менеджера коллизий, например CollisionManager1.

4. Выберите подходящее значение для свойства BoundingMode – это какой поверхностью заменяется объект.

Не при всех значениях BoundingMode правильно обрабатываются столкновения:

cbmPoint

cbmSphere

cbmEllipsoid

CbmCube

cbmFaces

cbmPoint

Правильно

Правильно

Правильно

Правильно

Как точка с

кубом

cbmSphere

Правильно

Правильно

Правильно

Правильно

Как куб с

кубом

cbmEllipsoid

Правильно

Правильно

Неправильно

Неправильно

Как куб с

кубом

cbmCube

Правильно

Правильно

Неправильно

Правильно

Правильно

cbmFaces

Как точка с

кубом

Как куб с

кубом

Как куб с

кубом

Правильно

Правильно

(между двумя

freeforms)

5. Установите свойство GroupIndex.

Если GroupIndex<0, то проверка на столкновения с другими объектами не делается;

Если GroupIndex=0, то проверяются столкновения с объектами, у которых GroupIndex>=0;

Если GroupIndex>0, то проверяются столкновения с объектами, у которых GroupIndex не совпадает;

Установка проверки коллизий в режиме run-time:

With GetOrCreateCollision(GLSphere1) do

Begin

Manager:=CollisionManager1;

GroupIndex:=0;

BoundingMode:=cbmSphere;

End;

Теперь в событии OnCollision менеджера коллизий напишите, что должно происходить при столкновении. Например:

procedure TForm1.CollisionManager1Collision(Sender: TObject; object1, object2: TGLBaseSceneObject); begin

ShowMessage('Collision between '+object1.Name+' and '+object2.Name);

end;

Теперь, если выполнить команду CollisionManager1.CheckCollisions; и какие-нибудь два объекта окажутся столкнувшимися, то выполнится процедура CollisionManager1Collision.