Beispiel #1
0
	MainApplication::ComponentCollection MainApplication::addDrawDebug(MeshCollider * collider, int level)
	{
		BVHNode * root = collider->m_bvh->root();

		Material * wireframe = new Material(Shader::find("shader"));
		wireframe->setAmbientColor(glm::vec4(1.0f));
		wireframe->setWireframe(true);

		std::vector<BVHNode *> nodes;
		collectBvhs(nodes, root, level, level);

		int leaves = 0;
		ComponentCollection components;

		for (unsigned i = 0; i < nodes.size(); i++) {
			BoundingSphere * bs = nodes[i]->m_bv;
			if (nodes[i]->m_isLeaf)
				leaves++;

			MeshObject * sphere = new MeshObject(MeshFactory::Sphere(glm::vec4(1.0f), 10), wireframe);

			sphere->transform().translate(bs->c);
			sphere->transform().translate(collider->transform().position());
			sphere->transform().scale(glm::vec3(1.0f) * bs->r);

			components.push_back(sphere);
		}

		Trace::info("Nodes at level %d: %d (%d leaves)\n", level, nodes.size(), leaves);

		return components;
	}
Beispiel #2
0
	void MainApplication::draw()
	{
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		for (ComponentIterator it = m_components.begin(); it != m_components.end(); ++it)
		{
			(*it)->draw();
		}

		if (m_debug)
		{
			DebugIterator dit = m_debugComponents.find(m_currentLevel);
			if (dit != m_debugComponents.end())
			{
				ComponentCollection components = dit->second;
				for (ComponentIterator it = components.begin(); it != components.end(); it++)
				{
					(*it)->draw();
				}
			}
		}

		std::stringstream ss;
		ss << "Cloth Simulation Demo" << std::endl;
		ss << std::setiosflags(std::ios::fixed) << std::setprecision(1);
		ss << std::endl;
		
		if (m_help) {
			ss << "<Space> Start/reset simulation" << std::endl;
			ss << "<Enter> Toggle BVH visualization" << std::endl;
			ss << "<+/-> Adjust BVH visualization level";
			if (m_debug) { ss << " (" << m_currentLevel << ")"; } ss << std::endl;
			ss << "<c> Toggle constrained corners: " << (m_constrained ? "true" : "false") << std::endl;
			ss << "<v> Toggle moving ball: " << (m_animate ? "true" : "false") << std::endl;
			ss << "<Numpad 1-9> Adjust wind speed" << std::endl;
			ss << "<h> Show this help (reduces fps)" << std::endl;
			ss << std::endl;
			ss << "Friction: " << SoftBody::FRICTION << std::endl;
			ss << "Iteration count: " << SoftBody::ITERATION_COUNT << std::endl;
			ss << "Cloth size: " << SoftBody::WIDTH << "x" << SoftBody::LENGTH << std::endl;
		}
		ss << "Wind: (" << SoftBody::WIND.x << ", " << SoftBody::WIND.y << ", " << SoftBody::WIND.z << ")" << std::endl;

		std::string text = ss.str();

		display_text(text.c_str(), 10, 15);

		GLenum err = glGetError();
		if (err != GL_NO_ERROR)
			Trace::error("OpenGL error: %d\n", err);
	}
void ComponentCollection::CopyTo(const Reflect::ElementPtr& destination)
{
    __super::CopyTo( destination );

    ComponentCollection* destCollection = Reflect::ObjectCast< ComponentCollection >( destination );
    if ( destCollection )
    {
        // Remove all attributes, we're going to bring them over manually
        destCollection->Clear(); 

        // For each component in this component collection
        Reflect::Registry* registry = Reflect::Registry::GetInstance();
        M_Component::const_iterator attrItr = m_Components.begin();
        M_Component::const_iterator attrEnd = m_Components.end();
        for ( ; attrItr != attrEnd; ++attrItr )
        {
            // Create a new copy of the component and try to add it to the destination
            const ComponentPtr& attrib = attrItr->second;
            ComponentPtr destAttrib = Reflect::AssertCast< ComponentBase >( registry->CreateInstance( attrib->GetClass() ) );
            if ( !CopyComponentTo( *destCollection, destAttrib, attrib ) )
            {
                // Component could not be added to the destination collection, check sibling classes
                const std::set<tstring>& derived = ( registry->GetClass( attrib->GetClass()->m_Base ) )->m_Derived;
                std::set<tstring>::const_iterator derivedItr = derived.begin();
                std::set<tstring>::const_iterator derivedEnd = derived.end();
                for ( ; derivedItr != derivedEnd; ++derivedItr )
                {
                    const Reflect::Class* currentType = Reflect::Registry::GetInstance()->GetClass(*derivedItr);
                    if ( currentType->m_TypeID != attrib->GetType() )
                    {
                        destAttrib = Reflect::AssertCast< ComponentBase >( registry->CreateInstance( currentType ) );
                        if ( destAttrib.ReferencesObject() )
                        {
                            if ( CopyComponentTo( *destCollection, destAttrib, attrib ) )
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
}
void ComponentCollection::CopyTo(Reflect::Object* object)
{
    Base::CopyTo( object );

    ComponentCollection* collection = Reflect::SafeCast< ComponentCollection >( object );
    if ( collection )
    {
        // Remove all attributes, we're going to bring them over manually
        collection->Clear(); 

        // For each component in this component collection
        Reflect::Registry* registry = Reflect::Registry::GetInstance();
        M_Component::const_iterator attrItr = m_Components.begin();
        M_Component::const_iterator attrEnd = m_Components.end();
        for ( ; attrItr != attrEnd; ++attrItr )
        {
            // Create a new copy of the component and try to add it to the destination
            const ComponentPtr& attrib = attrItr->second;
            ComponentPtr destAttrib = Reflect::AssertCast< ComponentBase >( registry->CreateInstance( attrib->GetMetaClass() ) );
            if ( !CopyComponentTo( *collection, destAttrib, attrib ) )
            {
                // Component could not be added to the destination collection, check sibling classes
                for ( const Composite* sibling = attrib->GetMetaClass()->m_Base->m_FirstDerived; sibling; sibling = sibling->m_NextSibling )
                {
                    if ( sibling != attrib->GetMetaClass() )
                    {
                        destAttrib = Reflect::AssertCast< ComponentBase >( registry->CreateInstance( Reflect::ReflectionCast< const MetaClass >( sibling ) ) );
                        if ( destAttrib.ReferencesObject() )
                        {
                            if ( CopyComponentTo( *collection, destAttrib, attrib ) )
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
    }
}
bool ComponentCollection::CopyComponentTo( ComponentCollection& destCollection, const ComponentPtr& destAttrib, const ComponentPtr& srcAttrib )
{
    bool inserted = false;
    Reflect::Registry* registry = Reflect::Registry::GetInstance();

    tstring unused;
    // If there is already an component in the destination slot, or the
    // component is not in the destination, but is allowed to be...
    if ( destCollection.ValidateComponent( destAttrib, unused ) )
    {
        // Component can be added to the destination collection, so do it!
        srcAttrib->CopyTo( destAttrib );
        destCollection.SetComponent( destAttrib, false );
        inserted = true;
    }
    else
    {
        ComponentPtr existing = destCollection.GetComponent( destAttrib->GetSlot() );
        if ( existing.ReferencesObject() )
        {
            destCollection.RemoveComponent( existing->GetSlot() );
            if ( destCollection.ValidateComponent( destAttrib, unused ) )
            {
                srcAttrib->CopyTo( destAttrib );
                destCollection.SetComponent( destAttrib, false );
                inserted = true;
            }
            else
            {
                destCollection.SetComponent( existing, false );
            }
        }
    }

    return inserted;
}
Beispiel #6
0
	void MainApplication::initScene()
	{
		m_components.clear();
		m_debugComponents.clear();
		g_world = SoftBodyWorld();
		g_body = 0;

		// Create wood material
		Material * woodMaterial = new Material(Shader::find("shader"));
		woodMaterial->setTexture(new Texture("resources/wood.bmp"));

		// Load bowl model
		MeshObject * bowl = new MeshObject(MeshFactory::FromFile("resources/bowl.ply"), woodMaterial);
		bowl->transform().translate(glm::vec3(0.0f, 2.0f, 0.0f));
		bowl->transform().update();

		// Load low-poly model of bowl for collision detection
		Mesh * lowpoly = MeshFactory::FromFile("resources/bowl-low.ply");

		MeshCollider * bowlCollider = new MeshCollider(bowl);
		bowlCollider->m_mesh = lowpoly;
		bowlCollider->m_bvh = BVH::constructFromMesh(lowpoly);
		CollisionDetector::instance()->addCollider(bowlCollider);

		m_components.push_back(bowl);

		// Create cloth material
		Material * clothMaterial = new Material(Shader::find("shader"));
		clothMaterial->setTexture(new Texture("resources/cloth.bmp"));
		clothMaterial->setDiffuseColor(glm::vec4(0.8f, 0.8f, 0.8f, 1.0f));
		clothMaterial->setAmbientColor(glm::vec4(0.3f, 0.3f, 0.3f, 1.0f));
		clothMaterial->setSpecularColor(glm::vec4(0.5f, 0.5f, 0.5f, 1.0f));

		// Create cloth mesh with attached soft body information
		MeshObject * cloth = SoftBody::createCloth(clothMaterial, &g_world, &g_body);
		cloth->transform().translate(glm::vec3(-2.5f, 5.0f, -2.5f));
		cloth->transform().update();

		m_components.push_back(cloth);

		// Create material for apple
		Material * appleMaterial = new Material(Shader::find("shader"));
		appleMaterial->setDiffuseColor(glm::vec4(0.9f));
		appleMaterial->setTexture(new Texture("resources/apple.bmp"));

		// Load apple model from file
		MeshObject * apple = new MeshObject(MeshFactory::FromFile("resources/apple.ply"), appleMaterial);
		apple->transform().translate(glm::vec3(0.0f, 3.0f, 10.0f));
		apple->transform().scale(glm::vec3(0.5f));

		// Create a mathematical sphere collider for the apple
		SphereCollider * sphereCollider = new SphereCollider(apple);
		CollisionDetector::instance()->addCollider(sphereCollider);

		m_components.push_back(apple);

		// Create animator that animates the apple
		KeyframeAnimator<glm::vec3> * anim = new KeyframeAnimator<glm::vec3>(apple, new LinearInterpolator<glm::vec3>, apple->transform().position());
		anim->addKeyframe(0.0f, glm::vec3(0.0f, 3.0f, 10.0f));
		anim->addKeyframe(20000.0f, glm::vec3(0.0f, 3.0f, -10.0f));
		anim->addKeyframe(40000.0f, glm::vec3(0.0f, 3.0f, 10.0f));
		m_ballAnimator = anim;

		// Create some debug spheres for the BVH
		int level = 0;
		while (true) {
			ComponentCollection components = addDrawDebug(bowlCollider, level);
			if (components.empty())
				break;

			m_debugComponents[level] = components;
			level++;
		}
	}