forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Коллизия без метода? Это возможно? (http://forum.boolean.name/showthread.php?t=12112)

battou 04.03.2010 21:47

Коллизия без метода? Это возможно?
 
В общем мне надо как-то сделать что бы столкновение между объектами просчитывалось, что они объект соприкасается с другим, но при этом они могли спокойно проходить сквозь друг друга. Так можно сделать? Например вот движется куб, проходит сквозь другой куб и в этот момент считается коллизия, но куб не останавливается, а проходит насквозь.

SKA_DIMKA 04.03.2010 21:59

Ответ: Коллизия без метода? Это возможно?
 
Кажется тебе стоит посмотреть в сторону CountCollisions ( entity )... (Справка) Команда возвращает число столкновений за последний UpdateWorld();)

Reks888 04.03.2010 22:01

Ответ: Коллизия без метода? Это возможно?
 
ы? А кто мешает тебе проверять дистанцию между твоими кубами? Если все-таки нужно столкновения , то делай так:
If EntityCollided(cube1,cube2) Then ClearCollisions()
при столкновении кубов эта команда очистит список столкновений, поэтому столкновения не будут обрабатываться до следующего использования команды Collisions.

battou 04.03.2010 22:11

Re: Коллизия без метода? Это возможно?
 
Не, мне надо что бы коллизия считалась, так как она будет условием внутри цакла, триггером считайте, но кубы должны проходить сквозь друг друга. А Countcollisions только выдаст количество столкновений, оно без Collisions не работает всё равно и не поможет мне.

Reks888 04.03.2010 22:24

Ответ: Коллизия без метода? Это возможно?
 
А EntityDistance не может быть условием внутри цикла?

SKA_DIMKA 04.03.2010 22:46

Ответ: Коллизия без метода? Это возможно?
 
Цитата:

Сообщение от Reks888 (Сообщение 140591)
А EntityDistance не может быть условием внутри цикла?

Еще тогда нужно учитывать и Scale модели.

battou 04.03.2010 23:03

Re: Коллизия без метода? Это возможно?
 
Эх, дистанция подошла бы если бы определялась дистанция до ближайшего полигона или хотя бы стороны бокса модели, а определяется до центра, а мне надо что бы при контакте с гланицами срабатывало условие.(

H@NON 04.03.2010 23:09

Ответ: Коллизия без метода? Это возможно?
 
последний параметр отвечает за реакцию на столкновение, 0 вроде отключает реакцию.
Collisions type1, type2, method, 0

battou 04.03.2010 23:14

Re: Коллизия без метода? Это возможно?
 
Неа, не работает. Я тут посмотрел, а если через Entityintersect? Она очень тормозит программу?

Taugeshtu 04.03.2010 23:45

Ответ: Коллизия без метода? Это возможно?
 
Подключи физикс и радуйся жизни. Средствами блитца коллизии медлительны, хотя если не хочется привлекать сторонние модули - ими тоже можно обойтись...
Хитросфинктерное решение:
перед применением коллизий (вроде updateworld, да?) запоминать координаты объектов, затем применять коллизии, считать пересечения объектов и возвращать ентити в свои позиции перед рендером. Но как я понял, тебе такое не подойдет.
МешИнтерсект кажется затратный был ощутимо...

IGR 04.03.2010 23:53

Ответ: Коллизия без метода? Это возможно?
 
мешИнтерсект как бэ решение !! ;)

KingMaks 04.03.2010 23:57

Ответ: Коллизия без метода? Это возможно?
 
Я как то попробовал мешинтерсект -
когда возле игрока слишком много полигонов было(относительно много) то игра начала тормозить

battou 05.03.2010 00:21

Re: Коллизия без метода? Это возможно?
 
Ну у меня интерсект проверяется только с объектами триггерами, а они максимум 20 поликов, в основном вообще боксы всякие в максе расставленные. Просто при коллизии если без пересечения то надо что бы объект постоянно упарался в этот триггер, а не просто стоял в нём.

H@NON 05.03.2010 13:29

Ответ: Коллизия без метода? Это возможно?
 
Юзай мою систему триггеров :
Код:

;============================ 
 ;Title: TriggerSystem 0.1 
 ;Autor: H@non 
 ;contact: [email protected] 
 ;============================ 

 Const TRIG_BOX1 = 1, TRIG_BOX2 = 2, TRIG_SPHERE = 3 

 Type TriggerInfo 
  Field x#, y#, z# 
  Field pitch#, yaw#, roll# 
  Field Tip 
  Field HandleTrig 
 End Type 

 Type TriggerBox 
  Field w#, h#, d# 
  Field mesh 
 End Type 

 Type TriggerSphere 
  Field radius# 
  Field mesh 
 End Type 

 Global TrigEnt 

 Function InitTrigger() 
  TrigEnt = CreatePivot() 
 End Function 

 Function AddTrigSphere.TriggerInfo(debug=False, x#, y#, z#, radius#=1) 
  Local t.TriggerInfo = New TriggerInfo 
  t\x=x : t\y=y : t\z=z 
  t\Tip = TRIG_SPHERE 
  Local ts.TriggerSphere = New TriggerSphere 
  If debug = True Then 
    ts\mesh = CreateSphere(16) 
    ScaleMesh ts\mesh, radius, radius, radius 
    PositionEntity ts\mesh, t\x, t\y, t\z 
    EntityAlpha ts\mesh, 0.5 
  EndIf 
  ts\radius = radius*radius 
  t\HandleTrig = Handle (ts) 
   
  Return t 
 End Function 

 Function AddTrigBox.TriggerInfo(debug=False, x#, y#, z#, w#=1, h#=1, d#=1, Tip=TRIG_BOX1, pitch#=0, yaw#=0, roll#=0) 
  Local t.TriggerInfo = New TriggerInfo 
  t\x=x : t\y=y : t\z=z 
  t\Tip = Tip 
  If Tip = TRIG_BOX2 Then 
    t\pitch=pitch : t\yaw=yaw : t\roll=roll 
  EndIf 
  Local tb.TriggerBox = New TriggerBox 
  tb\w=w : tb\h=h : tb\d=d 
  t\HandleTrig = Handle (tb) 
  If debug=True Then 
    tb\mesh = CreateCube() 
    FitMesh tb\mesh, 0, 0, 0, tb\w, tb\h, tb\d 
    PositionEntity tb\mesh, t\x, t\y, t\z 
    RotateEntity tb\mesh, t\pitch, t\yaw, t\roll 
    EntityAlpha tb\mesh, 0.5 
  EndIf 
   
   
  Return t 
 End Function 

 Function CheckEntityInTrig( ent, t.TriggerInfo ) 
  Local dx#, dy#, dz# 
  Local dist# 
  Local tb.TriggerBox, ts.TriggerSphere 
   
  Select t\Tip 
    Case TRIG_SPHERE : 
    dx = EntityX(ent,1) - t\x 
    dy = EntityY(ent,1) - t\y 
    dz = EntityZ(ent,1) - t\z 
    dist = (dx*dx + dy*dy + dz*dz) 
    ts.TriggerSphere = Object.TriggerSphere( t\HandleTrig ) 
    If dist <= ts\radius Then Return True 
    Return False 
    Case TRIG_BOX1 : 
    If EntityX(ent,1) >= t\x Then 
      If EntityY(ent,1) >= t\y Then 
      If EntityZ(ent,1) >= t\z Then 
        tb.TriggerBox = Object.TriggerBox( t\HandleTrig ) 
        If EntityX(ent,1) <= t\x+tb\w Then 
        If EntityY(ent,1) <= t\y+tb\h Then 
          If EntityZ(ent,1) <= t\z+tb\d Then 
          Return True 
          EndIf 
        EndIf 
        EndIf 
      EndIf 
      EndIf 
    EndIf 
    Return False 
    Case TRIG_BOX2 : 
    tb.TriggerBox = Object.TriggerBox( t\HandleTrig ) 
    PositionEntity (TrigEnt, t\x, t\y, t\z) 
    RotateEntity (TrigEnt, t\pitch, t\yaw, t\roll) 
     
    TFormPoint (EntityX(ent,1), EntityY(ent,1), EntityZ(ent,1), 0, TrigEnt) 
    If TFormedX() >= 0 Then 
      If TFormedY() >= 0 Then 
      If TFormedZ() >= 0 Then 
        If TFormedX() <= tb\w Then 
        If TFormedY() <= tb\h Then 
          If TFormedZ() <= tb\d Then 
          Return True 
          EndIf 
        EndIf 
        EndIf 
      EndIf 
      EndIf 
    EndIf 
    Return False 
  End Select 
 End Function

пример использования:
Код:

Graphics3D 800, 600, 32, 2 
 SetBuffer BackBuffer() 
 SeedRnd MilliSecs() 

 Local lit = CreateLight(1) 
 RotateEntity lit, 45, 45, 0 

 Local camera = CreateCamera() 
 PositionEntity camera, 0, 10, -10 
 RotateEntity camera, 45, 0, 0 

 Local plane = CreatePlane() 
 PositionEntity plane, 0, -1, 0 
 EntityColor plane, 0, 255, 0 
 Local texplane = CreateTexture( 128, 128 ) 
 SetBuffer TextureBuffer(texplane) 
 For Y = 0 To 128 
  For X = 0 To 128 
    WritePixel X, Y, (Rand(96,160) * $010101) Or $FF000000 
  Next 
 Next 
 SetBuffer BackBuffer() 
 EntityTexture plane, texplane 
 ScaleTexture texplane, 10, 10 
 FreeTexture texplane 

 Include "TrigMain.bb" 

 Global trigSphere.triggerinfo 
 Global trigBox1.triggerinfo 
 Global trigBox2.triggerinfo 
 InitTrigger() 
 trigSphere = AddTrigSphere(True, 6, 0, 0, 2) 
 trigBox1 = AddTrigBox(True, -2, -1, -1, 4, 2, 2) 
 trigBox2 = AddTrigBox(True, -7, -1, -1, 2, 2, 2, TRIG_BOX2, 0,  45, 0) 

 Local cube = CreateCube() 
 ScaleEntity cube, 0.1, 0.1, 0.1 
 MoveEntity cube, 0, 0.5, 0 

 Local InTrigSphere, InTrigCube1, InTrigCube2 
 While Not KeyHit(1) 
   
  MoveEntity cube, (KeyDown(205)-KeyDown(203))*0.1, 0, (KeyDown(200)-KeyDown(208))*0.1 
   
    InTrigSphere = CheckEntityInTrig( cube, trigSphere ) 
    InTrigCube1 = CheckEntityInTrig( cube, trigBox1 ) 
    InTrigCube2 = CheckEntityInTrig( cube, trigBox2 ) 
   
  RenderWorld 
   
  If InTrigSphere=True Then Text( 20, 20, "In Sphere!!!!" ) 
  If InTrigCube1=True Then Text( 20, 40, "In cube1 !!!!" ) 
  If InTrigCube2=True Then Text( 20, 60, "In cube2 !!!!" ) 
  Flip 
 Wend 

 End

вот листинг функций:
InitTrigger() - это инициализация системы, ее нужно ставить сразу после того как вы заинклудили исходник, то есть после строки: Include "TrigMain.bb" AddTrigSphere(debug=False, x#, y#, z#, radius#=1)
Функция создает триггер, который реагиурет на расстояние, то есть если предмет ближе чем радиус триггера, тогда он сработает. Параметры функции:
debug - нужно для визуальной отладки, если равна True, тогда на месте триггера создается сфера.
x, y, z - координаты триггера
radius - это радиус реагирования триггера
AddTrigBox(debug=False, x#, y#, z#, w#=1, h#=1, d#=1, Tip=TRIG_BOX1, pitch#=0, yaw#=0, roll#=0)
Функция создается триггер ввиде коробки( параллепипеда ). Бывает двух типов, но о них ниже. Параметры:
debug - также как и в предыдущей функции нужна для отладки. Создается бокс на месте триггера нужного размера.
x, y, z - указываем координаты триггера
w, h, d - размеры, ширина, высота и глубина соответственно.
Tip : - задаем тип бокса
TRIG_BOX1 - это самая простая и самая быстрая проверка, проверка на координаты.
TRIG_BOX2 - это прповерка учитывает ориентацию бокса, то есть он может быть повернут.
Если Tip равен TRIG_BOX2, тогда учитываются следующие параметры:
pitch, yaw, roll - углы поворота бокса
CheckEntityInTrig( ent, t.TriggerInfo )
Основная функция. Она проверяет нахождение объекта в заданном триггере, если это так, тогда возвращает True иначе False.
ent - объект, который нужно проверить на пересечение с триггером
t.TriggerInfo - триггер, с которым осуществляется проверка.
Вся система крайне быстрая( проверка на расстояние сделана по быстрому методу с уходом от квадратного корня ) и удобная в обращении. Чтобы создать триггер нужно сделать следующее:
Include "TrigMain.bb" ; подключаем систему
InitTrigger() ; инициализируем триггер
Global trig.triggerinfo ; создаем переменную под триггер
x=6 : y=0 : z=0
radius = 2
trig = AddTrigSphere(True, x,y,z, radius)
if CheckEntityInTrig( Entity, trig )=true then
;.... что делать если ентити внутри тригера
endif


Часовой пояс GMT +4, время: 12:53.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot