BUG (+solution): GUISceneview RenderMask NoRenderMask
by Martijn Segers · in Torque X 2D · 01/30/2008 (8:06 am) · 2 replies
I am testing with the Torque X Pro Beta 3D v1.5.0.0.
While trying to get the 'Airplane' Example - tutorial working i ran into a problem with the RenderMask and NoRendermask attributes on the GUISceneView object.
While implementing and testing the sample code ( changing it along the way because of - not documented- API changes ), I could not get the NoRenderMask attribute working correctly. It seemed that all sprites with any TorqueObjectTypes got rendered every time.
I solved the issue changing the following code ( at two particular places) :
-------------------------------------------------------------------------------------------------------------------------------
The BaseSceneGraph.PreRender function was only using the renderMask parameter and ignoring the noRenderMask parameter.
-------------------------------------------------------------------------------------------------------------------------------
SceneGraph.cs
in public abstract class BaseSceneGraph : TorqueObject
changed to
-------------------------------------------------------------------------------------------------------------------------------
In the SceneContainer._FindInBin function ourType ( ObjectType bits of the found sceneObjectRef ) where (AND) compared with the typebits ( renderMask-noRenderMask.bits ).
This would work if an sprites Torque Object's ObjectType bits where only set to one specific ObjectType.
However ...
In my case the ObjectType (instrument) i was excluding had bit value 2 .. but Sprites that used this ObjectType (2) had bit value 19
?? ( 1 ( torqueobject?? ) +2 (instrument) +16 (t2dSpriteType) ) ??
so...
in case of excluding ( rendering : renderMask - noRenderMask)
(instrumenSpriteObject.bits) and (all.bits - instrument.bit )
(19) and (ulong - 2) = 17
... skip object if (ourType & typebits) != ourType
( not all ObjectType bits of SpriteObject were set )
in case of rendering a specific objectType (rendering only ObjectType.bit )
( instrumentSpriteObject.bits) and (instrument.bit )
(19) and (2) = 2
.. skip object if (ourType & typebits) != typebits
( ObjectType bit of SpriteObject was not set )
-------------------------------------------------------------------------------------------------------------------------------
so I changed the following code
SceneContainer.cs
abstract public class SceneContainer : TorqueBase
changed to
I dont know if this is the right solution or if there was a particular reason why the NoRenderMask was ignored or the bits checked the way it was. The changes above solved my problem however so i presume it was the right way.
Would be nice if a GarageGames developer would share his/her thoughts about this issue and let me know if I totaly messed up the code or it was the right thing to do ....
:)
Martijn Segers
While trying to get the 'Airplane' Example - tutorial working i ran into a problem with the RenderMask and NoRendermask attributes on the GUISceneView object.
While implementing and testing the sample code ( changing it along the way because of - not documented- API changes ), I could not get the NoRenderMask attribute working correctly. It seemed that all sprites with any TorqueObjectTypes got rendered every time.
I solved the issue changing the following code ( at two particular places) :
-------------------------------------------------------------------------------------------------------------------------------
The BaseSceneGraph.PreRender function was only using the renderMask parameter and ignoring the noRenderMask parameter.
-------------------------------------------------------------------------------------------------------------------------------
SceneGraph.cs
in public abstract class BaseSceneGraph : TorqueObject
public void PreRender(GFXDevice gfx, TorqueObjectType renderMask,
TorqueObjectType noRenderMask, float aspectRatio)
{
...
_RenderObjects(renderMask , aspectRatio);
...
}changed to
public void PreRender(GFXDevice gfx, TorqueObjectType renderMask,
TorqueObjectType noRenderMask, float aspectRatio)
{
...
_RenderObjects(renderMask - noRenderMask , aspectRatio);
...
}-------------------------------------------------------------------------------------------------------------------------------
In the SceneContainer._FindInBin function ourType ( ObjectType bits of the found sceneObjectRef ) where (AND) compared with the typebits ( renderMask-noRenderMask.bits ).
This would work if an sprites Torque Object's ObjectType bits where only set to one specific ObjectType.
However ...
In my case the ObjectType (instrument) i was excluding had bit value 2 .. but Sprites that used this ObjectType (2) had bit value 19
?? ( 1 ( torqueobject?? ) +2 (instrument) +16 (t2dSpriteType) ) ??
so...
in case of excluding ( rendering : renderMask - noRenderMask)
(instrumenSpriteObject.bits) and (all.bits - instrument.bit )
(19) and (ulong - 2) = 17
... skip object if (ourType & typebits) != ourType
( not all ObjectType bits of SpriteObject were set )
in case of rendering a specific objectType (rendering only ObjectType.bit )
( instrumentSpriteObject.bits) and (instrument.bit )
(19) and (2) = 2
.. skip object if (ourType & typebits) != typebits
( ObjectType bit of SpriteObject was not set )
-------------------------------------------------------------------------------------------------------------------------------
so I changed the following code
SceneContainer.cs
abstract public class SceneContainer : TorqueBase
protected void _FindInBin(SceneContainerBinReference bin, SceneContainerQueryData queryData)
{
...
if ((ourType & typebits) == 0)
{
// Move to next bin reference.
bin = bin._nextBinReference;
continue;
}
...
}changed to
protected void _FindInBin(SceneContainerBinReference bin, SceneContainerQueryData queryData)
{
...
if (((ourType & typebits) != typebits) && ((ourType & typebits) != ourType))
{
// Move to next bin reference.
bin = bin._nextBinReference;
continue;
}
...
}I dont know if this is the right solution or if there was a particular reason why the NoRenderMask was ignored or the bits checked the way it was. The changes above solved my problem however so i presume it was the right way.
Would be nice if a GarageGames developer would share his/her thoughts about this issue and let me know if I totaly messed up the code or it was the right thing to do ....
:)
Martijn Segers
#2
This is assuming a project was created with TorqueX Pro 2.0. I can't be sure if it will work in other versions, but feel free to try it out. Obviously will need access to the TorqueX source code.
Changes are required in four TorqueX files: SceneContainer.cs, SceneGraph.cs, T2DSceneGraph.cs, and T3DSceneGraph.cs. I don't actually use the 3D part, yet, but one function in it has to be changed to allow the solution to build.
Added new member and property:
class SceneContainer:
Added lines to _FindInBin() -- 2nd one replaces the line "if ((ourType & typebits) == 0)":
it applies to T3D compared to T2D, so I am not sure whether this will work for 3D.
Added parameter noRenderMask to _RenderObjects() call:
Added parameter noRenderMask to _RenderObjects() and changed line:
Added parameter exclTypes to FindObjects() and extra line:
Added parameter exclTypes to other FindObjects() and changed line:
(NOT tested)
Added parameter noRenderMask to _RenderObjects() and extra line:
I find that this works for any kind of type-filering, whether it is for Rendering, Collisions, your own checks, or whatever.
Simply use some lines like:
where "view" is a GUISceneview already set up as usual. You can, of course, combine types using the + and - operators.
As the code works now, the exclude mask will take precedent, so that an object type which is in both the include mask and the exclude mask will be excluded.
06/02/2009 (12:49 pm)
NoRenderMask functionality solution
This is assuming a project was created with TorqueX Pro 2.0. I can't be sure if it will work in other versions, but feel free to try it out. Obviously will need access to the TorqueX source code.
Changes are required in four TorqueX files: SceneContainer.cs, SceneGraph.cs, T2DSceneGraph.cs, and T3DSceneGraph.cs. I don't actually use the 3D part, yet, but one function in it has to be changed to allow the solution to build.
***SceneContainer.cs***
class SceneContainerQueryData:Added new member and property:
/// <summary>
/// TorqueObjectTypes to exclude.
/// </summary>
public TorqueObjectType ExcludeObjectTypes
{
get { return _excludeObjectTypes; }
set { _excludeObjectTypes = value; }
}
internal TorqueObjectType _excludeObjectTypes = TorqueObjectType.NoObjects;class SceneContainer:
Added lines to _FindInBin() -- 2nd one replaces the line "if ((ourType & typebits) == 0)":
protected void _FindInBin(SceneContainerBinReference bin, SceneContainerQueryData queryData)
{
.
.
.
ulong excltypebits = queryData._excludeObjectTypes._bits;
.
.
.
if ((ourType & typebits) == 0 //if ourType DOES NOT match up with any of typebits
|| (ourType & excltypebits) != 0) //or if ourType DOES match up with any of excltypebits
.
.
.
} NOTE: There is a comment in the code about the type check from the Torque developers about howit applies to T3D compared to T2D, so I am not sure whether this will work for 3D.
***SceneGraph.cs***
class BaseSceneGraph:Added parameter noRenderMask to _RenderObjects() call:
void PreRender(GFXDevice gfx, TorqueObjectType renderMask, TorqueObjectType noRenderMask, float aspectRatio)
{
.
.
.
_RenderObjects(renderMask, noRenderMask, aspectRatio); //goes to 2D or 3D version
.
.
.
}***T2DSceneGraph.cs***
class T2DSceneGraph:Added parameter noRenderMask to _RenderObjects() and changed line:
_RenderObjects(TorqueObjectType renderMask, TorqueObjectType noRenderMask, float aspectRatio)
{
.
.
.
FindObjects(sceneRect, renderMask, noRenderMask, 0xFFFFFFFF, _containerQueryResults);
.
.
.
}Added parameter exclTypes to FindObjects() and extra line:
FindObjects(RectangleF searchRect, TorqueObjectType findTypes, TorqueObjectType exclTypes, ...
{
.
.
.
_queryData.ExcludeObjectTypes = exclTypes;
.
.
.
}Added parameter exclTypes to other FindObjects() and changed line:
FindObjects(Vector2 pos, float radius, TorqueObjectType findTypes, TorqueObjectType exclTypes, ...
{
.
.
.
FindObjects(searchRect, findTypes, exclTypes, layerMask, list);
.
.
.
}***T3DSceneGraph.cs***
class T3DSceneGraph:(NOT tested)
Added parameter noRenderMask to _RenderObjects() and extra line:
_RenderObjects(TorqueObjectType renderMask, TorqueObjectType noRenderMask, float aspectRatio)
{
.
.
.
_queryData.ExcludeObjectTypes = noRenderMask;
.
.
.
}I find that this works for any kind of type-filering, whether it is for Rendering, Collisions, your own checks, or whatever.
Simply use some lines like:
TorqueObjectType MiniMapOnly = TorqueObjectDatabase.Instance.GetObjectType("MiniMapOnly");
view.NoRenderMask = MiniMapOnly;where "view" is a GUISceneview already set up as usual. You can, of course, combine types using the + and - operators.
As the code works now, the exclude mask will take precedent, so that an object type which is in both the include mask and the exclude mask will be excluded.
Torque Owner Scott Zarnke
I should point out that I have been using TorqueX Pro 2.0, in 2D, using TXB.
I began working along the same lines as Martijn, "subtracting" the norender from the render, and changing the bitwise test. I had even used the same part "(ourType & typebits) != ourType", which is heading in the right direction. But I found it caused collisions to not always work correctly if CollidesWith is more than one type but not all types, since the same object type filtering is used in collisions, as well.
The extra part "(ourType & typebits) != typebits)" helps, but still only will work if there is just ONE type being searched for. If, for instance, the collision filter is for more than one type, this test fails and so the object is skipped.
In my game, I had some blank scene objects used to restrict movement, but using the above solution they did not stop anything. The vehicle that should have been stopped was looking for collisions with three types. Tracing into the code, I found that these were the values:
ourType: 0x0801 //has generic type (1) plus my custom type (8)
typebits: 0x6800 //filtering for custom type (8) plus two others
Thus, the bitwise-and of them is 0x0800, which is not equal to either one and so the current object would be skipped when it should have been selected. Had the typebits (i.e. filter) been 0x0800, it would have worked, but obviously that only filters for one type.
The solution I came up with is just a little more coding, but I think works a little easier because it allows the two masks to be kept separate and dealt with separately.
I will post again soon with the details of what I came up with.