Projective Textures and Decals
From NeoAxis Engine Wiki
Work in progress
Please add any reference material you know about here, just a link a short description or whatever you can manage
- At the end for example, under Suggestions
Background
- Many people seem to want selector rings which are on the ground around a unit for their projects/games.
- I want them (mrexcessive)
- However, it is not sufficient
- to use a light linked to a unit and projecting downwards because it will be shadowed by the unit and also light the unit from above
- to create a billboard because even if it is aligned with its normal parallel to the terrain normal at the unit's position it will still potentially be cut off under local terrain changes and not be displayed on ingame objects e.g. steps
- to create something purely on the terrain, because of e.g. steps
- it may not be easy... all input welcome, this means You!
Reference material
Forum threads
- How to create a game effect like this using NeoAxis
- http://www.neoaxisgroup.com/phpBB2/viewtopic.php?p=18876
- This includes some examples from other engines/games of ideal (for me) projected decal rings/burning fire rings etc. around units including wrapping from steps onto terrain
- HardwarePixelBuffer Usage Tutorials with Manual Plane
- http://www.neoaxisgroup.com/phpBB2/viewtopic.php?t=2603
- I think this is relevant ;-) from my position of limited understanding
- Moving Decals
- http://www.neoaxisgroup.com/phpBB2/viewtopic.php?t=1715
- Has a useable workaround using particles (not projective)
- Betauser says (in the forum)
- Decals can't moving in realtime. Decals is always static.
- Better way to create a new special type for your task.
- You need create entity with dynamic geometry.
- As example of making dynamic geometry you can see decals source code and yellow blinking panel (See panel above mirror in the RenderDemo).
- Does anyone understand how to do these things... I (mrexcessive) looked at the blink panel code (GameEntities/BlinkGrid.cs, I think) but don't claim to understand it yet.
Other wiki pages
Websites (external to NeoAxis)
- The OGRE3D intermediate tutorial 6 - which seems to be
- a) exactly what we want, or close to it
- b) using OGRE (which underlies NeoAxis) so it should be possible
- If someone can describe or indeed complete a NeoAxis version of the essence of this tutorial, then, well, they'll be at least worthy of a big High Five!
Step zero: How to create a decal projection without firing a bullet
Decals are normally created when a bullet hits something
- The code in GameEntities/DecalCreator.cs is normally invoked by a chain of events
- A Bullet.cs collides with something and 'dies'
- Dynamic.cs contains code which creates the objects listed in the type
- For example if you look in SDK\Game\Bin\Data\Types\Bullets\ShotgunBullet\ShotgunBullet.type
you will find
dieObjects
{
particle
{
particleName = ShotgunBulletHitParticle
}
sound
{
soundName = Types/Bullets/ShotgunBullet/Die.ogg
volume = 0.5
}
mapObject
{
type = DefaultBulletDecalCreator
}
}
However, we don't want to fire bullets at players feet to create selection markers...
- So we need another way to invoke a DecalCreator (we are experimenting with Decals as they exist already for now
I created some 'naive' code to do this... and failed miserably until I asked in the forums
See http://www.neoaxisgroup.com/phpBB2/viewtopic.php?t=2831 to follow our discussion
After considerable encouragement, and a lot of help from Wellu, we have the following starting point created by him :
- This post is on page 3 of the forum conversation just above the large 'decals_on_group.JPG' picture, posted by Wellu.
- The code as it stands here needs to be put into the Game project source code file ActionGameWindow.cs into the OnKeyDown event handler (at approximately line 151, just after the closing } from the block dealing with F7
//decal practise in "protected override bool OnKeyDown(KeyEvent e)"
if (e.Key == EKeys.O) //key "o" was pressed
{
//create a DecalCreator from the DefaultBulletDecalCreator.type
DecalCreator dc = Entities.Instance.Create(EntityTypes.Instance.GetByName("ZombieBulletDecalCreator"), Map.Instance) as DecalCreator;
if (dc != null) // it went ok
{
//this DecalCreator creates directional decals as it is set to do so in the .type
//this means decals appear on StaticMesh located in DecalCreators position
//it shoots a Ray to it's own direction to find the spot for decals. You can see this in DecalCreator.cs -> CreateDecals()
//create decals in same direction my character points at
dc.Rotation = GetPlayerUnit().Rotation;
//set location to player for now
dc.Position = GetPlayerUnit().Position;
//get the Ray from Unit.Position downwards at least as long as CharacterType.Height
Character chr = GetPlayerUnit() as Character;
float height = chr.Type.Height;
Ray floorLocator = new Ray(GetPlayerUnit().Position, new Vec3(0, 0, -height * 1.5f));
//get the piercing results if the ray hit a anything. This time it's piercing so many results!!!
RayCastResult[] results = PhysicsWorld.Instance.RayCastPiercing(floorLocator, (int)ContactGroup.CastAll);
foreach(RayCastResult res in results)
{
//if it's the unit self continue
Body body = res.Shape.Body;
if (MapSystemWorld.GetMapObjectByBody(body) == GetPlayerUnit()) continue;
//we hit something else. Ask DecalCreator to create Decals on that location
dc.Position = res.Position; //DecalCreator.cs has logic to create decals at this location
//let's put this baby on the map and it will die when it's LifeTime goes to zero
dc.PostCreate();
//Let's create only on one place so break here
break;
}
}
}
- When you press the "O" key then zombievomit (no really) will appear under your feet. Select the third-person camera and walk along pressing O... a trail of splats
- Now obviously the behaviour of the zombievomit is not appropriate for a selection ring, there's the smell apart from anything else.
- So Next we will try this code out with our new SelectionRingCreator class
Step one: Adding a SelectionRing and SelectionRingManager class to your application
Step by step in Visual Studio (2008)
- Create the two new classes in GameEntities
- right click on GameEntities, Add, Code File and type in name SelectionRing.cs and then SelectionRingManager.cs
- I have uploaded a new version (01mar09A) of the SelectionRing.cs and SelectionRingManager.cs (http://www.neoaxisgroup.com/phpBB2/download.php?id=751)
- These belong in the SDK\Game\Src\GameEntities directory, then build GameEntities
A selection ring highmaterial
- This is simple and _very_ programmer art - so improvements from someone with art talents would be gratefully received and credited of course, download http://www.neoaxisgroup.com/phpBB2/download.php?id=752 and add this to the SDK\Game\Bin\Data\Types directory
- All that remains is to modify ActionGameWindow.cs so that it invokes the new class SelectionRing
Of course I will get this working directly from the logic editor - I think that will not be too hard now
- Add this after the check for EKeys.F7
else if (e.Key == EKeys.O) // press "O" for SelectionRing
{
//create a SelectionRingCreator from the SimpleSelectionRingCreator.type
Unit unitPlayer = GetPlayerUnit() as Unit;
SelectionRingManager.AttachSelectionRingTo(unitPlayer);
}
else if (e.Key == EKeys.P) // press "P" to remove SelectionRing
{
Unit unitPlayer = GetPlayerUnit() as Unit;
SelectionRingManager.RemoveSelectionRingsFrom(unitPlayer);
}
- Start the game.
- When you press O a selection ring appears under your feet, view in third person camera (F7) to see clearly, but can just look down at your feet
- Move around
- Press P to hide it
Step two: How to create a simple projection which follows a new type of unit entity
Requirements
- How we might isolate gameplay elements (such as timeouts on heals etc.) from the core functionality (projecting a coloured ring, changing the colour, hiding it again, not filling up all space with coloured rings... etc. etc.)
- It is starting to look as though some of these requirements have been satisfied by the previous step... a refactoring of SelectionRingManager and SelectionRing will tell... more later
Step three: Units and Players
- The current implementation of SelectionRingManager is starting to support the Unit generally as well as Player.
Step four: Decorative enhancements
- Variable colours
- Rotation
- Embedded particle systems
- an apparent effect, coordinating with rotation/colour
Step five: Beyond simple selection
Consider how and why these might be used on a client
- To indicate a target unit of an action
- To indicate an active 'over time' effect on a unit
- To indicate that the player has been targetted by an AI/some other in-game entity
- Priority, stacking, single or multiple
Server model
- discussion only until networking examples from betauser in .60 release
- This probably belongs in a different wiki page...
- Maintaining a stack of effects on a unit (e.g. stacked heals/damage over time/self-buffs/group-buffs/area-debuffs)
- Managing timeouts of each effect
- Resolving which effect should receive the priority in display for all clients
- Excepting a particular client may override this, e.g. if the unit in question is selected by that client's player
- Perhaps an example healing system with simple server modelling of units being healed and client decisions about display only and interaction with unit selection
Authors
- wellu for the 'creatable decals' code on which all is based
- mrexcessive layout and SelectionRingManager, SelectionRing classes
Credits
Kudos to Wellu who has patiently explained things to me and provided example code.
Suggestions area
- If you don't want to spend time editing the wiki,
- but you have a great idea or some feedback,
- then please email me mrexcessive _at_no_spam_at gmail _dot_ com or just add your comments and ideas here
