Google
 

Tuesday, April 24, 2007

Engine Design - RCModel

Now this class is probably the biggest deviation from the tutorial. I have added a number of fields and properties for my shaders, from the basic AmbientLightColor to and environment cube map, bump maps and height maps. I don't see any point in documenting these as they are pretty much run of the mill and are required for the shaders you use. So I am going to document the fundimental differences here.

New Fields

public bool UseBasicRender;
private float tick;
private float animSpeed;

UseBasicRender
This field (should have a property) is used as with Mike's original render method shaders using reflective cube mapping did not draw correctly, I don't know why, but they just didn't work. So I had to use a more basic draw method. So if this field is set to true then this basic method is used:


for (int msh = 0; msh < myModel.Meshes.Count; msh++)
{
    ModelMesh mesh = myModel.Meshes[msh];
    for (int prt = 0; prt < mesh.MeshParts.Count; prt++)
        mesh.MeshParts[prt].Effect = shader.Effect;
    mesh.Draw();
}



tick & animSpeed
This is how we decide how fast we want our shader animation to run.For examplt in the Microsoft HLSL exabmple it ripples the mesh at a given speed. The speed is set externaly in a Property called AnimationSpeed, this sets the animSpeed field. This is then passed to the shader.

New Properties

public BoundingSphere ObjectBoundingSphere
I added this property so I could get a bounding sphere that was not always positioned at 0,0,0


public BoundingSphere ObjectBoundingSphere
{
    get
    {
        BoundingSphere bs = new BoundingSphere(myModel.Meshes[0].BoundingSphere.Center + myPosition, myModel.Meshes[0].BoundingSphere.Radius);
        return bs;
    }
}



New Methods

protected override void DrawBounds(GraphicsDevice myDevice, Color col)
This method draws the bounding box for the mesh


protected override void DrawBounds(GraphicsDevice myDevice, Color col)
{
    List<BoundingBox> bounds = (List<BoundingBox>)((object[])myModel.Tag)[0];
    for (int b = 0; b < bounds.Count; b++)
    {
        myBounds = bounds[b];
        BuildBoxCorners();

        myDevice.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.LineList, points, 0, 8, index, 0, 12);
    }
}



public void UpdateAnimation()
This was added recently to update the bones of an animated mesh. This method is called at the top of the RenderChildren method.


public void UpdateAnimation()
{
    if (animationData != null)
    {
        Matrix[] m_bonetrans = new Matrix[animationData.m_bones.Count];

        currentAnimationFrame++;
        if (currentAnimationFrame >= animationData.m_timeframes.Count)
            currentAnimationFrame = 0;

        int i = 0;
        foreach (TimeFrame tf in animationData.m_timeframes.Values)
        {
            if (i == currentAnimationFrame)
            {
                for (int j = 0; j < tf.m_transforms.Count; j++)
                {
                    m_bonetrans[tf.m_transforms[j].m_boneindex] = tf.m_transforms[j].m_transform;
                }
                break;
            }
            i++;
        }
        Effect effect = RCShaderManager.GetShader(myShader).Effect;
        if(effect.Parameters["mWorldMatrixArray"] != null)
            effect.Parameters["mWorldMatrixArray"].SetValue(m_bonetrans);

        if (effect.Parameters["Bones"] != null)
            effect.Parameters["Bones"].SetValue(m_bonetrans);
    }
}



And finaly the modified public void SetMaterialProperties() that now takes into account Semantics and Annotations.


public void SetMaterialProperties()
{
    Effect effect = RCShaderManager.GetShader(myShader).Effect;

    for (int parm = 0; parm < effect.Parameters.Count; parm++)
    {
        string paramSemantic = "";
        paramSemantic = effect.Parameters[parm].Semantic;

        if (effect.Parameters[parm].Semantic != null)
        {
            switch (effect.Parameters[parm].Semantic.ToLower())
            {
                case "position": // Presume it's a light
                    for (int note = 0; note < effect.Parameters[parm].Annotations.Count; note++)
                    {
                        EffectAnnotation desc = effect.Parameters[parm].Annotations[note];

                        switch (desc.ParameterType)
                        {
                            case EffectParameterType.String:
                            switch (desc.ParameterClass)
                            {
                                case EffectParameterClass.Object:
                                    switch (desc.GetValueString().ToLower())
                                    {
                                        case "lightfromsky":
                                            effect.Parameters[parm].SetValue(myLightFromSky);
                                            break;
                                        case "directionallight":
                                        case "pointlight":
                                            effect.Parameters[parm].SetValue(myLightPosition);
                                            break;
                                    }
                                    break;
                            }
                            break;
                        }
                    }
                    break;
                case "ambient":
                    switch (effect.Parameters[parm].ParameterClass)
                    {
                        case EffectParameterClass.Vector: // Color
                            if (effect.Parameters[parm].Name.ToLower().IndexOf("light") != -1)
                                effect.Parameters[parm].SetValue(myLightAmbientIntensity);
                            else
                                effect.Parameters[parm].SetValue(myAmbientLightColor);
                            break;
                    }
                    break;
                case "diffuse":
                    switch (effect.Parameters[parm].ParameterClass)
                    {
                        case EffectParameterClass.Vector: // Color
                            if (effect.Parameters[parm].Name.ToLower().IndexOf("light") != -1)
                                effect.Parameters[parm].SetValue(myLightDiffuseColor);
                            else
                            {
                                bool loaded = false;
                                for (int an = 0; an < effect.Parameters[parm].Annotations.Count; an++)
                                {
                                    if (effect.Parameters[parm].Annotations[an].Name == "UIName")
                                    {
                                        switch (effect.Parameters[parm].Annotations[an].GetValueString().ToLower())
                                        {
                                            case "groundcolor":
                                                loaded = true;
                                                effect.Parameters[parm].SetValue(myGroundColor);
                                                break;
                                            case "skycolor":
                                                loaded = true;
                                                effect.Parameters[parm].SetValue(mySkyColor);
                                                break;
                                        }
                                        break;
                                    }
                                }
                                if (!loaded)
                                    effect.Parameters[parm].SetValue(myDiffuseColor);
                            }
                            break;
                    }
                    break;
                case "specular":
                    switch (effect.Parameters[parm].ParameterClass)
                    {
                        case EffectParameterClass.Vector: // Color
                            if (effect.Parameters[parm].Name.ToLower().IndexOf("light") != -1)
                                effect.Parameters[parm].SetValue(myLightSpecularColor);
                            else
                                effect.Parameters[parm].SetValue(mySpecularColor);
                            break;
                        case EffectParameterClass.Scalar: // Value
                            effect.Parameters[parm].SetValue(mySpecularPower);
                            break;
                        }
                        break;
                    case "environment":
                        if(myCube != null)
                            effect.Parameters[parm].SetValue(myCube);
                        else
                            if(myColorMap != null)
                                effect.Parameters[parm].SetValue(myColorMap);
                            break;
                        case "rcmaterialparameter":
                            switch (effect.Parameters[parm].ParameterClass)
                            {
                                case EffectParameterClass.Vector:
                                    for (int an = 0; an < effect.Parameters[parm].Annotations.Count; an++)
                                    {
                                        if (effect.Parameters[parm].Annotations[an].Name == "UIName")
                                        {
                                            switch (effect.Parameters[parm].Annotations[an].GetValueString().ToLower())
                                            {
                                                case "etas":
                                                    effect.Parameters[parm].SetValue(new Vector3(0.80f, 0.82f, 0.84f));
                                                    break;
                                            }
                                            break;
                                        }
                                    }
                                    break;
                                case EffectParameterClass.Scalar:
                                    for (int an = 0; an < effect.Parameters[parm].Annotations.Count; an++)
                                    {
                                        if (effect.Parameters[parm].Annotations[an].Name == "UIName")
                                        {
                                            switch (effect.Parameters[parm].Annotations[an].GetValueString().ToLower())
                                            {
                                                case "reflectivestrength":
                                                    effect.Parameters[parm].SetValue(1.0f);
                                                    break;
                                                case "refractstrength":
                                                    effect.Parameters[parm].SetValue(1.0f);
                                                    break;
                                            }
                                            break;
                                        }
                                    }
                                    break;
                                case EffectParameterClass.Object:
                                    for (int an = 0; an < effect.Parameters[parm].Annotations.Count; an++)
                                    {
                                        if (effect.Parameters[parm].Annotations[an].Name == "UIName")
                                        {
                                            switch (effect.Parameters[parm].Annotations[an].GetValueString().ToLower())
                                            {
                                                case "colormap":
                                                    effect.Parameters[parm].SetValue(myColorMap);
                                                    break;
                                                case "bumpmap":
                                                    effect.Parameters[parm].SetValue(myBumpMap);
                                                    break;
                                                case "heightmap":
                                                    effect.Parameters[parm].SetValue(myHeightMap);
                                                    break;
                                            }
                                            break;
                                        }
                                    }
                                    break;
                            }
                            break;
                        default:
                            break;
            }
        }
    }
}

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.