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