Author Topic: Glue an object to another  (Read 3616 times)

Offline nabz32

  • Community Developer
  • Dr. Type
  • ******
  • Posts: 307
    • View Profile
Glue an object to another
« on: 2015-Jun-10 »
Hello,

If you want to glue an object to another one, here is a nice code snipped for you:

Code: GLBasic [Select]
// --------------------------------- //
// Project: genericGlue
// Start: Wednesday, June 10, 2015
// IDE Version: 12.312

TYPE vec3D
        x#
        y#
        z#
ENDTYPE

TYPE object
        objID% // could store a previously loaded objects ID
        x#
        y#
        z#
        anX#
        anY#
        anZ#
        glueDist#
        glueInit%
        rootGlueObjAnY#
        myOldAny#
        glueObjAnY#
        glueObject%
ENDTYPE

GLOBAL Objects[] AS object

main()


FUNCTION main:
        LOCAL ObjectMax% , finished%
        ObjectMax = 10 ; finished = 0
        DIM Objects[ObjectMax]
        // create some objects
        WHILE finished = 0
                // you could change glueDist and glueObjAnY before the calculateglue() call for relative movements
                calculateGlue()
                // draw those objects here
        WEND
ENDFUNCTION

FUNCTION calculateGlue:
        LOCAL rotate AS vec3D
        FOR i = 0 TO ObjectMax - 1 // parse through all objects
                IF Objects[i].glueInit = 0 AND Objects[i].glueObject > -1 // initialise gluing
                        // get glue Dist by using pythagoras on the x and z difference between object A and object B
                        Objects[i].glueDist = SQR( ( POW( ( Objects[i].x - Objects[Objects[i].glueObject].x ) , 2 ) + POW( ( Objects[i].z - Objects[Objects[i].glueObject].z ) , 2 ) ) )
                        // get the original Y Angle of the object where object A is glued to ( of object B )
                        Objects[i].rootGlueObjAnY = Objects[Objects[i].glueObject].anY
                        // save the original Y Angle of tobject A
                        Objects[i].myOldAnY = Objects[i].anY
                        // get the Y Angle between Object A and Object B
                        Objects[i].GlueObjAnY = 360 - ( ATAN( ( Objects[i].z - Objects[Objects[i].glueObject].z ) , ( Objects[i].x - Objects[Objects[i].glueObject].x ) ) + 180 )
                        // get the Y difference between object A and object B
                        Objects[i].yDistRoot = Objects[i].y - Objects[Objects[i].linkEvent].y
                        // set glue initialisation variable
                        Objects[i].glueInit = 1
                ENDIF
                IF Objects[i].glueInit > 0 AND Objects[i].glueObject > -1 // calculate coordinates for a glueing initialised object
                        // calculate a vector which originates in ( 0 , 0 , 0 ) and has the Objects new X and Z positions as endcoordinates
                        rotate.x = Objects[i].glueDist * COS( 360 - ( Objects[i].glueObjAnY - ( Objects[i].rootGlueObjAnY - Objects[ Objects[i].glueObject].anY ) ) )
                        rotate.z = Objects[i].glueDist * SIN( 360 - ( Objects[i].glueObjAnY - ( Objects[i].rootGlueObjAnY - Objects[ Objects[i].glueObject].anY ) ) )
                        rotate.y = Objects[i].yDistRoot
                        // rotate the vector, which is stored as rotate ( the call order is important here )
                        RotateCoordAroundOrigin( 0 , 360 - ( Objects[ Objects[i].glueObject].anY + 180 ) , 0 , rotate )
                        RotateCoordAroundOrigin( 360 - ( Objects[ Objects[i].glueObject].anZ + 180 ) , 0 , 0 , rotate )
                        RotateCoordAroundOrigin( 0 , 0 , 360 - ( Objects[ Objects[i].glueObject].anX + 180 ) , rotate )
                        // add the rotated vector to the real origin ( the real origin is at the coordinates of object B )
                        Objects[i].x = Objects[Objects[i].glueObject].x + rotate.x
                        Objects[i].z = Objects[Objects[i].glueObject].z + rotate.z
                        Objects[i].y = Objects[Objects[i].glueObject].y + rotate.y
                        // finally also change X and Z angles of the object
                        Objects[i].anY = Events[eNr].myOldAnY - ( Events[eNr].rootGlueObjAnY - Events[Events[eNr].glueObject].anY )
                        Objects[i].anX = Events[Events[eNr].glueObject].anX
                        Objects[i].anZ = Events[Events[eNr].glueObject].anZ
                ENDIF
        NEXT
ENDFUNCTION

FUNCTION RotateCoordAroundOrigin: rotx# , roty# , rotz# , point AS coord // point is called by reference
        LOCAL result AS vec3D
        result = point
        IF rotx > 0
                result.y = point.y * COS(rotx) - point.z * SIN(rotx) ; result.z = point.y * SIN(rotx) + point.z * COS(rotx)
        ENDIF
        IF roty > 0
                result.x = point.x * COS(roty) + point.z * SIN(roty) ; result.z = point.x * SIN(roty) + point.z * COS(roty)
        ENDIF
        IF rotz > 0
                result.x = point.x * COS(rotz) - point.y * SIN(rotz) ; result.y = point.x * SIN(rotz) + point.y * COS(rotz)
        ENDIF
        point = result
ENDFUNCTION
 

With the Object will always stay in the same position and angle to the object it has been glued onto,
no matter how the object which "carries" the glued object turns.

I used this to glue my event objects together, to make even more interesting Bossfights and it works nicely.
You just need to preload 2 objects and set the variable glueInit to 1 and the calculate glue function will do the rest.
Of course you will also need to draw those objects using the information stored in the object type,
if you want some visible results.

You can also change the glueDist and glueObjAnY Variables over time, to make one Object orbit the other one or do other cool
stuff with it.


« Last Edit: 2015-Jun-10 by nabz32 »

Offline Schranz0r

  • Premium User :)
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 5014
  • O Rly?
    • View Profile
Re: Glue an object to another
« Reply #1 on: 2015-Jun-11 »
It's called Parenting and Child setting :D
I <3 DGArray's :D

PC:
AMD RYzen 7 1700 @3.9Ghz, 16GB HyperX Fury 2666Mhz Ram, ASUS ROG GTX 1060 STRIX 6GB, Windows 10 Pro 64Bit, MSi Tomahawk B350 Mainboard

Offline nabz32

  • Community Developer
  • Dr. Type
  • ******
  • Posts: 307
    • View Profile
Re: Glue an object to another
« Reply #2 on: 2015-Jun-11 »
In dbpro its called glue object

Offline kanonet

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1142
    • View Profile
    • My GLBasic code archiv
Re: Glue an object to another
« Reply #3 on: 2015-Jun-11 »
Wouldn't it be easier to just use X_PUSHMATRIX+X_POPMATRIX? And of cause every Enity System can do this too (Schranz0r named it). But of cause, well done, still.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Offline mentalthink

  • Prof. Inline
  • *****
  • Posts: 3366
  • Integrated Brain
    • View Profile
Re: Glue an object to another
« Reply #4 on: 2015-Jun-11 »
I'm not sure guys but I think in the 3Demos comes an example similar ins't?¿, I think appears some torus and boxes turning around itself.

Offline erico

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 4186
    • View Profile
    • Portfolio
Re: Glue an object to another
« Reply #5 on: 2015-Jun-11 »
It's called Parenting and Child setting :D
In dbpro its called glue object

You guys are all wrong...
the proper name is "3 dimensional silver taping". :P

Code looks interesting, bookmarked for when I get to 3d.
Thanks for sharing.

Offline nabz32

  • Community Developer
  • Dr. Type
  • ******
  • Posts: 307
    • View Profile
Re: Glue an object to another
« Reply #6 on: 2015-Jun-12 »
Well good to know, that GLBasic supports matrix tranformations. :-[
It is very nice to have many events glued to another one, i.E. for different scripts for every weapon system of a boss.

I have even made one who has blinking buttons on the back, after some time one of those starts to blink green,
then you have to jump on that and another will turn green, hit all in one combo jump in the right order for a real hit on the boss.