//----------------------------------------------------------------------------
Node* SimplePendulumFriction::CreatePendulum ()
{
	VertexFormat* vformat = VertexFormat::Create(2,
	                        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
	                        VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0);

	StandardMesh sm(vformat);

	// Pendulum rod.
	TriMesh* rod = sm.Cylinder(2, 8, 0.05f, 12.0f, true);
	rod->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, 10.0f));

	// The pendulum bulb.  Start with a sphere (to get the connectivity) and
	// then adjust the vertices to form a pair of joined cones.
	TriMesh* bulb = sm.Sphere(16, 32, 2.0f);
	VertexBufferAccessor vba(bulb);
	int numVertices = vba.GetNumVertices();
	int i;
	for (i = 0; i < numVertices; ++i)
	{
		Float3& pos = vba.Position<Float3>(i);
		float r = Mathf::Sqrt(pos[0]*pos[0] + pos[1]*pos[1]);
		float z = pos[2] + 2.0f;
		if (z >= 2.0f)
		{
			z = 4.0f - r;
		}
		else
		{
			z = r;
		}
		pos[2] = z;
	}

	// Translate the pendulum joint to the origin for the purpose of
	// rotation.
	for (i = 0; i < numVertices; ++i)
	{
		vba.Position<Float3>(i)[2] -= 16.0f;
	}
	bulb->UpdateModelSpace(Visual::GU_NORMALS);

	vba.ApplyTo(rod);
	numVertices = vba.GetNumVertices();
	for (i = 0; i < numVertices; ++i)
	{
		vba.Position<Float3>(i)[2] -= 16.0f;
	}
	rod->UpdateModelSpace(Visual::GU_NORMALS);

	// Group the objects into a single subtree.
	mPendulum = new0 Node();
	mPendulum->AttachChild(rod);
	mPendulum->AttachChild(bulb);

	// Translate back to original model position.
	mPendulum->LocalTransform.SetTranslate(APoint(0.0f, 0.0f, 16.0f));

	// Add a material for coloring.
	Float4 black(0.0f, 0.0f, 0.0f, 1.0f);
	Float4 white(1.0f, 1.0f, 1.0f, 1.0f);
	Material* material = new0 Material();
	material->Emissive = black;
	material->Ambient = Float4(0.1f, 0.1f, 0.1f, 1.0f);
	material->Diffuse = Float4(0.99607f, 0.83920f, 0.67059f, 1.0f);
	material->Specular = black;

	// Use two lights to illuminate the pendulum.
	Light* light[2];
	light[0] = new0 Light(Light::LT_DIRECTIONAL);
	light[0]->Ambient = white;
	light[0]->Diffuse = white;
	light[0]->Specular = black;
	light[0]->SetDirection(AVector(-1.0f, -1.0f, 0.0f));

	light[1] = new0 Light(Light::LT_DIRECTIONAL);
	light[1]->Ambient = white;
	light[1]->Diffuse = white;
	light[1]->Specular = black;
	light[1]->SetDirection(AVector(+1.0f, -1.0f, 0.0f));

	// TODO:  The following code is used to piece together an effect with
	// two passes.  It is better to write an effect whose vertex shader
	// has constants corresponding to the two lights (for a single-pass
	// effect).
	LightDirPerVerEffect* effect = new0 LightDirPerVerEffect();
	VisualTechnique* technique = effect->GetTechnique(0);
	VisualPass* pass0 = technique->GetPass(0);
	VisualPass* pass1 = new0 VisualPass();
	pass1->SetVertexShader(pass0->GetVertexShader());
	pass1->SetPixelShader(pass0->GetPixelShader());
	AlphaState* astate = new0 AlphaState();
	astate->BlendEnabled = true;
	astate->SrcBlend = AlphaState::SBM_ONE;
	astate->DstBlend = AlphaState::DBM_ONE;
	pass1->SetAlphaState(astate);
	pass1->SetCullState(pass0->GetCullState());
	pass1->SetDepthState(pass0->GetDepthState());
	pass1->SetStencilState(pass0->GetStencilState());
	pass1->SetOffsetState(pass0->GetOffsetState());
	pass1->SetWireState(pass0->GetWireState());
	technique->InsertPass(pass1);

	VisualEffectInstance* instance = new0 VisualEffectInstance(effect, 0);
	for (int pass = 0; pass < 2; ++pass)
	{
		instance->SetVertexConstant(pass, 0,
		                            new0 PVWMatrixConstant());
		instance->SetVertexConstant(pass, 1,
		                            new0 CameraModelPositionConstant());
		instance->SetVertexConstant(pass, 2,
		                            new0 MaterialEmissiveConstant(material));
		instance->SetVertexConstant(pass, 3,
		                            new0 MaterialAmbientConstant(material));
		instance->SetVertexConstant(pass, 4,
		                            new0 MaterialDiffuseConstant(material));
		instance->SetVertexConstant(pass, 5,
		                            new0 MaterialSpecularConstant(material));
		instance->SetVertexConstant(pass, 6,
		                            new0 LightModelDVectorConstant(light[pass]));
		instance->SetVertexConstant(pass, 7,
		                            new0 LightAmbientConstant(light[pass]));
		instance->SetVertexConstant(pass, 8,
		                            new0 LightDiffuseConstant(light[pass]));
		instance->SetVertexConstant(pass, 9,
		                            new0 LightSpecularConstant(light[pass]));
		instance->SetVertexConstant(pass, 10,
		                            new0 LightAttenuationConstant(light[pass]));
	}

	rod->SetEffectInstance(instance);
	bulb->SetEffectInstance(instance);

	return mPendulum;
}
//----------------------------------------------------------------------------
void IntersectingBoxes::CreateScene ()
{
    // Create some axis-aligned boxes for intersection testing.
    const int imax = 16;
    int i;
    for (i = 0; i < imax; ++i)
    {
        float xMin = 0.5f*mSize*Mathf::SymmetricRandom();
        float xMax = xMin + Mathf::IntervalRandom(8.0f, 32.0f);
        float yMin = 0.5f*mSize*Mathf::SymmetricRandom();
        float yMax = yMin + Mathf::IntervalRandom(8.0f, 32.0f);
        float zMin = 0.5f*mSize*Mathf::SymmetricRandom();
        float zMax = zMin + Mathf::IntervalRandom(8.0f, 32.0f);
        mBoxes.push_back(
            AxisAlignedBox3f(xMin, xMax, yMin, yMax, zMin, zMax));
    }
    mManager = new0 BoxManagerf(mBoxes);

    // Scene graph for the visual representation of the boxes.
    mScene = new0 Node();
    mWireState = new0 WireState();
    mRenderer->SetOverrideWireState(mWireState);

    // Effects for boxes, blue for nonintersecting and red for intersecting.
    Float4 black(0.0f, 0.0f, 0.0f, 1.0f);
    Float4 white(1.0f, 1.0f, 1.0f, 1.0f);
    Material* blueMaterial = new0 Material();
    blueMaterial->Emissive = black;
    blueMaterial->Ambient = Float4(0.25f, 0.25f, 0.25f, 1.0f);
    blueMaterial->Diffuse = Float4(0.0f, 0.0f, 1.0f, 1.0f);
    blueMaterial->Specular = black;

    Material* redMaterial = new0 Material();
    redMaterial->Emissive = black;
    redMaterial->Ambient = Float4(0.25f, 0.25f, 0.25f, 1.0f);
    redMaterial->Diffuse = Float4(1.0f, 0.0f, 0.0f, 1.0f);
    redMaterial->Specular = black;

    // A light for the effects.
    Light* light = new0 Light(Light::LT_DIRECTIONAL);
    light->Ambient = white;
    light->Diffuse = white;
    light->Specular = black;
    light->SetDirection(AVector::UNIT_Z);

    LightDirPerVerEffect* effect = new0 LightDirPerVerEffect();
    mNoIntersectEffect = effect->CreateInstance(light, blueMaterial);
    mIntersectEffect = effect->CreateInstance(light, redMaterial);

    // Create visual representations of the boxes.
    VertexFormat* vformat = VertexFormat::Create(2,
        VertexFormat::AU_POSITION, VertexFormat::AT_FLOAT3, 0,
        VertexFormat::AU_NORMAL, VertexFormat::AT_FLOAT3, 0);

    for (i = 0; i < imax; ++i)
    {
        APoint center(
            0.5f*(mBoxes[i].Min[0] + mBoxes[i].Max[0]),
            0.5f*(mBoxes[i].Min[1] + mBoxes[i].Max[1]),
            0.5f*(mBoxes[i].Min[2] + mBoxes[i].Max[2]));

        Transform transform;
        transform.SetTranslate(center);

        float xExtent = 0.5f*(mBoxes[i].Max[0] - mBoxes[i].Min[0]);
        float yExtent = 0.5f*(mBoxes[i].Max[1] - mBoxes[i].Min[1]);
        float zExtent = 0.5f*(mBoxes[i].Max[2] - mBoxes[i].Min[2]);

        StandardMesh sm(vformat, true, false, &transform);
        TriMesh* mesh = sm.Box(xExtent, yExtent, zExtent);

        mesh->SetEffectInstance(mNoIntersectEffect);
        mScene->AttachChild(mesh);
    }
}
//----------------------------------------------------------------------------
VisualEffectInstance* LightDirPerVerEffect::CreateUniqueInstance (
    Light* light, Material* material)
{
	LightDirPerVerEffect* effect = new0 LightDirPerVerEffect();
	return effect->CreateInstance(light, material);
}