Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


/Jeff/

Member Since 24 Mar 2010
Offline Last Active Nov 09 2014 09:17 AM

Topics I've Started

Player movement without physics engine

28 September 2014 - 12:11 PM

I'm curious as to what sort of techniques exist for handling player movement in a 3D environment without the use of a physics engine.

 

One approach I've tried in the past was using sphere casting (performing multiple iterations to handle sliding), but it had a number of quirks that I couldn't easily resolve.

 

Another thought I had was to just move the player along a navmesh, as described in http://digestingduck.blogspot.com/2010/07/constrained-movement-along-navmesh-pt-3.html. The main thing I'm still unsure about is how to handle dynamic obstacles (ex. enemies). And most of the navmesh resouces I've found so far pertain to the implementations in Unity, Unreal, or Source, rather than how to actually implement it.

 

Any thoughts on the above or alternative techniques? Or good resources on implementing them?

 

Also, are there any commercial games using similar approaches? From the small amount that I've played it, I think Kingdoms of Amalur: Reckoning might be using an approach similar to the second one I described, but I'm not sure. 


Effect fails to compile unless preshader disabled

03 July 2013 - 06:30 AM

I have an effect that I'm using in XNA that fails to compile in release mode, but works fine in debug mode. I was able to reproduce the behavior using the version of fxc included in the March 2009 DirectX SDK. Compilation fails unless preshaders are disabled (/Op)

 

This is the output, which isn't particularly helpful

error : (202,17): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
error : ID3DXEffectCompiler: Compilation failed 

The problem seems related to the if/elseif/else block at the top of TransformPixel().

 

Any suggestions? XNA doesn't seem to have a way to disable preshaders but keep other optimizations. It also applies some post processing to the compiled effect code. I was thinking I could replace XNA's EffectProcessor with one that uses a compiler from a more recent DirectX SDK, and then call XNA's post processor through reflection. I did a quick test of this and was able to load an effect compiled using the June 2010 SDK, but I'm not sure if there are cases where the output isn't compatible.

 

Here is the effect code, from http://animationcomponents.codeplex.com/

float4x4 World;
float4x4 View;
float4x4 Projection;
float3 DiffuseColor;
float3 SpecularColor;
float3 AmbientLightColor = float3(0,0,0);
float3 EmissiveColor;
float3 EyePosition;
float3 FogColor;
bool   FogEnable;
float FogStart;
float FogEnd;
bool   DirLight0Enable;
bool   DirLight1Enable;
extern bool    DirLight2Enable;
float3 DirLight0Direction;
float3 DirLight1Direction;
float3 DirLight2Direction;
float3 DirLight0DiffuseColor;
float3 DirLight1DiffuseColor;
float3 DirLight2DiffuseColor;
float3 DirLight0SpecularColor;
float3 DirLight1SpecularColor;
float3 DirLight2SpecularColor;
float Alpha;
float4x4 MatrixPalette[56];
float SpecularPower;
bool TextureEnabled;
bool LightingEnable = false;
texture BasicTexture;

sampler TextureSampler = sampler_state
{
   Texture = (BasicTexture);

};

struct VS_INPUT
{
    float4 position : POSITION;
    float4 color : COLOR;
    float2 texcoord : TEXCOORD0;
    float3 normal : NORMAL0;
    half4 indices : BLENDINDICES0;
    float4 weights : BLENDWEIGHT0;
};

struct VS_OUTPUT
{
    float4 position : POSITION;
    float4 color : COLOR;
    float2 texcoord : TEXCOORD0;
    float  distance : TEXCOORD1;
};

struct PS_INPUT
{
    float4 color : COLOR;
    float2 texcoord : TEXCOORD0;
    float  distance : TEXCOORD1;
};

struct PS_OUTPUT
{
    float4 color : COLOR;
};

struct SKIN_OUTPUT
{
    float4 position;
    float4 normal;
};

SKIN_OUTPUT Skin4( const VS_INPUT input)
{
    SKIN_OUTPUT output = (SKIN_OUTPUT)0;

    float lastWeight = 1.0;
    float weight = 0;
    for (int i = 0; i < 3; ++i)
    {
        weight = input.weights[i];
        lastWeight -= weight;
        output.position     += mul( input.position, MatrixPalette[input.indices[i]]) * weight;
        output.normal       += mul( input.normal  , MatrixPalette[input.indices[i]]) * weight;
    }
    output.position     += mul( input.position, MatrixPalette[input.indices[3]])*lastWeight;
    output.normal       += mul( input.normal  , MatrixPalette[input.indices[3]])*lastWeight;
    return output;
};

void TransformVertex (in VS_INPUT input, out VS_OUTPUT output)
{

    float3 inputN = normalize(input.normal);
    SKIN_OUTPUT skin = Skin4(input);
    output.position=skin.position;
    float3 normal = skin.normal;

    normal = normalize(mul(normal,World));

    float3 totalDiffuse = DiffuseColor*
         ((DirLight0Enable ? dot(-DirLight0Direction,normal) * DirLight0DiffuseColor : 0) +
         (DirLight1Enable ? dot(-DirLight1Direction,normal) * DirLight1DiffuseColor : 0) +
         (DirLight2Enable ?  dot(-DirLight2Direction,normal) * DirLight2DiffuseColor : 0));

    float3 viewDirection = normalize(EyePosition - mul(output.position,World));

    float3 spec0,spec1,spec2;
    if (DirLight0Enable)
    {
        float val = dot(-DirLight0Direction,normal);
        if (val < 0)
        {
            spec0 = float3(0,0,0);
        }
        else
        {
            spec0 = DirLight0SpecularColor *
                (pow(val*dot(reflect(DirLight0Direction,normal),viewDirection),SpecularPower));
        }
    }
    else
        spec0=float3(0,0,0);

    if (DirLight1Enable)
    {
        float val = dot(-DirLight1Direction,normal);
        if (val < 0)
        {
            spec1 = float3(0,0,0);
        }
        else
        {
            spec1 = DirLight1SpecularColor *
                (pow(val*dot(reflect(DirLight1Direction,normal),viewDirection),SpecularPower));
        }
    }
    else
        spec1=float3(0,0,0);

    if (DirLight2Enable)
    {
        float val = dot(-DirLight2Direction,normal);
        if (val < 0)
        {
            spec2 = float3(0,0,0);
        }
        else
        {
            spec2 = DirLight2SpecularColor *
                (pow(val*dot(reflect(DirLight2Direction,normal),viewDirection),SpecularPower));
        }
    }
    else
        spec2=float3(0,0,0);
    
    float3 totalSpecular = SpecularColor * (spec0+spec1+spec2);
    output.color.xyz = saturate(AmbientLightColor+totalDiffuse + totalSpecular);
    output.color.w=1.0;
    output.texcoord = input.texcoord;
    output.position = mul(output.position,World);
    output.distance = distance(EyePosition, output.position.xyz);
    output.position = mul(output.position,mul(View,Projection));
}



void TransformPixel (in PS_INPUT input, out PS_OUTPUT output)
{
    if (LightingEnable == false && TextureEnabled)
    {
        output.color.xyz = tex2D(TextureSampler,input.texcoord).xyz * saturate(EmissiveColor + DiffuseColor);
    }
    else if (LightingEnable == false)
    {
       output.color.xyz = saturate(EmissiveColor + DiffuseColor);
    }
    else
    {
        output.color.xyz = TextureEnabled ? tex2D(TextureSampler, input.texcoord).xyz  * input.color.xyz
            : input.color.xyz;
    }
    output.color.w   = 
         TextureEnabled ? tex2D(TextureSampler, input.texcoord).w * Alpha : Alpha;
    
    if (FogEnable)
    {
        float dist = (input.distance - FogStart) / (FogEnd - FogStart);
        dist = saturate(dist);
        float3 distv = float3(dist,dist,dist);
        distv = lerp(output.color.xyz,FogColor,distv);
        output.color.xyz = distv;
    }
}

technique TransformTechnique
{
    pass P0
    {
        VertexShader = compile vs_2_0 TransformVertex();
        PixelShader  = compile ps_2_0 TransformPixel();
    }
}

[Bullet] Static level geometry - boxes or triangle mesh?

16 September 2012 - 07:03 PM

Is there a recommended way to handle static level geometry in Bullet? I'm not sure whether I should use box shapes (and some convex hull shapes) or a triangle mesh shape.

My kinematic character controller works reasonably well with boxes, but there's a couple of issues when using triangle mesh shape and InternalEdgeUtility. I haven't figured out if they are problems with my code, the port, or InternalEdgeUtility. So if it happens to be the case that box shapes are the way to go, that would probably save me a considerable amount of debugging. One potential downside to the box shape approach is that it seems like creating a level with box shapes would be more time consuming.

If I were to use box shapes, how should I handle when walls intersect at non-right angles. Should I try to avoid overlap between the walls, which may require using convex hull shapes in some cases? Or is it not a problem?

Collision detection / response for enclosed 3d levels

01 August 2012 - 06:32 AM

I'm looking for methods of handling collision detection and response for enclosed 3d levels where walls are not necessarily axis-aligned, and parts of the level could be over or under other parts (so there are ramps, but the player cannot jump off of a higher section and land on a lower one). The player is able to shoot projectiles.

I'd like to avoid using a full 3d physics engine since it seems like overkill, and I'd like to avoid having a physically based character controller. Also, learning has priority over actually making a game.

The projectiles seem like they should be pretty easy to handle to me. I can treat them as points and do line segment vs plane intersection testing for the walls. I'd probably put the walls into a grid/octree/etc.

What I'm not sure about is handling collision detection/response between the player and the level. One idea I had was to use a sort of "navmesh" for determining where the player could walk. I would constrain the player's movement to the "navmesh" by tracking the triangle that they are currently on, and using BFS to find a path to their target location. I'd probably put the navmesh triangles into a grid/octree as well, to aid in finding the starting triangle when the player is spawned, for example. Having the navmesh might also be useful for when I get to NPCs.

I'm thinking the trickiest part of this approach would be the creation of the navmesh. I would like to be able to just cover the entire walkable area with a mesh in Blender/etc and then programmatically offset it based on the player's radius, which would allow me to treat the player as a point instead of a sphere. It seems like this would be tricky when the angle between two wall segments is greater than 180 degrees on the inside of the level (or less than 180 on the outside) since it would require additional vertices, and then I'd need to generate additional triangles.

Any suggestions? Thanks.

Sliding AABB collision - getting stuck on edges

10 October 2010 - 11:59 AM

I'm working on a 3D tile based game and I'm using AABB collision detection. For every cube that the player is intersecting, I find the axis along which the player is intersecting the cube the least, and push the player out of the cube along that axis.

Depending on the order that the cubes are checked in, this can cause problems when sliding along the edge of multiple cubes. I have created a diagram that should explain the problem:

http://imgur.com/mmK0W.png

Arrow #1 is the attempted movement of the player. The other arrows are the collision response.
In the left diagram, collision is tested against the right cube first, causing the player to be pushed to the left, and then upwards. (bad)
In the right diagram, collision is tested against the left cube first, causing the player to be pushed upwards, at which point the player is no longer intersecting the other cube. (good)
Any ideas on what the most efficient way to solve this might be? Or any better ways to handle the collision response?

Thank you.

PARTNERS