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(); } }
//---------------------------------------------------------------------------- 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; }