Showing posts with label animation. Show all posts
Showing posts with label animation. Show all posts

Sunday, June 6, 2010

XSI: Animate different instances at the same time

There is a bug/flaw when trying to animate individually different instances of the same model. Due to the model and animations are loaded only once (even if there are multiple models), models are shared.

One possible solution is to have one different file for each instance of the model. This is a bad design solution, due to we are replicating the same file but with a different name.

The second and best solution is to solve the actual flaw. The main problem is that every instance of the same model keeps track of the currentTime, instead of one per instance. The way to get around this is to:

1. Keep a local TimeSpan per instance of the model

2. Create an extension method of PlayBack().


public static void PlayBackAt( this XSIAnimationContent Animations, TimeSpan time, float blend )
{
if( (Animations.Loop) &&
(Animations.Duration > TimeSpan.Zero) )
{
long ticks = time.Ticks % Animations.Duration.Ticks;
time = TimeSpan.FromTicks(ticks);
}
Animations.CurrentTime = time;
foreach( KeyValuePair<string, XSIAnimationChannel> channel in Animations.Channels )
{
channel.Value.PlayBack(Animations.CurrentTime, blend);
}
}


This method should be called instead of the original PlayBack(). The extension method uses the old one but taking into account the local currentTime of each instance.

3. Call the PlayBackAt routine before the instance is drawn.

//------------------------------------------------------------
public void DrawModel( Game game, Camera camera )
{
Render();
this.model.DrawModel( game, camera, this );
}

//------------------------------------------------------------
private void Render()
{
TimeSpan elapsedTime = TimeSpan.FromTicks(
(long (gameTime.ElapsedGameTime.Ticks * this.thumbstick) );

if( this.model.Animations.Count > 0)
{
if( this.currentBlendTime < this.blendTime )
{
this.model.Animations[this.model.OldAnimationIndex].PlayBackAt( TimeSpan.Parse("0"), 1.0f );
this.currentBlendTime += (float)elapsedTime.TotalSeconds;
}
else
{
this.model.OldAnimationIndex = this.model.AnimationIndex;
this.currentBlendTime = this.blendTime;
}
if( this.model.AnimationIndex < this.model.Animations.Count )
{
if ( this.blendTime != 0.0 )
{
Blend =
this.currentBlendTime / this.blendTime;
}
this.model.Animations[currentAnimation].PlayBackAt( animationTimeElapsed, Blend );
}
}
}

Wednesday, April 21, 2010

Flaw in XSI: Skinned Vertex Shader

There is a flaw in the skinned vertex shader (xsi_defaultvs.hlsl) provided by AutoDesk SoftImage tool. In the VSSkinned vertex shader, the weighted position has not been transformed in the world space. This made the 3D model to ignore every transformation (translation and rotation) made on it. The line of code mistaken is:

// Skin the vertex position
float4 weightedposition = mul(IN.position, skinTransform);

should be changed into:

float4 weightedposition = mul(mul(IN.position, skinTransform), Model);

After this change you should be able to transform (translation, rotation and scale) your 3D model in the DrawModel() method in this way:

Model model = character.GetModel(); // my model
float rotation = character.GetRotation(); // desire rotation
Vector3 position = character.GetPosition(); // desire position
// transformation Matrix
Matrix worldMatrix = Matrix.CreateRotationY( rotation ) * Matrix.CreateTranslation( position );

UpdateSASData( game, camera );
Matrix[] bones = GetBones( model );
bool isSkinned = (bones.Length > 0);
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo( transforms ); // apply default transforms

foreach( ModelMesh mesh in model.Meshes )
{
//apply our transform to each mesh
this.SASData.Model = transforms[mesh.ParentBone.Index] * worldMatrix;
//...
}


Thanks to: http://www.matthughson.com/

Monday, April 12, 2010

Finite State Machine Tool

The main objective of this tool is to minimized the bottleneck that supposes animation development within the creation of a video game. Therefore, this tool is a bridge between the model software and the final game.

* Import animations from XSI to XNA using a modified XSI runtime pipeline
* Control the character locomotion via Finite State Machines
* Maintain the character locomotion and general animations within game easily before using them in the final version.
* Create a Performance Test. Animate an entire crowd of random characters at the same time.

More specific information and demonstrations can be found on the Finite State Machine page.