Beispiel #1
0
void GLWidget::TraceOneStep()
{
    if(_traceList.size() == 0)
    {
        _isTracingDone = false;

        AnIndex startIdx(0, 0);

        _traceList.push_back(startIdx); // put in list
        _cells[startIdx.x][startIdx.y]._isVisited = true; // mark
        _cells[startIdx.x][startIdx.y]._directionType = DirectionType::DIR_UPRIGHT; // (0,0) always upright or downleft

        _tilePainter->SetTiles(_cells, _traceList, _gridSpacing, _isTracingDone);
        this->repaint();
    }
    else if(!_isTracingDone)
    {
        AnIndex curIdx = _traceList[_traceList.size() - 1];
        _cells[curIdx.x][curIdx.y]._isVisited = true;

        DirectionType curDir =_cells[curIdx.x][curIdx.y]._directionType;

        AnIndex urIdx(curIdx.x + 1, curIdx.y - 1);    // up right
        AnIndex drIdx(curIdx.x + 1, curIdx.y + 1);    // down right
        AnIndex dlIdx(curIdx.x - 1, curIdx.y + 1);    // down left
        AnIndex ulIdx(curIdx.x - 1, curIdx.y - 1);    // up left

        AnIndex rIdx(curIdx.x + 1, curIdx.y    );     // right
        AnIndex dIdx(curIdx.x    , curIdx.y + 1);     // down
        AnIndex lIdx(curIdx.x - 1, curIdx.y    );     // left
        AnIndex uIdx(curIdx.x    , curIdx.y - 1);     // up

        // point-to-line intersection
        AVector endVec;
        if(curDir == DirectionType::DIR_UPRIGHT)
            { endVec = AVector(rIdx.x  * _gridSpacing, rIdx.y * _gridSpacing); }
        else if(curDir == DirectionType::DIR_DOWNRIGHT)
            { endVec = AVector(drIdx.x  * _gridSpacing, drIdx.y * _gridSpacing); }
        else if(curDir == DirectionType::DIR_DOWNLEFT)
            { endVec = AVector(dIdx.x  * _gridSpacing, dIdx.y * _gridSpacing); }
        else if(curDir == DirectionType::DIR_UPLEFT)
            { endVec = AVector(curIdx.x  * _gridSpacing, curIdx.y * _gridSpacing); }
        LineType hitType = GetLineIntersection(endVec);

        // enter
        if(curDir == DirectionType::DIR_RIGHT &&
           IsValid(rIdx) &&
           _cells[rIdx.x][rIdx.y]._straightness == Straightness::ST_HORIZONTAL)
        {
            //std::cout << "[a] " << "right --> right" << " - " << rIdx.x << " " << rIdx.y << "\n";
            _traceList.push_back(rIdx);
            _cells[rIdx.x][rIdx.y]._directionType = DirectionType::DIR_RIGHT;
            _cells[rIdx.x][rIdx.y]._tempDirection = _cells[curIdx.x][curIdx.y]._tempDirection;
        }
        else if(curDir == DirectionType::DIR_LEFT &&
                IsValid(lIdx) &&
                _cells[lIdx.x][lIdx.y]._straightness == Straightness::ST_HORIZONTAL)
        {
            //std::cout << "[b] " << "left --> left" << " - " << lIdx.x << " " << lIdx.y << "\n";
            _traceList.push_back(lIdx);
            _cells[lIdx.x][lIdx.y]._directionType = DirectionType::DIR_LEFT;
            _cells[lIdx.x][lIdx.y]._tempDirection = _cells[curIdx.x][curIdx.y]._tempDirection;
        }
        else if(curDir == DirectionType::DIR_UP &&
                IsValid(uIdx) &&
                _cells[uIdx.x][uIdx.y]._straightness == Straightness::ST_VERTICAL)
        {
            //std::cout << "[c] " << "up --> up" << " - " << uIdx.x << " " << uIdx.y << "\n";
            _traceList.push_back(uIdx);
            _cells[uIdx.x][uIdx.y]._directionType = DirectionType::DIR_UP;
            _cells[uIdx.x][uIdx.y]._tempDirection = _cells[curIdx.x][curIdx.y]._tempDirection;
        }
        else if(curDir == DirectionType::DIR_DOWN &&
                IsValid(dIdx) &&
                _cells[dIdx.x][dIdx.y]._straightness == Straightness::ST_VERTICAL)
        {
            //std::cout << "[d] " << "down --> down" << " - " << dIdx.x << " " << dIdx.y << "\n";
            _traceList.push_back(dIdx);
            _cells[dIdx.x][dIdx.y]._directionType = DirectionType::DIR_DOWN;
            _cells[dIdx.x][dIdx.y]._tempDirection = _cells[curIdx.x][curIdx.y]._tempDirection;
        }

        // out
        else if(curDir == DirectionType::DIR_RIGHT &&
           IsValid(rIdx) &&
           _cells[rIdx.x][rIdx.y]._straightness == Straightness::ST_DIAGONAL)
        {
            //std::cout << "[e] " << "right --> out" << " - " << rIdx.x << " " << rIdx.y << "\n";
            _traceList.push_back(rIdx);
            _cells[rIdx.x][rIdx.y]._directionType = _cells[curIdx.x][curIdx.y]._tempDirection;
        }
        else if(curDir == DirectionType::DIR_LEFT &&
                IsValid(lIdx) &&
                _cells[lIdx.x][lIdx.y]._straightness == Straightness::ST_DIAGONAL)
        {
            //std::cout << "[f] " << "left --> out" << " - " << lIdx.x << " " << lIdx.y << "\n";
            _traceList.push_back(lIdx);
            _cells[lIdx.x][lIdx.y]._directionType = _cells[curIdx.x][curIdx.y]._tempDirection;
        }
        else if(curDir == DirectionType::DIR_UP &&
                IsValid(uIdx) &&
                _cells[uIdx.x][uIdx.y]._straightness == Straightness::ST_DIAGONAL)
        {
            //std::cout << "[g] " << "up --> out" << " - " << uIdx.x << " " << uIdx.y << "\n";
            _traceList.push_back(uIdx);
            _cells[uIdx.x][uIdx.y]._directionType = _cells[curIdx.x][curIdx.y]._tempDirection;
        }
        else if(curDir == DirectionType::DIR_DOWN &&
                IsValid(dIdx) &&
                _cells[dIdx.x][dIdx.y]._straightness == Straightness::ST_DIAGONAL)
        {
            //std::cout << "[h] " << "down --> out" << " - " << dIdx.x << " " << dIdx.y << "\n";
            _traceList.push_back(dIdx);
            _cells[dIdx.x][dIdx.y]._directionType = _cells[curIdx.x][curIdx.y]._tempDirection;
        }

        else if(curDir == DirectionType::DIR_UPRIGHT &&
           hitType == LineType::LINE_HORIZONTAL &&
           IsValid(rIdx) &&
           _cells[rIdx.x][rIdx.y]._straightness == Straightness::ST_HORIZONTAL) // upright --> right
        {

            //std::cout << "[1] " << "upright --> right" << " - " << rIdx.x << " " << rIdx.y << "\n";
            // rIdx
            _traceList.push_back(rIdx);
            _cells[rIdx.x][rIdx.y]._directionType = DirectionType::DIR_RIGHT;
            _cells[rIdx.x][rIdx.y]._tempDirection = DirectionType::DIR_DOWNRIGHT;
        }
        else if(curDir == DirectionType::DIR_DOWNRIGHT  &&
                hitType == LineType::LINE_HORIZONTAL &&
                IsValid(rIdx) &&
                _cells[rIdx.x][rIdx.y]._straightness == Straightness::ST_HORIZONTAL) // downright --> right
        {
            //std::cout << "[2] " << "downright --> right" << " - " << rIdx.x << " " << rIdx.y << "\n";
            //std::cout << curDir << " " << hitType << " " << IsValid(rIdx) << " " << _cells[rIdx.x][rIdx.y]._straightness << "\n";
            // rIdx
            _traceList.push_back(rIdx);
            _cells[rIdx.x][rIdx.y]._directionType = DirectionType::DIR_RIGHT;
            _cells[rIdx.x][rIdx.y]._tempDirection = DirectionType::DIR_UPRIGHT;
        }
        else if(curDir == DirectionType::DIR_DOWNLEFT &&
                hitType == LineType::LINE_HORIZONTAL &&
                IsValid(lIdx) &&
                _cells[lIdx.x][lIdx.y]._straightness == Straightness::ST_HORIZONTAL) // downleft --> left
        {
            //std::cout << "[3] " << "downleft --> left" << " - " << lIdx.x << " " << lIdx.y << "\n";
            // lIdx
            _traceList.push_back(lIdx);
            _cells[lIdx.x][lIdx.y]._directionType = DirectionType::DIR_LEFT;
            _cells[lIdx.x][lIdx.y]._tempDirection = DirectionType::DIR_UPLEFT;
        }
        else if(curDir == DirectionType::DIR_UPLEFT &&
                hitType == LineType::LINE_HORIZONTAL &&
                IsValid(lIdx) &&
                _cells[lIdx.x][lIdx.y]._straightness == Straightness::ST_HORIZONTAL)    // upleft --> left
        {
            //std::cout << "[4] " << "// upleft --> left" << " - " << lIdx.x << " " << lIdx.y << "\n";
            // lIdx
            _traceList.push_back(lIdx);
            _cells[lIdx.x][lIdx.y]._directionType = DirectionType::DIR_LEFT;
            _cells[lIdx.x][lIdx.y]._tempDirection = DirectionType::DIR_DOWNLEFT;
        }

        else if(curDir == DirectionType::DIR_UPRIGHT &&
                hitType == LineType::LINE_VERTICAL &&
                IsValid(uIdx) &&
                _cells[uIdx.x][uIdx.y]._straightness == Straightness::ST_VERTICAL) // upright --> up
        {
            //std::cout << "[5] " << "upright --> up" << " - " << uIdx.x << " " << uIdx.y << "\n";
            // uIdx
            _traceList.push_back(uIdx);
            _cells[uIdx.x][uIdx.y]._directionType = DirectionType::DIR_UP;
            _cells[uIdx.x][uIdx.y]._tempDirection = DirectionType::DIR_UPLEFT;
        }
        else if(curDir == DirectionType::DIR_DOWNRIGHT  &&
                hitType == LineType::LINE_VERTICAL &&
                IsValid(dIdx) &&
                _cells[dIdx.x][dIdx.y]._straightness == Straightness::ST_VERTICAL) // downright --> down
        {
            //std::cout << "[6] " << "downright --> down" << " - " << dIdx.x << " " << dIdx.y << "\n";
            // dIdx
            _traceList.push_back(dIdx);
            _cells[dIdx.x][dIdx.y]._directionType = DirectionType::DIR_DOWN;
            _cells[dIdx.x][dIdx.y]._tempDirection = DirectionType::DIR_DOWNLEFT;
        }
        else if(curDir == DirectionType::DIR_DOWNLEFT &&
                hitType == LineType::LINE_VERTICAL &&
                IsValid(dIdx) &&
                _cells[dIdx.x][dIdx.y]._straightness == Straightness::ST_VERTICAL) // downleft --> down
        {
            //std::cout << "[7] " << "downleft --> down" << " - " << dIdx.x << " " << dIdx.y << "\n";
            // dIdx
            _traceList.push_back(dIdx);
            _cells[dIdx.x][dIdx.y]._directionType = DirectionType::DIR_DOWN;
            _cells[dIdx.x][dIdx.y]._tempDirection = DirectionType::DIR_DOWNRIGHT;
        }
        else if(curDir == DirectionType::DIR_UPLEFT &&
                hitType == LineType::LINE_VERTICAL &&
                IsValid(uIdx) &&
                _cells[uIdx.x][uIdx.y]._straightness == Straightness::ST_VERTICAL)    // upleft --> up
        {
            //std::cout << "[8] " << "upleft --> up" << " - " << uIdx.x << " " << uIdx.y << "\n";
            // uIdx
            _traceList.push_back(uIdx);
            _cells[uIdx.x][uIdx.y]._directionType = DirectionType::DIR_UP;
            _cells[uIdx.x][uIdx.y]._tempDirection = DirectionType::DIR_UPRIGHT;
        }

        // old code
        else if(curDir == DirectionType::DIR_UPRIGHT && IsValid(urIdx) && hitType == LineType::LINE_NONE)
        {
            //std::cout << "[9] " << hitType << " - " << urIdx.x << " " << urIdx.y << "\n";
            _traceList.push_back(urIdx);
            _cells[urIdx.x][urIdx.y]._directionType = DirectionType::DIR_UPRIGHT;
        }
        else if(curDir == DirectionType::DIR_DOWNRIGHT && IsValid(drIdx) && hitType == LineType::LINE_NONE)
        {
            //std::cout << "[10] " << hitType << " - " << drIdx.x << " " << drIdx.y << "\n";
            _traceList.push_back(drIdx);
            _cells[drIdx.x][drIdx.y]._directionType = DirectionType::DIR_DOWNRIGHT;
        }
        else if(curDir == DirectionType::DIR_DOWNLEFT && IsValid(dlIdx) && hitType == LineType::LINE_NONE)
        {
            //std::cout << "[11] " << hitType << " - " << dlIdx.x << " " << dlIdx.y << "\n";
            _traceList.push_back(dlIdx);
            _cells[dlIdx.x][dlIdx.y]._directionType = DirectionType::DIR_DOWNLEFT;
        }
        else if(curDir == DirectionType::DIR_UPLEFT && IsValid(ulIdx) && hitType == LineType::LINE_NONE)
        {
            //std::cout << "[12] " << hitType << " - " << ulIdx.x << " " << ulIdx.y << "\n";
            _traceList.push_back(ulIdx);
            _cells[ulIdx.x][ulIdx.y]._directionType = DirectionType::DIR_UPLEFT;
        }
        else if(curDir == DirectionType::DIR_UPRIGHT && ( IsValid(rIdx) || IsValid(uIdx) )  )
        {
            if(hitType == LineType::LINE_HORIZONTAL && IsValid(rIdx))
            {
                //std::cout << "[13] " << hitType << " - " << rIdx.x << " " << rIdx.y << "\n";
                _traceList.push_back(rIdx);
                _cells[rIdx.x][rIdx.y]._directionType = DirectionType::DIR_DOWNRIGHT;
            }
            else
            {
                //std::cout << "[14] " << hitType << " - " << uIdx.x << " " << uIdx.y << "\n";
                _traceList.push_back(uIdx);
                _cells[uIdx.x][uIdx.y]._directionType = DirectionType::DIR_UPLEFT;
            }
        }
        else if(curDir == DirectionType::DIR_DOWNRIGHT && ( IsValid(rIdx) || IsValid(dIdx) ))
        {
            if(hitType == LineType::LINE_HORIZONTAL && IsValid(rIdx))
            {
                //std::cout << "[15] " << hitType << " - " << rIdx.x << " " << rIdx.y << "\n";
                _traceList.push_back(rIdx);
                _cells[rIdx.x][rIdx.y]._directionType = DirectionType::DIR_UPRIGHT;
            }
            else
            {
                //std::cout << "[16] " << hitType << " - " << dIdx.x << " " << dIdx.y << "\n";
                //std::cout << curDir << " " << hitType << " " << IsValid(rIdx) << " " << _cells[rIdx.x][rIdx.y]._straightness << "\n";
                _traceList.push_back(dIdx);
                _cells[dIdx.x][dIdx.y]._directionType = DirectionType::DIR_DOWNLEFT;
            }
        }
        else if(curDir == DirectionType::DIR_DOWNLEFT && ( IsValid(lIdx) || IsValid(dIdx) ))
        {
            if(hitType == LineType::LINE_HORIZONTAL && IsValid(lIdx))   // up left
            {
                //std::cout << "[17] " << hitType << " - " << lIdx.x << " " << lIdx.y << "\n";
                _traceList.push_back(lIdx);
                _cells[lIdx.x][lIdx.y]._directionType = DirectionType::DIR_UPLEFT;
            }
            else        // down right
            {
                //std::cout << "[18] " << hitType << " - " << dIdx.x << " " << dIdx.y << "\n";
                _traceList.push_back(dIdx);
                _cells[dIdx.x][dIdx.y]._directionType = DirectionType::DIR_DOWNRIGHT;
            }
        }
        else if(curDir == DirectionType::DIR_UPLEFT && ( IsValid(lIdx) || IsValid(uIdx) ))
        {
            if(hitType == LineType::LINE_HORIZONTAL && IsValid(lIdx))
            {
                //std::cout << "[19] " << hitType << " - " << lIdx.x << " " << lIdx.y << "\n";
                _traceList.push_back(lIdx);
                _cells[lIdx.x][lIdx.y]._directionType = DirectionType::DIR_DOWNLEFT;
            }
            else
            {
                //std::cout << "[20] " << hitType << " - " << uIdx.x << " " << uIdx.y << "\n";
                _traceList.push_back(uIdx);
                _cells[uIdx.x][uIdx.y]._directionType = DirectionType::DIR_UPRIGHT;
            }
        }

        // check if we revisit a cell which means done
        AnIndex nextIdx = _traceList[_traceList.size() - 1];
        if(_cells[nextIdx.x][nextIdx.y]._isVisited)
        {
            //std::cout << "end here " << nextIdx.x << " " << nextIdx.y << "\n";
            _isTracingDone = true;
        }

        _tilePainter->SetTiles(_cells, _traceList, _gridSpacing, _isTracingDone);
        this->repaint();
    }
}
Beispiel #2
0
//----------------------------------------------------------------------------
Node* FoucaultPendulum::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)
	{
		Vector3f& pos = vba.Position<Vector3f>(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<Vector3f>(i)[2] -= 16.0f;
	}
	bulb->UpdateModelSpace(Visual::GU_NORMALS);

	vba.ApplyTo(rod);
	numVertices = vba.GetNumVertices();
	for (i = 0; i < numVertices; ++i)
	{
		vba.Position<Vector3f>(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.
	Material* material = new0 Material();
	material->Emissive = Float4(0.0f, 0.0f, 0.0f, 1.0f);
	material->Ambient = Float4(0.1f, 0.1f, 0.1f, 1.0f);
	material->Diffuse = Float4(0.99607f, 0.83920f, 0.67059f, 1.0f);
	material->Specular = Float4(0.0f, 0.0f, 0.0f, 0.0f);

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

	light[1] = new0 Light(Light::LT_DIRECTIONAL);
	light[1]->Ambient = Float4(1.0f, 1.0f, 1.0f, 1.0f);
	light[1]->Diffuse = Float4(1.0f, 1.0f, 1.0f, 1.0f);
	light[1]->Specular = Float4(0.0f, 0.0f, 0.0f, 1.0f);
	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;
}