Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 19 Jul 2011
Offline Last Active Jul 21 2014 09:57 PM

#5165530 State Machine

Posted by Alundra on 08 July 2014 - 06:18 AM

As example, I use a mix of behavior trees and FSM, my fsm are integrated in my BTs and look something like this:
int state = getState();
if(state==INIT) {
...start movement...
state = MOVE;
} else if(state==MOVE) {
// check if target reached
if(targetReached()) {
} else if(movementBlocked()) {
} else if(state==BLOCKED) {
if(timeoutReached()) {
You dont need any fancy, tool supported, generic state machine for simple stuff like this. More complex stuff is handled by my BTs.

This is what I have in my character animation state machine using if/else without state machine system :

enum TPlayerState
  PS_IDLE = 0,
  PS_MOVE = 1

// Animation state machine.
if( m_MoveDirection != DE::CVector2( 0.0f, 0.0f ) )
  m_PlayerState = PS_MOVE;
  // Check if we changed of state.
  if( m_PlayerState != PS_IDLE )
    m_PlayerState = PS_IDLE;
Go to AIGameDev.com, join for free (this will give you a restricted access), and read e.g. the articles / listen the recordings

Thanks for the link didn't knew that one smile.png

#5164743 Frustum sphere

Posted by Alundra on 04 July 2014 - 08:27 AM

Hi all,

Here my code to compute a bounding sphere from camera + near + far :

void ExtractFrustumSphere( CCameraActor* Camera, const float Near, const float Far, CVector3* Center, float* Radius )
  // Get the camera component.
  CCameraComponent* CameraComponent = static_cast< CCameraComponent* >( Camera->GetComponent( 0 ) );
  // Camera params.
  const CVector3 CameraPos = Camera->GetWorldTranslationVector();
  const CVector3 CameraRight = Camera->GetRightVector();
  const CVector3 CameraForward = Camera->GetForwardVector();
  const CVector3 CameraUp = Camera->GetUpVector();
  // Tangent values.
  const float TanFOVX = CMath::Tan( CameraComponent->GetAspectRatio() * CameraComponent->GetFieldOfView() * 0.5f );
  const float TanFOVY = CMath::Tan( CameraComponent->GetAspectRatio() );
  // Compute the half distance.
  const float HalfDistance = 0.5f * ( Far - Near );
  // Compute the center.
  *Center = CameraPos + CameraForward * ( Near + HalfDistance );
  // Compute the radius.
  *Radius = ( ( CameraRight * TanFOVX + CameraUp * TanFOVY + CameraForward ) * HalfDistance ).Length();

I'm not sure if I use the correct way to compute the radius.

I think this is wrong because for a near of 0.1f and a far of 100.0f with a FOV of QUATER_PI, I have 246 of radius.

What is wrong in the calcule of the radius ?

Thanks for the help.



I saw I used a bad value for TanFOVY, I have changed to use :

const float TanFOVX = CMath::Tan( CameraComponent->GetAspectRatio() * CameraComponent->GetFieldOfView() * 0.5f );
const float TanFOVY = CMath::Tan( CameraComponent->GetFieldOfView() * 0.5f );

I Have a radius of 68 for the same values I said before, Is it the correct answer ?

#5159275 I hate my code....How do you structure your code for a game?

Posted by Alundra on 09 June 2014 - 09:26 AM

You can write a whole game without class, look at quake source code, it's a monster source code without one class.

If you say you use class because others use class, that only mean you don't understand what class give you.

#5159102 I hate my code....How do you structure your code for a game?

Posted by Alundra on 08 June 2014 - 11:16 AM

It's nice to not like your code, because then you want more and more.

The best way to have a good code is to practice more and more until you have more results with less code.

It's called the experience and you can't get it without working on projects.

#5153765 Screen Space Reflection Optimization

Posted by Alundra on 15 May 2014 - 07:24 AM

Hi all,

I'm interested working on screen space reflection because it's the future.

Here the actual code I have, learned from a book :

struct PS_INPUT
  float4 Position : SV_POSITION;
  float3 Normal   : NORMAL;
  float4 Tangent  : TANGENT;
  float2 TexCoord : TEXCOORD0;
  float4 PosVS    : TEXCOORD1;

cbuffer PROJECTION_CBUFFER : register( b0 )
  float4x4 Projection;
  float4 PerspectiveValues;

cbuffer SSR_CBUFFER : register( b1 )
  float ViewAngleThreshold;
  float EdgeDistThreshold;
  float DepthBias;
  float ReflectionScale;

Texture2D DiffuseMap : register( t0 );
Texture2D DepthMap : register( t1 );
SamplerState LinearSampler : register( s0 );
SamplerState PointSampler : register( s1 );

float ConvertZToLinearDepth( in float DepthValue )
  return PerspectiveValues.z / (DepthValue - PerspectiveValues.w);

float3 PosFromDepth( in float2 uv, in float LinearDepth )
  return float3( PerspectiveValues.xy * uv * LinearDepth, LinearDepth );

static const float PixelSize = 2.0f / 720.0f;
static const int NumSteps = 1280;

float4 main( in PS_INPUT Input ) : SV_TARGET
  // Normalize the normal.
  float3 NormalVS = normalize( Input.Normal );
  // Compute the camera to pixel direction.
  float3 EyeToPixel = normalize( Input.PosVS.xyz );
  // Compute the reflected view direction.
  float3 ReflectVS = reflect( EyeToPixel, NormalVS );
  // The initial reflection color for the pixel.
  float4 ReflectColor = float4( 0.0f, 0.0f, 0.0f, 0.0f );
  // Check the angle using threshold.
  if( ReflectVS.z >= ViewAngleThreshold )
    // Fade the reflection as the view angles gets close to the threshold.
    float ViewAngleThresholdInv = 1.0f - ViewAngleThreshold;
    float ViewAngleFade = clamp( 3.0f * (ReflectVS.z - ViewAngleThreshold) / ViewAngleThresholdInv, 0.0f, 1.0f );
    // Transform the View Space Reflection to clip-space.
    float3 PosReflectVS = Input.PosVS.xyz + ReflectVS;
    float3 PosReflectCS = mul( float4( PosReflectVS, 1.0f ), Projection ).xyz / PosReflectVS.z;
    float3 ReflectCS = PosReflectCS - Input.Position.xyz;
    // Resize Screen Space Reflection to an appropriate length.
    float ReflectScale = PixelSize / length( ReflectCS.xy );
    ReflectCS *= ReflectScale;
    // Compute the first sampling position in screen-space.
    float2 SampPos = float2( 0.5f, -0.5f ) * (Input.Position.xy + ReflectCS.xy) + 0.5f;
    // Find each iteration step in screen-space.
    float2 Step = ReflectCS.xy * float2( 0.5f, -0.5f );
    // Build a plane laying on the reflection vector.
    float4 RayPlane;
    float3 Right = cross( EyeToPixel, ReflectVS );
    RayPlane.xyz = normalize( cross( ReflectVS, Right ) );
    RayPlane.w = dot( RayPlane.xyz, Input.PosVS.xyz );
    // Iterate over the texture searching for intersection.
    for( int CurStep = 0; CurStep < NumSteps; ++CurStep )
      // Get the current depth.
      float CurDepth = DepthMap.SampleLevel( PointSampler, SampPos, 0.0f ).x;
      // Reconstruct the position from depth.
      float CurDepthLin = ConvertZToLinearDepth( CurDepth );
      float3 CurPos = PosFromDepth( Input.Position.xy + ReflectCS.xy * ((float)CurStep + 1.0f), CurDepthLin );
      // The intersection happens between two positions on the oposite sides of the plane.
      if( RayPlane.w >= dot( RayPlane.xyz, CurPos ) + DepthBias )
        // Compute the actual position on the ray for the given depth value.
        float3 FinalPosVS = Input.PosVS.xyz + (ReflectVS / abs(ReflectVS.z)) * abs(CurDepthLin - Input.PosVS.z + DepthBias);
        float2 FinalPosCS = FinalPosVS.xy / PerspectiveValues.xy / FinalPosVS.z;
        SampPos = float2( 0.5f, -0.5f ) * FinalPosCS.xy + 0.5f;
        // Get the value at the current screen space location.
        ReflectColor.rgb = DiffuseMap.SampleLevel( LinearSampler, SampPos, 0.0f ).rgb;
        // Fade out samples as they get close to the texture edges.
        float EdgeFade = clamp( distance( SampPos, float2( 0.5f, 0.5f ) ) * 2.0f - EdgeDistThreshold, 0.0f, 1.0f );
        // Compute the fade value.
        ReflectColor.a = min( ViewAngleFade, 1.0f - EdgeFade * EdgeFade );
        // Apply the reflection scale.
        ReflectColor.a *= ReflectionScale;
        // Advance past the final iteration to break the loop.
        CurStep = NumSteps;
      // Advance to the next sample.
      SampPos += Step;
  // Return the reflect color.
  return ReflectColor;

This part is because it's fixed-size for test :

static const float PixelSize = 2.0f / 720.0f;
static const int NumSteps = 1280;

The problem is that cost very a lot.

Does a way exists to have a quality value ?


#5151209 what happens when std::vector is left empty?

Posted by Alundra on 03 May 2014 - 10:21 AM

To be more clear about the 12 and 24 bytes, it's because vector (and all array class in general) stores length,capacity and pointer of data.

At the end you have 2 size_t and one data pointer of the type of the vector, in x86 each is 4 bytes, in x64 each is 8 bytes.

#5149832 Unmaintainable code

Posted by Alundra on 27 April 2014 - 05:25 AM

Wow theres one hell of an if statement in there:

You can see a lot of hard coded value in this hell too, this file is a joke from A to Z.

Imagine the scene : "We have to change the jump height value"
Programmer of this file : "WHAT ?!"

#5149206 Best way to build SDL 2

Posted by Alundra on 24 April 2014 - 01:30 PM

can I call it engine?

If he does more than one thing and in different domain, you can call it engine I think.

For example a game engine is : Animation+Rendering+AI+Sound+Network


For this reason I want to share a "pre compiled" libraries, is it a good approach?.

You have to take care about license.You can distribute SDL2 but look to other license, and never forget to add license file.


I need to build statics or dinamics libraries?.

It's all a question of license for this one. Some library only give you dynamic lib but some give you both but has a restrictive license.

#5148972 Game Engine using SDL 2

Posted by Alundra on 23 April 2014 - 09:46 AM

If you use C++ go with SFML instead.

If he used SFML, the result would have been the same because it's a question of coding style more than API used.

Another point is SFML is more a game framework for OpenGL, SDL can be just used for windowing on D3D/OGL.

But after that, it's just a comment because SDL or SFML can be used for Unix version only if needed.


You're also not following the rule of three

I always like when Hodgman speaks about rule of three, because it's not always knew and should be.

#5148798 Game Engine using SDL 2

Posted by Alundra on 22 April 2014 - 12:50 PM

It's true, I didn't noticed that the first view. It's very bad coding style.

When you will move all the code, if you have function who is just "get" or "set", let them inline.

It's a hint for the compiler but you know these function will be inlined so it's ok to let them in .h inlined.

#5148763 Game Engine using SDL 2

Posted by Alundra on 22 April 2014 - 11:14 AM

Your math.h should have precomputed value :

const float DEG2RAD = 0.01745329251994329576923690768f;
const float RAD2DEG = 57.2957795130823208767981548141f;

inline float ToRadian( const float Degree )
  return ( Degree * DEG2RAD );

inline float ToDegree( const float Radian )
  return ( Radian * RAD2DEG );

You can clean your main.cpp, but it's personal comment, if you release, you have to clean, it's not a big code source so it's not a big effort.

You can optimize your vector2.h and vector3.h a lot using *= versus /= and avoiding return in CreateVector using reference as output.

I saw the same thing on different files who can be changed, output who has to be reference output and not returned.

This kind of optimization is important if the function is called each frame or often.

Now what I have to say about the all stuff is it's not a game engine for me but a framework actually.

But it can't be really used by other because you don't have any doc and it needs to be clean on different places.

#5148514 Game logic split between client & server - geometry

Posted by Alundra on 21 April 2014 - 05:15 AM

You have to share some code on the client side and the server side.

You have to keep in mind all gameplay stuff has to be done on the server side.

When a gameplay state is updated you have to send a message to all client who is connected about the change.

You have to take care of the bandwidth, don't send information who is not needed and use timer for some state of transform.

About the flashbang it could be one message with ID FLASHBANG_LAUNCHED who just add the flashbang on server and send the ID on client.

Using this ID who is called NetworkID you can update object from server to client, Raknet has a replication system who handle all that.

You will have to handle the reconnection of client if you need to keep the game in state, for counter-strike state of player is not stored.

In a DOTA game, when you have a reconnection the player keep his position on the list and has kills/deaths stored.

#5148456 undefined reference to `SDL_main'

Posted by Alundra on 20 April 2014 - 08:05 PM

SDL uses a macro for main, you have to link the SDL2main lib or "#undef main" after include SDL.h.

#5146396 where to start Physical based shading ?

Posted by Alundra on 11 April 2014 - 03:46 PM

You can convert the spec-power :

float RoughnessToSpecPower(in float m)
    return 2.0f / (m * m) - 2.0f;
float SpecPowerToRoughness(in float s)
    return sqrt(2.0f / (s + 2.0f));

#5144347 [C++] Is there an easy way to mimic printf()'s behavior?

Posted by Alundra on 04 April 2014 - 07:50 AM

Check out vsprintf, or for C++, boost::format.

Boost is ok for unit-test but should not be used since it's heavy weight.

In my opinion, vsprintf or use just a lib for that is a better choice.

EDIT: (it's funny like the truth always give bad point :))