Infrared Content

From SIMboxWiki
Jump to navigation Jump to search

The infrared content is made up of three major areas.

  • The SMG_HeatSignature component is used to allow entities to control their specific object settings.
  • The SMG_ThermalNightVision component which specifies the settings for cameras.
  • The EnvironmentManager extension which allows the terrain, water and ambient temperatures to be modified. You can also control how these temperatures are affected by the time of day change.


SMG_HeatSignature Component

All objects who reside in the SIMbox toolkit object hierarchy, under Simulation/Physical, inherit from this component. This component is used to control the object specific settings for the infrared effect.  

Object Specific Textures

In order for an object to take full advantage of the infrared feature, and to look as real as possible; an additional texture will need to be provided. This texture will contain color data that the graphics engine will use to determine which areas of the object should be rendered hot or cold.


Jeep without an IR specific texture: Jeep with out ir texture.png  Jeep with IR specific texture: Jeep with ir texture.png

Jeep IR.png
Humvee Body IR.png


The textures are resolved in runtime by the Graphics Engine using the following logic:

  1. Each model (.mesh) has a material file, for the Cessna (high LOD), it is cessna172_h.mesh.material
  2. Each material file may contain one or more materials, each will have a name. for the Cessna, these are cessna172_h/Cessna172, cessna172_h/Cessna172_Prop, cessna172_h/Cessna172_glass and cessna172_h/Cessna172_pilots
  3. For each material, get the relative name, e.g., for the cessna172_h/Cessna172 material, take only Cessna172
  4. For each of these names, postfix it with _IR.dds, e.g., for the Cessna172 name, use Cessna172_IR.dds
  5. If the file exists, use it as the IR texture for the material

Note: Different LOD materials may reference the same IR texture.

The image below shows the lookup sequence for the Cessna:
Cessna IR Texture Lookup Sequence.png

Texture Color Channels

An infrared texture can use three colors (red, green, blue) to mark specific areas of the object. The texture can also be grayscale. In the infrared texture for the hummer, you can see it uses red and blue for different areas of the object. The tires are colored blue and the body red. This allows the ability to raise and lower the temperature of certain areas of an object. The reason for this feature is to make objects heat signature more realistic. When a vehicle is turned on, the engine temperature will increase over time and decrease when turned off. After driving for ahwile the tires will heat up and cool down when stopped. If the infrared texture is grayscale, then specific areas of the object cannot have different temperatures. 

Controlling Temperature With Texture Color Channels

The SMG_HeatSignature component has attributes and actions that can manpulate the temperature of an object using the color in the infrared texture. The following attributes represent what can be controlled in real time. It is important to note here that these attributes should not be set directly. It is a good practice to use the corresponding actions to set data in a component. 


ATT_HS_TEMPERATURE_BASE

This is the overall temperature of the object.


ATT_HS_USE_AMBIENT_AS_BASE_TEMPERATURE

If this is set to true, the base temperature will automatically be set to the environments ambient temperature.


ATT_HS_TEXTURE_RANGE_RED
ATT_HS_TEXTURE_RANGE_GREEN
ATT_HS_TEXTURE_RANGE_BLUE

These are the temperature values for each color area specified in the infrared texture. It is important to note here that if the texture used is grayscale then the temperature value for red is the value used. The temperature values should in units of Celcius.


ATT_HS_TEXTURE_MODE_RED

ATT_HS_TEXTURE_MODE_GREEN

ATT_HS_TEXTURE_MODE_BLUE

These can be set to either absolute or relative. Absolute means that the base temperature value will automatically be subtracted from the red, green, and blue temperatures. If the value is set to relative then the base temperature is not taken into account. 

Using SMG_HeatSignature Example

The following example will use the Hummer entity to change the temperature of the tires and the engine during run time. This example assumes you already know how to create a basic logic component in visual studio 2005 and analyze that project to the Simbox database. You will also need to be familiar with the Simbox toolkit and know how to add components to a entity.


1. Create a logic component using the Simbox project generation wizard in Visual Studio 2005. Go ahead and compile and analyze the project.

2. Open the Simbox toolkit and select the Hummer entity. If you wish you can duplicate the Hummer so the base content version remains unchanged.

3. Add the newly created logic component to the Hummer entity. This logic component will be used to make action calls to the SMG_HeatSignature component to change temperature values.

4. Next you want to set the properties up in the SMG_HeatSignature component for the Hummer.

    PROP_HS_TEMPERATURE_BASE = 0

    PROP_HS_TEXTURE_MODE_BLUE = 1

    PROP_HS_TEXTURE_MODE_GREEN = 1

    PROP_HS_TEXTURE_MODE_RED = 1

    PROP_HS_TEXTURE_RANGE_BLUE = 40

    PROP_HS_TEXTURE_RANGE_GREEN = 35

    PROP_HS_TEXTURE_RANGE_RED = 80

    PROP_HS_USE_AMBIENT_AS_BASE_TEMPERATURE = True

5. Save the toolkit changes and create a basic scenario with the Hummer.

6. Now we can get to the code. In the logic component you created add a few private member variables.

float m_BlueTemperature;
float m_RedTemperature;

float m_BlueRate;
float m_RedRate;

7. In the constructor of your logic component init the values of the member variables.

m_BlueTemperature = 20.0f;
m_RedTemperature = 50.0f;

m_BlueRate = 2.0f;
m_RedRate = -2.0f;


8. In the update add the following code. This will increase and decrease the red and blue temperatures over time.

// Increase/decrease the temperature over time.
m_BlueTemperature += SimApi::Timer::deltaTime() * m_BlueRate;
m_RedTemperature += SimApi::Timer::deltaTime() * m_RedRate;

// Put a max and min on the temperature values and toggle the rate when they hit the limits.
if(m_BlueTemperature > 50.0f)
{
 m_BlueRate = -m_BlueRate;
 m_BlueTemperature = 50.0f;
}
else if(m_BlueTemperature < 20.0f)
{
 m_BlueRate = -m_BlueRate;
 m_BlueTemperature = 20.0f;
}

if(m_RedTemperature > 50.0f)
{
 m_RedRate = -m_RedRate;
 m_RedTemperature = 50.0f;
}
else if(m_RedTemperature < 20.0f)
{
 m_RedRate = -m_RedRate;
 m_RedTemperature = 20.0f;
}

// Set the temperature values in the SMG_HeatSignature component. 
CALL_ENTITY_ACTION_1(_pOwnerEntity, L"ACTION_HS_SET_TEXTURE_RANGE_BLUE", m_BlueTemperature);
CALL_ENTITY_ACTION_1(_pOwnerEntity, L"ACTION_HS_SET_TEXTURE_RANGE_RED", m_RedTemperature);

9. Compile the project and run your scenario. To active infrared you can set your view to outside (F3) and press CONTROL + I. SHIFT + I will also change white hot to black hot. You should now see the temperatures of the engine and tires changing over time.


Object Infrared API

Although the SMG_HeatSignature component provides a convient way to modify objects temperature during runtime; a lower level API is available so you can interact directly with the graphics engine. This is done by the TriD::SetInfraredObjectAttrib function call.


SetInfraredObjectAttrib

This function takes two parameters. The first is the id of the object of the entity. The easiest way to get your entities object id is from the 'EntityWorld::ATT_3D_OBJECT_HANDLE' attribute. The second parameter takes in a TriD::zsInfraredObjectAttrib struct. This struct contains object specific data that the graphics engine uses to render the object in infrared.

zsInfraredObjectAttrib

This struct contains the following members.


float temperatureBase;

This is the base temperature for the object. A good value to set this to is the environments ambient temperature. You can get the environments ambient temperature from the 'GLOBAL_ATT_ENVIRONMENT_AMBIENT_TEMPERATURE' attribute.


float textureRangeRed;
float textureRangeGreen;
float textureRangeBlue;

These values control the temperature of the red, green, and blue color channels that correspond to the infrared texture. If the infrared texture is in grayscale then the red value will control the temperature. The green and blue values are ignored. The temperature values should be in units of Celcius.


WORD attrib;

This is a flag for what data the graphics engine should use in this structure. 

const WORD IOA_TEMPERATUREBASE 
const WORD IOA_RANGERED 
const WORD IOA_RANGEGREEN 
const WORD IOA_RANGEBLUE 
const WORD IOA_RANGES

These are constant values that can be used to set the 'attrib' variable. 

Example of using the API

The following code is an example of how to set an object's infrared data. You can add this to the start function of any output component to set the object infrared data.

// Get the entity object id.
int objectId = -1;
GET_ENTITY_ATT(_pOwnerEntity, EntityWorld::ATT_3D_OBJECT_HANDLE, objectId);

// Get the environment ambient temperature.
float ambientTemperature = 0.0f;
GET_GLOBAL_ATT(L"GLOBAL_ATT_ENVIRONMENT_AMBIENT_TEMPERATURE", ambientTemperature);

// Set the object infrared data.
TriD::zsInfraredObjectAttrib irObjectAttributes;
irObjectAttributes.attrib = TriD::IOA_TEMPERATUREBASE | TriD::IOA_RANGES;
irObjectAttributes.temperatureBase = ambientTemperature;
irObjectAttributes.textureRangeRed = 30.0f;
irObjectAttributes.textureRangeGreen = 5.0f;
irObjectAttributes.textureRangeBlue = 10.0f;

// Tell the graphics engine to apply this data to the object.
TriD::SetInfraredObjectAttrib(objectId, irObjectAttributes);

SMG_ThermalNightVision Component

This component controls how a camera renders the infrared effect. All objects who reside in the SIMbox toolkit object heirarchy, under Infrastructure/Abstract/Scene/Render/3D, inherit from this component. The ways in which the camera renders the infrared effect are as follows:


Acclimation Time

This controls the motion blur of the infrared effect. The larger the value the more the motion blur. The picture below is an acclimation time of 2 seconds. The attribute ATT_TNV_INFRARED_ACCLIMATION_TIME controls this value.

Ir acclimation 2 sec.png

Interference

This is how much interference/distortion the camera has. Valid values for this are 0 to 1. The attribute ATT_TNV_INFRARED_INTERFERENCE controls this value.

Ir 0 interferance.PNG               Ir 1 interferance.PNG

Inversed

This controls if the camera renders in white hot or black hot. The attribute ATT_TNV_INFRARED_INVERSED controls this value.

Ir non inverted.png               Ir inverted.png

Temperature Min

The lowest temperature that can be displayed by the camera. The attribute ATT_TNV_INFRARED_TEMPERATURE_MIN controls this value.

Temperature Max

The highest temperature that can be displayed by the camera. The attribute ATT_TNV_INFRARED_TEMPERATURE_MAX controls this value.

Active

If the camera should render the infrared effect or not. The attribute ATT_TNV_INFRARED_ACTIVE controls this value.

Auto Setting Temp Range

If the camera should auto adjust the min and max temperature based on the object in the scene. This feature takes into account all entities in the camera's frustum and adjusts the camera's min and max temperature range to the highest and lowest entity temperature. The attribute ATT_TNV_INFRARED_AUTO_SETTING_TEMP_RANGE controls this value.

Auto Setting Max Distance

The max distance to include entities into the 'auto setting temp range' check.  The attribute ATT_TNV_INFRARED_AUTO_SETTING_MAX_DISTANCE controls this value.

Component Input

An input is provided via  'control + i' to toggle infrared on and off. 'shift + i' will invert the infrared effect.


EnvironmentManager Extension


Global heat signature dialog.png


The global heat signature settings of this extension control how the terrain, water and ambient areas of the world are affected by the infrared effect. The terrain and water each have a minimum and maximum temperature value. These min and max temperature values set a range for the coldest and hottest parts of the terrain. There are two different ways in which the temperatures are calculated. If the 'Affected by time of day' is not checked, then the temperature values are provided directly from the dialog. If the temperatures are affected by the time of day, then the 'Time Of Day Options' dialog is used to specify how the temperatures should be calculated. 


Time of day options.png


The 'Time Of Day Options' dialog contains a graph control for the terrain, water, and ambient temperatures. The terrain and water graphs contain min and max points, the ambient graph only contains single points. Points can be added to the graph by left clicking and removed from the graph by right clicking a point. Each point represents a temperature value; the top most points are maximum temperature and the bottom most points are minimum temperatures. Where the point is horizontaly placed on the graph specifies at what time the certain environment area is that temperature. The temperature points are linearly interpolated between. For example, if the ambient graph contains a point at time 12:00 with a temperature of 20, and another point at time 18:00 with a temperature of 10. The temperature will decrease as the time moves from 12:00 to 18:00.


Developing An Infrared Camera Example

This example explains how to create an infrared camera using the SimiGon video camera sdk template for visual studio 2005. This assumes that you already know how to create a SimiGon template project in visual studio, compile, and analyze the project to the database. Also that you are familiar with the SIMbox Toolkit and can duplicate entities.

Basic Infrared Camera

1. In Visual Studio 2005 select to add a new project. Expand the 'Visual C++' tab and then expand the 'SIMbox SDK' tab. Select 'Advanced Templates'; then in the templates box select the 'Video Camera Component' template.

2. Once the project is created compile and analyze the project.

3. In the toolkit find the 'Cessna172SP' entity and duplicate it. Also, in the Console Editor, find the Cessna172 console and duplicate it too.

4. Back in the toolkit set the duplicated Cessna entity's cockpit to the duplicated cockpit.

5. In the console editor add a new gauge to the panel 'PANEL_TOP'.

Ir tut create new gauge.png

6. In the 'Gauge Settings' set the X position to 670 and the Y position to 10.

Ir tut set gauge position.png          Ir tut gauge position.png

7. Add the 'Video Camera' project you created to the new gauge.

Ir tut insert new console component.png          Ir tut select video camera component.png

8. Once this component is added, you should have the camera render to the gauge canvas. Now we need to add some code to the template project to enable infrared.

Ir tut gauge with video camera.png

9. In the header of the 'Video Camera' project you will need to add a private member variable.

TriD::zsInfraredCameraAttrib m_infraredCameraAttribute;

10. In the Start() function of the component project you will need to set the infrared camera attributes.

// specify what data should be applied to the camera
m_infraredCameraAttribute.attrib = TriD::ICA_ACCLIMATIONTIME | TriD::ICA_INTERFERENCE | TriD::ICA_ISINFRAREDACTIVE | TriD::ICA_TEMPERATURE;

m_infraredCameraAttribute.acclimationTime = 0.2f; // motion blur
m_infraredCameraAttribute.interference = 0.2f; // static/fuzz
m_infraredCameraAttribute.isInfraredActive = true; // if infrared is on or off
m_infraredCameraAttribute.temperatureMin = 20.0f; // min temperature picked up by the camera
m_infraredCameraAttribute.temperatureMax = 40.0f; // max temperature picked up by the camera

// tell the graphics engine to apply these attributes to the camera.
TriD::SetInfraredCameraAttrib(m_CameraId, m_infraredCameraAttribute);

11. You may also want to adjust the orientation of the camera so it points slightly downward. In the component's Start() function you can adjust the orientation like so.

m_Orientation[X] = -2;

This is all that is needed to modify the existing 'Video Camera' template project to use infrared.

Ir tut cessna on runway ir.png

Inverting The Infrared Effect

In order to change to effect from white hot to black hot you will need to swap the min and max temperatures. To set the camera to white hot use the following code.

m_infraredCameraAttribute.temperatureMin = 20.0f;
m_infraredCameraAttribute.temperatureMax = 40.0f;
TriD::SetInfraredCameraAttrib(m_CameraId, m_infraredCameraAttribute);

To set the camera to black hot adjust the code like so.

m_infraredCameraAttribute.temperatureMin = 40.0f;
m_infraredCameraAttribute.temperatureMax = 20.0f;
TriD::SetInfraredCameraAttrib(m_CameraId, m_infraredCameraAttribute);