Показать сообщение отдельно
Старый 05.03.2010, 13:29   #14
H@NON
Дэвелопер
 
Регистрация: 17.01.2007
Сообщений: 1,552
Написано 351 полезных сообщений
(для 774 пользователей)
Ответ: Коллизия без метода? Это возможно?

Юзай мою систему триггеров :
;============================  
 ;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
(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо H@NON за это полезное сообщение:
IGR (05.03.2010), Nex (08.03.2010), Reks888 (05.03.2010), tormoz (05.03.2010)