void Board::fallSpheres(std::function<void(Sphere*,PointGrid)> logic){ GroupSphere spheres_fall; std::vector<PointGrid> spheres_fall_old_pos; std::vector<PointGrid> spheres_fall_new_pos; _match_lock(); //esto correge error de mal cambio de columna 0 a 11 //imprevistamente spheres_fall.clear(); std::cout << "GridCols:" << _grid.getCols() << " GridRows:" << _grid.getRows() << std::endl; for(int col=_grid.getCols()-1; col >= 0; col--){ for(int row=0; row < _grid.getRows(); row++){ PointGrid sphere_pos(col, row); Sphere* sphere = _grid.get(sphere_pos); //std::cout << "TryingFallingSphere:" << sphere_pos.x << "," << sphere_pos.y << std::endl; if(_grid.Empty(sphere)) continue; std::cout << "FallingSphere:" << sphere->getPosition().x << "," << sphere->getPosition().y << " Col: " << col << std::endl; sphere->retain(); PointGrid sphere_new_pos = PointGrid::BAD; for(int row_row=row-1; row_row>=0; row_row--){ if(_grid.Empty(PointGrid(col, row_row))){ std::cout << "FallingSphere::newpos:" << sphere_pos.x << "," << row_row << std::endl; sphere_new_pos = PointGrid(col, row_row); }else{ break; } } if(sphere_new_pos != PointGrid::BAD){ sphere->retain(); spheres_fall.push_back(sphere); spheres_fall_new_pos.push_back(sphere_new_pos); spheres_fall_old_pos.push_back(sphere->getPosition()); std::cout << "FallingSphere::newpos sended:" << sphere_new_pos.x << "," << sphere_new_pos.y << std::endl; if(logic) logic(sphere, sphere_new_pos); _grid.move(sphere->getPosition(), sphere_new_pos); sphere->setPosition(sphere_new_pos); } } } _match_unlock(); for(auto ifunc = onAttachFall.begin(); ifunc != onAttachFall.end(); ifunc++){ (*ifunc)(spheres_fall, spheres_fall_old_pos, spheres_fall_new_pos); } std::cout << "FallingSphere::End" << std::endl; }
void Board::roll(GroupSphere spheres) { int col = 0; GroupSphere spheres_end_board; _match_lock(); spheres_end_board.clear(); for(auto &sphere: spheres) { _grid.push_front(col, sphere); auto pos = PointGrid(col, 0); sphere->setPosition(pos); auto sphere_view = sphere->getView(); _node->addChild(sphere_view); auto poss = pos.toPoint(); poss.x += GRID_SIZE/2; poss.y *= -1; //invierte, para mostrar hacia abajo poss.y += _node->getContentSize().height; sphere_view->setPosition(poss); //std::cout << "Rolling sphere first" << std::endl; for(int row = _grid.getRows(); row > 0; row--){ Sphere* data = static_cast<Sphere*>(_grid.get(PointGrid(col, row))); if(!_grid.Empty(data)){ auto pos = PointGrid(col, row); auto sphere_view = data->getView(); data->setPosition(pos); auto poss = pos.toPoint(); poss.x += GRID_SIZE/2; poss.y *= -1; //invierte, para mostrar hacia abajo poss.y += _node->getContentSize().height; sphere_view->setPosition(poss); sphere_view->retain(); //std::cout << "Rolling sphere down" << std::endl; if(data->getPosition().y == _grid.getRows() - 1 //@patch para permitir colision ultima esfera ){ data->retain(); spheres_end_board.push_back(data); } } } col += 1; } _match_unlock(); for(auto &func: onAttachRoll) { func(spheres); } if(spheres_end_board.size()>0){ for(auto &func: onAttachEndBoard) { func(spheres_end_board); } } }
/*! * \brief Register::setUpResult * \param sphere * \return */ bool Register::setUpResult(Sphere &sphere){ //get and check plane if(!this->inputElements.contains(0) || this->inputElements[0].size() != 1){ return false; } QPointer<Plane> plane = this->inputElements[0].at(0).plane; if(plane.isNull() || !plane->getIsSolved()){ return false; } //get the position of the sphere and the plane and the normal vector OiVec n_plane = plane->getDirection().getVector(); n_plane.normalize(); OiVec x_plane = plane->getPosition().getVector(); OiVec x_sphere = sphere.getPosition().getVector(); //calculate the distance of the plane from the origin double d; OiVec::dot(d, x_plane, n_plane); if(d < 0.0){ n_plane = -1.0 * n_plane; d = -d; } //calculate the distance of the sphere position from the plane double s; OiVec::dot(s, x_sphere, n_plane); s = s - d; //project the sphere position into the plane x_sphere = x_sphere - s * n_plane; //set result Position position = sphere.getPosition(); position.setVector(x_sphere); Radius radius = sphere.getRadius(); sphere.setSphere(position, radius); return true; }
void fallingSphere(Sphere & s,position2di mousemove,f32 frameDeltaTime,f32 friction){ // This handler would accelerate the sphere downwards, ignoring all // mouse movements or speed in horizontal directions: vector3df p=s.getPosition(); vector3df v=s.getVelocity(); v.X=v.Z=0.f; v.Y-=1.f*frameDeltaTime; // falling; p+=v; s.setPosition(p); s.setVelocity(v); }
std::string Debug::Detail::ToString(const Sphere& node, uint32_t level) { std::stringstream stream; stream << "Sphere {" << std::endl << Debug::indent(level + 1) << "Name: \"" << node.getName() << "\"" << std::endl << Debug::indent(level + 1) << "Position: " << node.getPosition() << std::endl << Debug::indent(level + 1) << "Material: " << ToStringPtr(node.getMaterial(), level + 1) << std::endl << Debug::indent(level + 1) << "Radius: " << node.getRadius() << std::endl << Debug::Detail::ToStringNodeChilds(node, level + 1) << Debug::indent(level) << "}" ; return stream.str(); }
void Scene::addSphere(geovalue *pos, geovalue rad, Material *mat) { Vector3D p1(pos[0],pos[1],pos[2]); for (int i=0; i<objects.size(); ++i) { Sphere * s; if ((s = dynamic_cast<Sphere*>(objects[i]))) { Vector3D distvec = s->getPosition() - p1; float dist = distvec.length(); float minDist = rad + s->getRadius(); if (dist < minDist) { rad = (minDist - s->getRadius())/2.0; pos[1] = -1.0 + rad; } } } objects.push_back(new Sphere(pos, mat, rad, this)); }
//----------------------------------------------------------------------------- //! 衝突計算 //! 視錐台 vs 球 //! @param [in] sphere 当たり判定のしたい球 //----------------------------------------------------------------------------- bool Frustum::isHit(Sphere& sphere) { // 視錐台の面の更新 updateFrustumPlane(); // 球の座標 Vector3 spherePos = sphere.getPosition(); // 球の半径 f32 sphereRad = sphere.getRadius(); // 面との距離がすべての面の内側にあればあたっている for (s32 i = 0; i < 6; ++i){ f32 distance = _plane[i].getDistance(spherePos); // 裏面の場合距離はマイナスなので半径を足しても // 負の場合視錐台の外側で且つ半径以上離れている if (distance + sphereRad < 0.0f){ return false; } } return true; }
//----------------------------------------------------------------------------- //! 衝突計算 //! 円同士 //! @param [in] sphere 当たり判定のしたい球 //----------------------------------------------------------------------------- bool Sphere::isHit(Sphere& sphere) { return GmSystemCollision()->HitSphere(_position, sphere.getPosition(), _radius, sphere.getRadius()); }