void CollisionSolver::UpdateDiagnostics(const Simplex& simplex, 
                                        const D3DXVECTOR3& furthestPoint)
{
    if(m_engine->diagnostic()->AllowDiagnostics(Diagnostic::COLLISION))
    {
        const float radius = 0.1f;
        const float normalLength = 1.5f;
        D3DXVECTOR3 origin(0.0, 0.0, 0.0);

        m_engine->diagnostic()->UpdateSphere(Diagnostic::COLLISION,
            "OriginPoint", Diagnostic::WHITE, origin, radius);

        m_engine->diagnostic()->UpdateSphere(Diagnostic::COLLISION, 
            "FurthestPoint", Diagnostic::MAGENTA, furthestPoint, radius);

        const auto& borders = simplex.GetBorderEdges();
        for(unsigned int i = 0; i < borders.size(); ++i)
        {
            m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION,
                "BorderEdge" + StringCast(i), Diagnostic::RED, 
                simplex.GetPoint(borders[i].indices[0]), 
                simplex.GetPoint(borders[i].indices[1]));                    
        }

        const auto& faces = simplex.GetFaces();
        for(unsigned int i = 0; i < faces.size(); ++i)
        {
            if(faces[i].alive)
            {
                std::string id = StringCast(i);
                const Face& face = faces[i];

                const D3DXVECTOR3 center = simplex.GetFaceCenter(i);
                const D3DXVECTOR3& normal = face.normal * normalLength;
                const D3DXVECTOR3& pointA = simplex.GetPoint(face.indices[0]);
                const D3DXVECTOR3& pointB = simplex.GetPoint(face.indices[1]);
                const D3DXVECTOR3& pointC = simplex.GetPoint(face.indices[2]);

                m_engine->diagnostic()->UpdateSphere(Diagnostic::COLLISION, 
                    "sCenter" + id, Diagnostic::BLUE, center, radius);

                m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION, 
                    "sNormal" + id, Diagnostic::BLUE, center, center + normal);

                m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION, 
                    "sLine1" + id, Diagnostic::YELLOW, pointA, pointB);

                m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION, 
                    "sLine2" + id, Diagnostic::YELLOW, pointA, pointC);

                m_engine->diagnostic()->UpdateLine(Diagnostic::COLLISION,
                    "sLine3" + id, Diagnostic::YELLOW, pointC, pointB);
            }
        }
    }
}
void CollisionMesh::DrawDiagnostics()
{
    if(m_draw && m_geometry &&
        m_engine->diagnostic()->AllowDiagnostics(Diagnostic::MESH))
    {
        // Render world vertices
        const std::string id = StringCast(this);
        const float vertexRadius = 0.1f;
        const auto& vertices = GetVertices();
        for(unsigned int i = 0; i < vertices.size(); ++i)
        {
            m_engine->diagnostic()->UpdateSphere(Diagnostic::MESH,
                "0" + StringCast(i) + id, Diagnostic::RED, 
                vertices[i], vertexRadius);
        }

        // Render face normals
        m_geometry->UpdateDiagnostics(*m_engine->diagnostic(), m_world.GetMatrix());

        // Render OABB for diagnostic mesh
        auto getPointColor = [=](int index) -> Diagnostic::Colour
        {
            return index == MINBOUND || index == MAXBOUND ?
                Diagnostic::BLUE : Diagnostic::MAGENTA;
        };

        const float radius = 0.2f;
        std::string corner;
        for(unsigned int i = 0; i < CORNERS/2; ++i)
        {
            corner = StringCast(i);
            
            m_engine->diagnostic()->UpdateSphere(Diagnostic::MESH,
                "CornerA" + corner + id, getPointColor(i), m_oabb[i], radius);

            m_engine->diagnostic()->UpdateSphere(Diagnostic::MESH,
                "CornerB" + corner + id, getPointColor(i+4), m_oabb[i+4], radius);

            m_engine->diagnostic()->UpdateLine(Diagnostic::MESH,
                "LineA" + corner + id, Diagnostic::MAGENTA, 
                m_oabb[i], m_oabb[i+1 >= 4 ? 0 : i+1]);
            
            m_engine->diagnostic()->UpdateLine(Diagnostic::MESH,
                "LineB" + corner + id, Diagnostic::MAGENTA, 
                m_oabb[i+4], m_oabb[i+5 >= CORNERS ? 4 : i+5]);
                
            m_engine->diagnostic()->UpdateLine(Diagnostic::MESH,
                "LineC" + corner + id, Diagnostic::MAGENTA, 
                m_oabb[i], m_oabb[i+4]);
        }

        // Render radius of diagnostic mesh in wireframe
        m_engine->diagnostic()->UpdateSphere(Diagnostic::MESH,
            "Radius" + id, Diagnostic::WHITE, GetPosition(), GetRadius());
    }
}
Esempio n. 3
0
int Octree::RenderPartition(const std::unique_ptr<Partition>& partition)
{
    int nodeCount = 0;

    // Render all children of this partition
    const auto& children = partition->GetChildren();
    for(const std::unique_ptr<Partition>& child : children)
    {
        nodeCount += RenderPartition(child);
    }

    // Only render the root children and onwards if they have nodes
    if(partition->GetLevel() > 0 && partition->HasNodes())
    {
        const float size = partition->GetSize();
        const D3DXVECTOR3 minBounds = partition->GetMinBounds();
        std::array<D3DXVECTOR3, CUBE_POINTS> corners =
        {
            // top four corners
            minBounds,
            minBounds + D3DXVECTOR3(size, 0, 0),
            minBounds + D3DXVECTOR3(size, -size, 0),
            minBounds + D3DXVECTOR3(0, -size, 0),
            
            // bottom four corners
            minBounds + D3DXVECTOR3(0, 0, size),
            minBounds + D3DXVECTOR3(size, 0, size),
            minBounds + D3DXVECTOR3(size, -size, size),
            minBounds + D3DXVECTOR3(0, -size, size)
        };
            
        const std::string& id = partition->GetID();
        auto colour = partition->GetColor();

        for(int i = 0, j = SQUARE_POINTS; i < SQUARE_POINTS; ++i, ++j)
        {
            m_engine->diagnostic()->UpdateLine(Diagnostic::OCTREE, 
                id + StringCast(i) + "1", colour, 
                corners[i], corners[i+1 >= SQUARE_POINTS ? 0 : i+1]);
            
            m_engine->diagnostic()->UpdateLine(Diagnostic::OCTREE, 
                id + StringCast(i) + "2", colour, 
                corners[j], corners[j+1 >= CUBE_POINTS ? SQUARE_POINTS : j+1]);
            
            m_engine->diagnostic()->UpdateLine(Diagnostic::OCTREE,
                id + StringCast(i) + "3", colour, 
                corners[i], corners[j]);
        }
    }
    return nodeCount + static_cast<int>(partition->GetNodes().size());
}
Esempio n. 4
0
void Scene::PreCollisionUpdate(bool pressed, const D3DXVECTOR2& direction,
        const Matrix& world, const Matrix& invProjection, float deltatime)
{
    if(m_engine->diagnostic()->AllowDiagnostics(Diagnostic::MESH))
    {
        m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "QueueFront", 
            Diagnostic::WHITE, StringCast(m_open.empty() ? 0 : m_open.front()));

        m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "QueueSize", 
            Diagnostic::WHITE, StringCast(m_open.size()));

        m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "SelectedMesh", 
            Diagnostic::WHITE, StringCast(m_selectedMesh));

        if(m_diagnosticMesh != NO_INDEX)
        {
            const auto& mesh = m_meshes[m_diagnosticMesh];
            if(mesh->IsVisible())
            {
                const auto& collision = m_meshes[m_diagnosticMesh]->GetCollisionMesh();
                const Partition* partition = collision.GetPartition();
                const D3DXVECTOR3& velocity = collision.GetVelocity();
                const D3DXVECTOR3 scale = collision.GetLocalScale();

                m_manipulator->UpdateDiagnostics(m_meshes[m_diagnosticMesh]);

                m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "PartitionID", 
                    Diagnostic::WHITE, partition ? partition->GetID() : "None", true);

                m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "Velocity", 
                    Diagnostic::WHITE, StringCast(velocity.x) + " " +
                    StringCast(velocity.y) + " " + StringCast(velocity.z), true);

                m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "LocalScale", 
                    Diagnostic::WHITE, StringCast(scale.x) + " " +
                    StringCast(scale.y) + " " + StringCast(scale.z), true);
            }
        }
    }

    if(m_selectedMesh != NO_INDEX)
    {
        m_manipulator->UpdateState(m_meshes[m_selectedMesh],
            direction, world, invProjection, pressed, deltatime);
    }

    std::for_each(m_meshes.begin(), m_meshes.end(), [deltatime](const MeshPtr& mesh)
    {
        if(mesh->IsVisible())
        {
            mesh->Animate(deltatime);
        }
    });
}
Esempio n. 5
0
void Geometry::UpdateDiagnostics(Diagnostic& renderer, const D3DXMATRIX& world)
{
    if(renderer.AllowDiagnostics(Diagnostic::MESH))
    {
        std::string id = StringCast(this);
        const auto& faces = GetFaces();
        const float normalsize = 0.6f;
        for(unsigned int i = 0; i < faces.size(); ++i)
        {
            D3DXVECTOR3 center, normal;
            D3DXVec3TransformCoord(&center, &faces[i].center, &world);
            D3DXVec3TransformNormal(&normal, &faces[i].normal, &world);
            D3DXVec3Normalize(&normal, &normal);

            renderer.UpdateLine(Diagnostic::MESH, "FaceNormal" + 
                StringCast(i) + id, Diagnostic::CYAN, 
                center, center + (normal * normalsize));
        }
    }
}
Esempio n. 6
0
void Timer::UpdateTimer()
{
    QueryPerformanceCounter(&m_timer);
    double currentTime = static_cast<double>(m_timer.QuadPart);

    double deltatime = (currentTime - m_previousTime) / m_frequency;
    m_deltaTimeCounter += deltatime;
    if (m_deltaTimeCounter >= 1.0) //one second has passed
    {
        m_deltaTimeCounter = 0.0;
        m_fps = m_fpsCounter;
        m_fpsCounter = 0;
    }

    m_deltaTime = max(deltatime, DT_MINIMUM);
    m_deltaTime = min(m_deltaTime, DT_MAXIMUM);

    if(m_engine->diagnostic()->AllowDiagnostics(Diagnostic::TEXT))
    {
        m_engine->diagnostic()->UpdateText(Diagnostic::TEXT,
            "FramePerSec", Diagnostic::WHITE, StringCast(m_fps));

        m_engine->diagnostic()->UpdateText(Diagnostic::TEXT,
            "DeltaTime", Diagnostic::WHITE, StringCast(deltatime));

        m_engine->diagnostic()->UpdateText(Diagnostic::TEXT,
            "CappedDeltaTime", Diagnostic::WHITE, StringCast(m_deltaTime));

        if(m_forceDeltatime)
        {
            m_engine->diagnostic()->UpdateText(Diagnostic::TEXT,
                "ForcedDeltaTime", Diagnostic::YELLOW, 
                StringCast(m_forcedDeltatime), true);
        }
    }
    
    ++m_fpsCounter; //increment frame counter
    m_previousTime = currentTime;
}
Esempio n. 7
0
void Picking::SolvePicking()
{
    if(Diagnostic::AllowText())
    {
        Diagnostic::UpdateText("DistanceToPick", Diagnostic::WHITE, 
            StringCast(m_distanceToMesh == FLT_MAX ? 0.0f : m_distanceToMesh));
    }

    if(m_mesh)
    {
        m_mesh->OnPickMesh();
    }
}
Esempio n. 8
0
void Diagnostic::UpdateText(const std::string& id, Diagnostic::Colour color, bool increaseCounter)
{
    if(sm_diag->m_textmap.find(id) == sm_diag->m_textmap.end())
    {
        sm_diag->m_textmap.insert(TextMap::value_type(id,DiagText())); 
        sm_diag->m_textmap[id].counter = 0;
    }
    else if(increaseCounter)
    {
        ++sm_diag->m_textmap[id].counter;
    }
    sm_diag->m_textmap[id].color = sm_diag->m_colourmap[color];
    sm_diag->m_textmap[id].text = id + ": " + StringCast(sm_diag->m_textmap[id].counter);
}
Esempio n. 9
0
void Particle::UpdateDiagnostics(Diagnostic& renderer)
{
    if(renderer.AllowDiagnostics(Diagnostic::TEXT))
    {
        renderer.UpdateText(Diagnostic::TEXT, "Particle Delta",
            Diagnostic::WHITE, StringCast(m_positionDelta.y));;

        renderer.UpdateText(Diagnostic::TEXT, 
            "Particle Collision", Diagnostic::WHITE, std::string(
            (m_collision->IsCollidingWith(Geometry::NONE) ? "NONE " : "")) +
            (m_collision->IsCollidingWith(Geometry::SPHERE) ? "SPHERE " : "") +
            (m_collision->IsCollidingWith(Geometry::BOX) ? "BOX " : "") +
            (m_collision->IsCollidingWith(Geometry::CYLINDER) ? "CYLINDER " : ""));
    }
}
Esempio n. 10
0
void Octree::RenderDiagnostics()
{
    if(m_engine->diagnostic()->AllowDiagnostics(Diagnostic::OCTREE))
    {
        int nodeCount = static_cast<int>(m_octree->GetNodes().size());

        const auto& children = m_octree->GetChildren();
        for(const std::unique_ptr<Partition>& child : children)
        {
            nodeCount += RenderPartition(child);
        }

        m_engine->diagnostic()->UpdateText(Diagnostic::OCTREE,
            "NodeCount", Diagnostic::WHITE, StringCast(nodeCount));
    }
}
Esempio n. 11
0
void Manipulator::UpdateDiagnostics(const MeshPtr selectedMesh)
{
    const float length = 5.0f;
    const auto position = selectedMesh->Position();

    m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "SelectedTool", 
        Diagnostic::WHITE, GetDescription(m_selectedTool));

    m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "SelectedAxis", 
        Diagnostic::WHITE, GetDescription(m_selectedAxis));

    m_engine->diagnostic()->UpdateText(Diagnostic::MESH, "AnimationPoints",
        Diagnostic::WHITE, StringCast(selectedMesh->GetAnimationPoints().size()));

    m_engine->diagnostic()->UpdateLine(Diagnostic::MESH, "MeshXaxis", 
        Diagnostic::YELLOW, position, position + (selectedMesh->Right() * length));

    m_engine->diagnostic()->UpdateLine(Diagnostic::MESH, "MeshYaxis", 
        Diagnostic::RED, position, position + (selectedMesh->Up() * length));

    m_engine->diagnostic()->UpdateLine(Diagnostic::MESH, "MeshZaxis", 
        Diagnostic::GREEN, position, position + (selectedMesh->Forward() * length));
}
Esempio n. 12
0
void Manipulator::UpdateState(Manipulator::MeshPtr mesh, const D3DXVECTOR2& direction, 
    const Matrix& world, const Matrix& invProjection, bool pressed, float deltatime)
{
    if(m_selectedTool == NONE)
    {
        return;
    }

    // Ensure the tool axis are aligned with the mesh axis
    std::for_each(m_tools[m_selectedTool]->axis.begin(), 
        m_tools[m_selectedTool]->axis.end(), [&mesh](const MeshPtr& axis)
    {
        axis->SetRotationMatrix(mesh->GetRotationMatrix());
    });

    if(pressed)
    {
        if(m_selectedAxis != NO_AXIS && D3DXVec2Length(&direction) > 0.0f)
        {
            D3DXVECTOR3 axis;
            switch(m_selectedAxis)
            {
            case X_AXIS:
                axis = mesh->Right();
                break;
            case Y_AXIS:
                axis = mesh->Up();
                break;
            case Z_AXIS:
                axis = mesh->Forward();
                break;
            }

            D3DXVECTOR3 mouseDirection(direction.x, direction.y, CAMERA_NEAR);
            mouseDirection.x *= -1.0f;

            // Transform the screen space mouse direction into global 3D coordinates
            // Camera world matrix is the inverse view matrix
            D3DXVec3TransformNormal(&mouseDirection, &mouseDirection, &invProjection.GetMatrix());
            D3DXVec3TransformNormal(&mouseDirection, &mouseDirection, &world.GetMatrix());

            D3DXVec3Normalize(&mouseDirection, &mouseDirection);
            D3DXVec3Normalize(&axis, &axis);

            const float dot = D3DXVec3Dot(&axis, &mouseDirection);
            const float angle = RadToDeg(std::acos(dot));
            const float speed = fabs(dot) * (angle > 90.0f ? -1.0f : 1.0f) * deltatime;

            if(m_engine->diagnostic()->AllowDiagnostics(Diagnostic::MESH))
            {
                m_engine->diagnostic()->UpdateLine(Diagnostic::MESH,
                    "MouseDirection3D", Diagnostic::WHITE, mesh->Position(),
                    mesh->Position() + mouseDirection * 20.0f);

                m_engine->diagnostic()->UpdateText(Diagnostic::MESH,
                    "MovementDot", Diagnostic::WHITE, StringCast(dot));

                m_engine->diagnostic()->UpdateText(Diagnostic::MESH,
                    "MovementAngle", Diagnostic::WHITE, StringCast(angle));
            }

            switch(m_selectedTool)
            {
            case ROTATE:
                RotateMesh(mesh, speed * ROTATION_SPEED);
                break;
            case MOVE:
                mesh->ResetAnimation();
                TranslateMesh(mesh, speed * TRANSLATION_SPEED);
                break;
            case SCALE:
                ScaleMesh(mesh, speed * SCALE_SPEED);
                break;
            case ANIMATE:
                AnimateMesh(mesh, speed * TRANSLATION_SPEED);
                break;
            }
        }
    }

    if(m_selectedTool == ANIMATE)
    {
        if(mesh->GetAnimationPoints().empty() || (!pressed && m_saveAnimation))
        {
            m_saveAnimation = false;
            mesh->SavePosition();
        }
    }
}