Google
 
Showing posts with label BoundingSphere. Show all posts
Showing posts with label BoundingSphere. Show all posts

Monday, July 23, 2007

Source Example 2 - Scene Picking & Targets



Moving on from example 1 but sticking with the Model and Scene class, this example shows how to apply picking objects from the scene and also how to apply a targeting reticle to a model using the Get2DCoors method.

For this to be done I have added the RandomchaosContentPipelineManager to the project, this gives the model class the ability to use the bounding box data.

You will see in the example screen above that the target reticle is not in the center of the model, this is because the skullocc.x file has it's center at the bottom of the model. I have also noticed a bug with the targeting code, if you target a model then rotate the camera 180 degrees away, you get the target reticle behind you.

Again to ensure the download works, you will have to reference the Randomchaos3Engine.dll and the RandomchaosContentPipelineManager.dll, the later is done by right clicking the project name in the project explorer, select properties, select the Content Pipeline tab remove the current setting and replace with the path you have for the dll on your system.

RC3DEModelExample2.zip

If you have any comments or issues with this example, please post them here :)

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;
            }
        }
    }
}