ShapeBaseImage for Firing
by Xavier "eXoDuS" Amado · in Torque Game Engine · 07/01/2002 (2:17 pm) · 20 replies
Hey, why is it that the only way to fire is to have a shapeBaseImage mounted on the object?
For example, a player to fire needs a weapon mounted, a vehicle to fire needs a weapon mounted... and in my case my turret needs a weapon mounted :(
Which sounds very silly, how where the turrets in tribes2 made? did they have a mounted shapeBaseImage?
Anyone knows of a way to do this without having to mount a shapeBaseImage on my turret?
For example, a player to fire needs a weapon mounted, a vehicle to fire needs a weapon mounted... and in my case my turret needs a weapon mounted :(
Which sounds very silly, how where the turrets in tribes2 made? did they have a mounted shapeBaseImage?
Anyone knows of a way to do this without having to mount a shapeBaseImage on my turret?
About the author
#2
07/01/2002 (6:08 pm)
that's so nasty! rendering the same model twice on the screen... bah... guess i'll have to do it that way or code a way to shoot without a shapeImage... mmm...
#3
A turret's image was literally TurretImageData which I believe was simply a derivation of ShapeBaseImageData with a couple extra datablock values for yaw/pitch speeds and accuracy (set in its own datablock for efficiency's sake so you don't send irrelevant data on non turret images).
Remember how T2 had different barrels which could be mounted on a turret? That's what the images were for. It's an incredibly smart way to do it, you don't render the same object twice you simply break the original one off into multiple pieces. The barrel is always the mounted image while the turret object is the mechanical part of the turret. You could have a turret which cycles through weapons like a player if you wanted. I really think this is quite intuitive (very consistent with the weapons too), and it makes for some interesting scenarios: You could have a player walk up to a turret and unload the barrel and run off with it as a weapon.
07/01/2002 (6:58 pm)
The outdoor deployable turret image you see there is a pack :)A turret's image was literally TurretImageData which I believe was simply a derivation of ShapeBaseImageData with a couple extra datablock values for yaw/pitch speeds and accuracy (set in its own datablock for efficiency's sake so you don't send irrelevant data on non turret images).
Remember how T2 had different barrels which could be mounted on a turret? That's what the images were for. It's an incredibly smart way to do it, you don't render the same object twice you simply break the original one off into multiple pieces. The barrel is always the mounted image while the turret object is the mechanical part of the turret. You could have a turret which cycles through weapons like a player if you wanted. I really think this is quite intuitive (very consistent with the weapons too), and it makes for some interesting scenarios: You could have a player walk up to a turret and unload the barrel and run off with it as a weapon.
#4
07/02/2002 (1:24 am)
The big advantage of the ShapeBaseImage is that you get the state machine for free. So why don't use it? Otherwise you have to code that yourself.
#5
And then the turret itself where the player sits down in it or whatever....
mmm... how would I mount the barrel on my turret object?
07/02/2002 (8:01 am)
mmm.... so i basically model the barrel of the turret in one separate model?And then the turret itself where the player sits down in it or whatever....
mmm... how would I mount the barrel on my turret object?
#6
You mount objects to other objects via:
object.mountObject(otherobject, mountpoint); //mounts otherobject onto object on the specified mountpoint number, you'd use this to mount your player to the turret
object.mountImage(barrel, imageslot); //essentially same thing but this mounts an image, not an object (checkout shapeimage.cc to see what the difference is, images are just datablocks) onto a certain mountpoint, referred to as imageslot...you'd use this to mount the barrel
07/02/2002 (8:29 am)
You could actually make a seat which is built onto the turret part which yaws and mount your player onto it.You mount objects to other objects via:
object.mountObject(otherobject, mountpoint); //mounts otherobject onto object on the specified mountpoint number, you'd use this to mount your player to the turret
object.mountImage(barrel, imageslot); //essentially same thing but this mounts an image, not an object (checkout shapeimage.cc to see what the difference is, images are just datablocks) onto a certain mountpoint, referred to as imageslot...you'd use this to mount the barrel
#7
Thanks!
07/02/2002 (11:10 am)
Could you try to explain a bit more about ShapeBaseImage ? why is it only a datablock like you say?Thanks!
#8
ShapeBaseImageData in itself is much like anyother datablock class defined the engine (and instantiated in scripts the same way too).
Instead of being an entire object (it doesn't process ticks, or interpolate, moves, insert render images, and so forth) it only handles timed/triggered states. So in itself it really is a "datablock" as it just holds data for the ShapeBase class (and it's derivatives, your turret would probably be an example as players are).
When you tell a ShapeBase object to mount an image to a certain slot it will add it into the mMountedImageList array (member of ShapeBase) referencing the image's datablock. I believe the index of that array is equivalent to the slot number. A slot isn't necessarily equivalent to a mountpoint on the ShapeBase object (you define that in the ShapeBaseImage datablock). The mountpoint is the node which will be used as the image's shape's origin when rendered. For example a player has a mount0 (that's the node's name in the dts shape) on it's hand. If you want to mount a weapon to that hand, you would set the mountpoint in the weapon's datablock to 0.
Also, triggers are relative to slots. Right now, for the player, only the first two triggers are used and they only trigger slots 0 and 1.
If you check out how ShapeBase renders, it'll render it's own image (ie: a player) and then render all the mounted ones (ie: packs, weapons, even body parts...).
Images have a variety of other little functions like correcting the muzzle vector (which is on the muzzle node on the image's shape transformed relative the player/object's mountpoint plus image defined offset) with the eye vector (so you shoot smack on the reticle). In first person you can give them any offset you like, provided the shapebase object isn't set to render in first person otherwise it'll be relative to the mountpoint. I personally always use the mountpoint so you can see the weapon bob with the player as it breathes and animates.
So here's how it all plays out in script:
So now, this image will render relative to mountPoint 0 (attached to) with no extra offset. So the origin of mountPoint 0 will line up with that of the image shape (unless you define a mountPoint on the image shape, it should then use that instead of the origin).
To mount it to an object you would do:
object.mountImage(RifleImage, slot);
If you want it to be triggered by your script bound mouse fire key, it must be on slot 0. There are a max of 8 slots on an object and 6 triggers.
To remove it, either mount another image over the same slot or:
object.unMountImage(slot);
The images all throw script side callbacks like
And you can define your own callbacks in the scripted image states (onFire being one).
Another thing to note is that even though an image can be mounted on multiple players, you will always have only one shape instance for the image and that's in the image datablock.
I hope I haven't confused you more :)
//Edit: terrible grammar
07/02/2002 (7:28 pm)
Sure. I'm not a very good teacher but I'll do my best (I tend to ramble).ShapeBaseImageData in itself is much like anyother datablock class defined the engine (and instantiated in scripts the same way too).
Instead of being an entire object (it doesn't process ticks, or interpolate, moves, insert render images, and so forth) it only handles timed/triggered states. So in itself it really is a "datablock" as it just holds data for the ShapeBase class (and it's derivatives, your turret would probably be an example as players are).
When you tell a ShapeBase object to mount an image to a certain slot it will add it into the mMountedImageList array (member of ShapeBase) referencing the image's datablock. I believe the index of that array is equivalent to the slot number. A slot isn't necessarily equivalent to a mountpoint on the ShapeBase object (you define that in the ShapeBaseImage datablock). The mountpoint is the node which will be used as the image's shape's origin when rendered. For example a player has a mount0 (that's the node's name in the dts shape) on it's hand. If you want to mount a weapon to that hand, you would set the mountpoint in the weapon's datablock to 0.
Also, triggers are relative to slots. Right now, for the player, only the first two triggers are used and they only trigger slots 0 and 1.
//
//... in player.cc Player::updateMove(...)
setImageTriggerState(0,move->trigger[0]);
setImageTriggerState(1,move->trigger[1]);
//...If you check out how ShapeBase renders, it'll render it's own image (ie: a player) and then render all the mounted ones (ie: packs, weapons, even body parts...).
Images have a variety of other little functions like correcting the muzzle vector (which is on the muzzle node on the image's shape transformed relative the player/object's mountpoint plus image defined offset) with the eye vector (so you shoot smack on the reticle). In first person you can give them any offset you like, provided the shapebase object isn't set to render in first person otherwise it'll be relative to the mountpoint. I personally always use the mountpoint so you can see the weapon bob with the player as it breathes and animates.
So here's how it all plays out in script:
datablock ShapeBaseImageData(RifleImage)
{
// the shape and rendering settings
shapeFile = "~/data/shapes/rifle/weapon.dts";
emap = true;
// mountPoint is the mount# on the objects
// this will mount to
mountPoint = 0;
// offset is any extra displacement you want
// to add to the mountPoint's, for tweeking
// image position
offset = "0 0 0";
// offset used when in first person
eyeOffset = "0.1 0.2 -0.55";
// this will correct the muzzle vector to point
// towards the same imaginary point on the horizon
// as your eye vector in first person
correctMuzzleVector = true;
// Projectile && Ammo.
// now the projectile data is actually stored here
// engine side, keep a note of that so you define
// your projectiles before this image
// you may want this if you want your turret to
// estimate ahead of a moving target object...
// if you do you'll need the projectile's velocity
// and like this you'll be able to claim it engine
// side
projectile = RifleProjectile;
// script use variables removed for brevity
// image states removed for brevity
};So now, this image will render relative to mountPoint 0 (attached to) with no extra offset. So the origin of mountPoint 0 will line up with that of the image shape (unless you define a mountPoint on the image shape, it should then use that instead of the origin).
To mount it to an object you would do:
object.mountImage(RifleImage, slot);
If you want it to be triggered by your script bound mouse fire key, it must be on slot 0. There are a max of 8 slots on an object and 6 triggers.
To remove it, either mount another image over the same slot or:
object.unMountImage(slot);
The images all throw script side callbacks like
RifleImage::onmountImage(%slot); RifleImage::onUnmountImage(%slot);
And you can define your own callbacks in the scripted image states (onFire being one).
Another thing to note is that even though an image can be mounted on multiple players, you will always have only one shape instance for the image and that's in the image datablock.
I hope I haven't confused you more :)
//Edit: terrible grammar
#9
Anyway, after reading all your explanation i re-checked my code and it seems to be the way you explain, but still when I click my mounted ShapeBaseImage isn't being fired, not even the onFire script function from the image is being called.
Maybe i'm missing something? I tried to copy the code from Vehicles and Players for the processTick and updateMove functions... the script function onTrigger from the shape (TurretObject) does work and get's called when I click, but the shapeBaseImage doesn't seem to get a clue about the click...
Thanks for your help.
07/03/2002 (8:45 am)
Wow, that is a great explanation luigi, thanks a lot, i knew some of the stuff already, but hearing it from someone else makes me be sure about them :)Anyway, after reading all your explanation i re-checked my code and it seems to be the way you explain, but still when I click my mounted ShapeBaseImage isn't being fired, not even the onFire script function from the image is being called.
Maybe i'm missing something? I tried to copy the code from Vehicles and Players for the processTick and updateMove functions... the script function onTrigger from the shape (TurretObject) does work and get's called when I click, but the shapeBaseImage doesn't seem to get a clue about the click...
Thanks for your help.
#10
object.setImageTrigger(slot, true/false);
so it'd be:
%turret.setImageTrigger(0, true);
You'd set it to false to stop firing.
This simply triggers the current state, provided it has an onTriggerDown event.
See if that does it :)
07/03/2002 (6:11 pm)
If onTrigger works then try using this (script side):object.setImageTrigger(slot, true/false);
so it'd be:
%turret.setImageTrigger(0, true);
You'd set it to false to stop firing.
This simply triggers the current state, provided it has an onTriggerDown event.
See if that does it :)
#11
07/03/2002 (7:25 pm)
Unknown command setImageTrigger on SimObject... :\
#12
For example if I wanted to set off my gun this way I'd do:
%player.setImageTrigger(0, true);
07/03/2002 (7:42 pm)
You have to call it for the object on which the image is mounted.For example if I wanted to set off my gun this way I'd do:
%player.setImageTrigger(0, true);
#13
07/03/2002 (8:03 pm)
It's a ShapeBase member function, if your turret is a derivate of ShapeBase you should have no problems...
#14
silly me :)
07/04/2002 (9:00 am)
Argh, i was calling this on the datablock, not in the object :\silly me :)
#15
It isn't firing
07/04/2002 (9:17 am)
Well, i changed it to the object but it still doesnt work :\It isn't firing
#16
Use echo(turret.getImageState(slot)); in the console to see what the state is. If it's always on your first state then it's not initiating the states at all. Try replacing your image with just a normal weapon one which you know for sure works.
Also make sure all the inventory settings are correct (like you have enough ammo or energy to fire).
07/04/2002 (9:20 am)
There may be a mistake in your scripted states for the image.Use echo(turret.getImageState(slot)); in the console to see what the state is. If it's always on your first state then it's not initiating the states at all. Try replacing your image with just a normal weapon one which you know for sure works.
Also make sure all the inventory settings are correct (like you have enough ammo or energy to fire).
#17
07/04/2002 (10:26 am)
I just remembered that the internal shapeBaseImage does a check to see if there's enough ammo too... at first i was thinking the only check was the on in onFire... which isn't right.. so the problem IS the ammunition... how would you set the ammo for a turret object? i mean, the player doesn't have to have the ammunition, the turret has to...
#18
I'd probably make the turret use energy.
07/04/2002 (7:18 pm)
There's a state event called stateTransitionOnNoAmmo which will evaluate to a another state event. You could either directly set that to Fire/Activate or whatever the state event is for stateTransitionOnLoaded in the same state. I'd probably make the turret use energy.
#19
07/05/2002 (9:14 am)
So there's no way to assign an ammunition amount to the turret? I guess that to do that I would need to give the turret and inventory right?
#20
%turret.setInventory(ammo, amount);
07/06/2002 (5:26 pm)
You'd simply set it to use a certain type of ammo (in the image datablock) and then give the turret some of that ammo.%turret.setInventory(ammo, amount);
Torque 3D Owner Robert Blanchet Jr.
They used the same dts file for both however.
Here is an example of one of the turrets in Tribes 2:
datablock ShapeBaseImageData(TurretOutdoorDeployableImage) { mass = 15; shapeFile = "pack_deploy_turreto.dts"; item = TurretOutdoorDeployable; mountPoint = 1; offset = "0 0 0"; deployed = TurretDeployedOutdoor; stateName[0] = "Idle"; stateTransitionOnTriggerDown[0] = "Activate"; stateName[1] = "Activate"; stateScript[1] = "onActivate"; stateTransitionOnTriggerUp[1] = "Idle"; maxDamage = 4.5; destroyedLevel = 4.5; disabledLevel = 4.0; isLarge = true; emap = true; maxDepSlope = 40; deploySound = TurretDeploySound; minDeployDis = 0.5; maxDeployDis = 5.0; //meters from body }; datablock ItemData(TurretOutdoorDeployable) { className = Pack; catagory = "Deployables"; shapeFile = "pack_deploy_turreto.dts"; mass = 3.0; elasticity = 0.2; friction = 0.6; pickupRadius = 1; rotate = false; image = "TurretOutdoorDeployableImage"; pickUpName = "a landspike turret pack"; computeCRC = true; emap = true; };