afxWeaponLight
by Gibby · 01/23/2014 (7:51 am) · 9 comments
Greets all, in response to Brian M's post here's my weapon light/sight effectron;
Create a new file, lights.cs or something to that effect, in your datablocks folder and be sure to add it to datablockExec.cs
Now in server/player.cs add this to the bottom of the file:
Next, in server/commands
finally, depending on whether you're using the Full template or afxDemo, change client/default.bind.cs or client/afx/default.bind_AFX.cs:
Note:
I rig my weapons with extra nodes light0 and light1. You'll need to do the same or use shape editor to add them. I then setup constraints for each node using afxXM_MountedImageNodeData, then a light using afxT3DSpotLightData. These are then enclosed within the corresponding afxEffectWrapperData and afxEffectronData. The scripts then simply launch/delete the effectron as needed.
Disfruten!
Create a new file, lights.cs or something to that effect, in your datablocks folder and be sure to add it to datablockExec.cs
//****************************************************************
// Gibby's Uber-Duper Weapon sight/Light script...
//****************************************************************
datablock afxXM_MountedImageNodeData(Weapon_MuzzlePoint_XM)
{
imageSlot = 0;
nodeName = "muzzlepoint";
};
datablock afxXM_MountedImageNodeData(Weapon_Light0_XM)
{
imageSlot = 0;
nodeName = "light0";
};
datablock afxXM_MountedImageNodeData(Weapon_Light1_XM)
{
imageSlot = 0;
nodeName = "light1";
};
datablock afxT3DSpotLightData(Weapon_WeaponLight_CE)
{
range = 40;
color = "1.0 1.0 1.0";
cookie = "art/gui/light.png";
flareType = "LightFlareExample1";
brightness = 3.0;
castShadows = false;
localRenderViz = false;
};
datablock afxT3DSpotLightData(Weapon_WeaponSight_CE)
{
range = "50";
innerAngle = 0;
outerAngle = 1;
brightness = "10";
color = "1 0 0 1"; // red?
cookie = "art/gui/laser.png"; // Basic Lighting will not render this.
// Lens Flare will need a good mount and will need the mountOffset of the Flashlight
// to be modified for your specific application.
flareType = "LightFlareExample2";
castShadows = false;
localRenderViz = false;
};
datablock afxEffectWrapperData(Weapon_MuzzleLight_EW)
{
effect = Weapon_WeaponLight_CE; // some effect to mount
constraint = "caster";
xfmModifiers[0] = Weapon_MuzzlePoint_XM;
};
datablock afxEffectWrapperData(Weapon_WeaponLight_EW)
{
effect = Weapon_WeaponLight_CE; // some effect to mount
constraint = "caster";
xfmModifiers[0] = Weapon_Light0_XM;
};
datablock afxEffectWrapperData(Weapon_MuzzleSight_EW)
{
effect = Weapon_WeaponSight_CE; // some effect to mount
constraint = "caster";
xfmModifiers[0] = Weapon_MuzzlePoint_XM;
};
datablock afxEffectWrapperData(Weapon_WeaponSight_EW)
{
effect = Weapon_WeaponSight_CE; // some effect to mount
constraint = "caster";
xfmModifiers[0] = Weapon_Light1_XM;
};
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
// Muzzle Spotlight EFFECTRON
//
datablock afxEffectronData(Weapon_MuzzleLight_Effectron)
{
echoPacketUsage = 20;
duration = -1;
numLoops = 1;
execOnNewClients = true;
// mine zodiacs //
addEffect = Weapon_MuzzleLight_EW;
};
datablock afxEffectronData(Weapon_WeaponLight_Effectron)
{
echoPacketUsage = 20;
duration = -1;
numLoops = 1;
execOnNewClients = true;
// mine zodiacs //
addEffect = Weapon_WeaponLight_EW;
};
datablock afxEffectronData(Weapon_WeaponSight_Effectron)
{
echoPacketUsage = 20;
duration = -1;
numLoops = 1;
execOnNewClients = true;
// mine zodiacs //
addEffect = Weapon_WeaponSight_EW;
};Now in server/player.cs add this to the bottom of the file:
//----------------------------------------------------------------------------
// Enable/Disable Player Weapon Lights
//----------------------------------------------------------------------------
function Player::MuzzleLightEnable(%this)
{
// delete existing lights
if(isObject(%this.light))
%this.light.interrupt();
echo("Player::MuzzleLightEnable -> CALLED BY: "@%this);
// spotlight
%effectron = new afxEffectron()
{
datablock = Weapon_MuzzleLight_Effectron;
};
%effectron.addConstraint(%this, "caster");
%this.light = %effectron;
}
function Player::MuzzleLightDisable(%this)
{
// delete lights
if(isObject(%this.light))
%this.light.interrupt();
}
function Player::WeaponLightEnable(%this)
{
// delete existing lights
if(isObject(%this.light))
%this.light.interrupt();
echo("Player::WeaponLightEnable -> CALLED BY: "@%this);
// spotlight
%effectron = new afxEffectron()
{
datablock = Weapon_WeaponLight_Effectron;
};
%effectron.addConstraint(%this, "caster");
%this.light = %effectron;
}
function Player::WeaponLightDisable(%this)
{
// delete lights
if(isObject(%this.light))
%this.light.interrupt();
}
function Player::WeaponSightEnable(%this)
{
// delete existing lights
if(isObject(%this.light))
%this.light.interrupt();
echo("Player::WeaponSightEnable -> CALLED BY: "@%this);
// spotSight
%effectron = new afxEffectron()
{
datablock = Weapon_WeaponSight_Effectron;
};
%effectron.addConstraint(%this, "caster");
%this.light = %effectron;
}
function Player::WeaponSightDisable(%this)
{
// delete lights
if(isObject(%this.light))
%this.light.interrupt();
}Next, in server/commands
//------------------------------------------------------------------------------
// Light Controls
//------------------------------------------------------------------------------
function serverCmdEnableMuzzleLight(%client)
{
%player = %client.player;
echo("serverCmdEnableMuzzleLight( -> CALLED BY: "@%client@" player: "@%player);
%player.MuzzleLightEnable();
}
function serverCmdDisableMuzzleLight(%client)
{
%player = %client.player;
%player.MuzzleLightDisable();
}
function serverCmdEnableWeaponLight(%client)
{
%player = %client.player;
echo("serverCmdEnableWeaponLight( -> CALLED BY: "@%client@" player: "@%player);
%player.WeaponLightEnable();
}
function serverCmdDisableWeaponLight(%client)
{
%player = %client.player;
%player.WeaponLightDisable();
}
function serverCmdEnableWeaponSight(%client)
{
%player = %client.player;
echo("serverCmdEnableWeaponSight( -> CALLED BY: "@%client@" player: "@%player);
%player.WeaponSightEnable();
}
function serverCmdDisableWeaponSight(%client)
{
%player = %client.player;
%player.WeaponSightDisable();
}finally, depending on whether you're using the Full template or afxDemo, change client/default.bind.cs or client/afx/default.bind_AFX.cs:
$MuzzleLightVar = "1";
function toggleMuzzleLight(%val)
{
if (%val)
{
if($MuzzleLightVar)
{
$MuzzleLightVar = "0";
commandToServer('EnableMuzzleLight');
}
else
{
$MuzzleLightVar = "1";
commandToServer('DisableMuzzleLight');
}
}
}
$WeaponLightVar = "1";
function toggleWeaponLight(%val)
{
if (%val)
{
if($WeaponLightVar)
{
$WeaponLightVar = "0";
commandToServer('EnableWeaponLight');
}
else
{
$WeaponLightVar = "1";
commandToServer('DisableWeaponLight');
}
}
}
$WeaponSightVar = "1";
function toggleWeaponSight(%val)
{
if (%val)
{
if($WeaponSightVar)
{
$WeaponSightVar = "0";
commandToServer('EnableWeaponSight');
}
else
{
$WeaponSightVar = "1";
commandToServer('DisableWeaponSight');
}
}
}
moveMap.bind( keyboard, "alt f", toggleMuzzleLight );
moveMap.bind( keyboard, "l", toggleWeaponLight );
moveMap.bind( keyboard, "alt l", toggleWeaponSight );Note:
I rig my weapons with extra nodes light0 and light1. You'll need to do the same or use shape editor to add them. I then setup constraints for each node using afxXM_MountedImageNodeData, then a light using afxT3DSpotLightData. These are then enclosed within the corresponding afxEffectWrapperData and afxEffectronData. The scripts then simply launch/delete the effectron as needed.
Disfruten!
#2
Thanks so much, this is perfect!
Renders great in the Oculus Rift too, we're going to use the laser sight as a sort of selection cursor for selectable objects in the world... Can't use a normal 2D mouse cursor with the Rift so have to come up with creative solutions for user input :)
Will work on fine tuning the laser sight and post any solutions we find.
Cheers
01/23/2014 (10:34 am)
Confirmed as working great in AFX 2.0 with T3D MIT 3.0Thanks so much, this is perfect!
Renders great in the Oculus Rift too, we're going to use the laser sight as a sort of selection cursor for selectable objects in the world... Can't use a normal 2D mouse cursor with the Rift so have to come up with creative solutions for user input :)
Will work on fine tuning the laser sight and post any solutions we find.
Cheers
#3
01/23/2014 (3:27 pm)
Great to see a possible solution for you Brian :)
#4
"TGEA - Select objects with FPS HUD with Arcane FX"
http://www.garagegames.com/community/resources/view/18183
I seem to recall it working with T3D 3.0 without any issues...
01/23/2014 (9:36 pm)
@Brian: I found this resource useful:"TGEA - Select objects with FPS HUD with Arcane FX"
http://www.garagegames.com/community/resources/view/18183
I seem to recall it working with T3D 3.0 without any issues...
#5
Does exactly what we figured out already, but in a different way - we just piggybacked off the Awesomium raycast, checking for selectable objects at the same time as we check for Awesomium web shapes.
If a player is looking at a selectable object, then in the background it sets that as the AFX preselected object. Then when you right-click, it actions whatever object has been preselected.
If you are not using the Oculus Rift, then the AFX highlighting works when looking at an object, as well as when you mouse over it in standard AFX gui mode. When using the Rift, we disable the AFX highlight because it does not stereo render correctly.
So, in this case we are already there... But for anyone who doesn't have Awesomium integrated, that solution would certainly achieve the same result, good find!
01/27/2014 (7:31 am)
@Gibby: Thanks for that, never seen that one before... Does exactly what we figured out already, but in a different way - we just piggybacked off the Awesomium raycast, checking for selectable objects at the same time as we check for Awesomium web shapes.
If a player is looking at a selectable object, then in the background it sets that as the AFX preselected object. Then when you right-click, it actions whatever object has been preselected.
If you are not using the Oculus Rift, then the AFX highlighting works when looking at an object, as well as when you mouse over it in standard AFX gui mode. When using the Rift, we disable the AFX highlight because it does not stereo render correctly.
So, in this case we are already there... But for anyone who doesn't have Awesomium integrated, that solution would certainly achieve the same result, good find!
#6
All we did was open our weapons in the shape editor, and move the light-mount nodes up and to the left, until they line up with the player's eye.
Makes for a dead-on accurate laser sight, that when using the Rift can pinpoint even the tiniest of clickable buttons even if there are several close together. Then right-click on what the laser is pointing at and it performs the selection just as if you'd clicked with the mouse in non-Rift mode.
Not sure if this is portable code or not, may be specific to our weapons, but these co-ordinates worked on all of our weapons to get the laser sight centered in the crosshair.
In art/shapes/weapons/Phaser (substitute your weapon folder name), there is a .cs file corresponding to the weapon shape, in our case this is Phaser.cs... Here are the contents after adding and moving the light nodes:
singleton TSShapeConstructor(PhaserDts)
{
baseShape = "./Phaser.dts";
};
function PhaserDts::onLoad(%this)
{
%this.setNodeTransform("light0", "-0.452485 0.617027 0.500264 1 0 0 0", "1");
%this.addNode("light1", "", "-0.452485 0.617027 0.500264 1 0 0 0", "1");
}
Moving existing nodes in the Shape editor does not alter the original model, and in fact the original model does not even need the extra node points on it, they will be added on the fly with this script.
Anyhow, give it a shot if you like, see if it works for you.
Cheers
01/27/2014 (7:38 am)
Oh, and FYI, here is a quick and dirty hack to get the laser pointer to match the center of the crosshair.All we did was open our weapons in the shape editor, and move the light-mount nodes up and to the left, until they line up with the player's eye.
Makes for a dead-on accurate laser sight, that when using the Rift can pinpoint even the tiniest of clickable buttons even if there are several close together. Then right-click on what the laser is pointing at and it performs the selection just as if you'd clicked with the mouse in non-Rift mode.
Not sure if this is portable code or not, may be specific to our weapons, but these co-ordinates worked on all of our weapons to get the laser sight centered in the crosshair.
In art/shapes/weapons/Phaser (substitute your weapon folder name), there is a .cs file corresponding to the weapon shape, in our case this is Phaser.cs... Here are the contents after adding and moving the light nodes:
singleton TSShapeConstructor(PhaserDts)
{
baseShape = "./Phaser.dts";
};
function PhaserDts::onLoad(%this)
{
%this.setNodeTransform("light0", "-0.452485 0.617027 0.500264 1 0 0 0", "1");
%this.addNode("light1", "", "-0.452485 0.617027 0.500264 1 0 0 0", "1");
}
Moving existing nodes in the Shape editor does not alter the original model, and in fact the original model does not even need the extra node points on it, they will be added on the fly with this script.
Anyhow, give it a shot if you like, see if it works for you.
Cheers
#7
I think you can also implement the offset with afx - I'll try this and post the result...
01/27/2014 (8:53 am)
@Brian:I think you can also implement the offset with afx - I'll try this and post the result...
#8
01/27/2014 (8:42 pm)
Thank you for posting this, very helpful to me for even unrelated areas.
#9
02/18/2014 (9:54 am)
awesome,good post~~ 
Torque Owner Gibby
faderboy digital media
I setup a default in my game where the sight/light uses the muzzlepoint in case it wasn't rigged for nodes for the lights.
Note that the laser sight is a bit off from the crosshair. I'm using this in a TPS so I've not dealt with the math to fix this issue, if anyone resolves it please share...