示例#1
0
int Check(Point &p1,Point &p2)
{
    int i;
    if (fabs(p1.x-p2.x)<eps && fabs(p1.y-p2.y)<eps) return 0;
    for (i=0;i<n;i++) if (!IsIntersected(p1,p2,s[i],e[i])) return 0;
    return 1;
}
void 
GamePlaying::onTouchEnded(Touch* t,Event* ev){
	if(_slushLimit==0){
		return;
	}

	auto stigma = getChildByName("stigma");
	stigma->setName("");
	stigma->runAction(Sequence::createWithTwoActions(FadeOut::create(0.5f),RemoveSelf::create()));

	//CreateSlushParticle(_touchedPos,t->getLocation());

	bool flg=false;
	///カットチェック
	for(MyPolygon& p : _polygons){
		auto nnode = getChildByTag(p.tag);
		if(nnode==nullptr){
			continue;
		}
		auto psp=(MyPhysicsShape*)(nnode->getPhysicsBody()->getFirstShape());
		auto cps=(cpPolyShape*)(psp->getPolyShape());
		
		auto& polyPos = getChildByTag(p.tag)->getPosition();
		for(int j=0;j<cps->numVerts;++j){
			if(j==cps->numVerts-1){
				flg=IsIntersected(_touchedPos,
					t->getLocation(),
					Vec2(cps->tVerts[j].x,cps->tVerts[j].y),
					Vec2(cps->tVerts[0].x,cps->tVerts[0].y));
				if(flg){
					PosUv posuv;
					posuv.pos = IntersectedPoint(_touchedPos,
								t->getLocation(),
								Vec2(cps->tVerts[j].x,cps->tVerts[j].y),
								Vec2(cps->tVerts[0].x,cps->tVerts[0].y));
					//とりあえずvertsのインデックスとp.vertices,p.uvsのインデクスが同一であると仮定する。
					posuv.uv = GetMidUV(Vec2(cps->verts[j].x,cps->verts[j].y)+polyPos,
						p.uvs[j],
						Vec2(cps->tVerts[0].x,cps->tVerts[0].y),
						p.uvs[0],
						posuv.pos);
					p.cutEdges.push_back(std::make_pair(j,posuv));//インデックスとuv&posのペア
					p.wasCut=true;
					
				}
			}else{
				flg=IsIntersected(_touchedPos,
					t->getLocation(),
					Vec2(cps->tVerts[j].x,cps->tVerts[j].y),
					Vec2(cps->tVerts[j+1].x,cps->tVerts[j+1].y));
				if(flg){
					PosUv posuv;
					posuv.pos =IntersectedPoint(_touchedPos,
								t->getLocation(),
								Vec2(cps->tVerts[j].x,cps->tVerts[j].y),
								Vec2(cps->tVerts[j+1].x,cps->tVerts[j+1].y));
					//とりあえずvertsのインデックスとp.vertices,p.uvsのインデクスが同一であると仮定する。
					posuv.uv = GetMidUV(Vec2(cps->tVerts[j].x,cps->tVerts[j].y),
						p.uvs[j],
						Vec2(cps->tVerts[j+1].x,cps->tVerts[j+1].y),
						p.uvs[j+1],
						posuv.pos);
					p.cutEdges.push_back(std::make_pair(j,posuv));
					p.wasCut=true;

				}
			}
		}
	}

	std::vector<Vec2> cuttingEdges;

	///一時的…追加用ベクタ作成
	std::vector<MyPolygon> addedpolygons(0);
	int cutcount=0;
	///分離処理(頂点の生成)
	for(MyPolygon& p : _polygons){
		if(p.cutEdges.empty() || p.cutEdges.size()==1){//カットできてない場合は次へ
			p.wasCut=false;
			p.cutEdges.clear();
			continue;
		}
		++cutcount;
		//n番目がカットされている場合、nとn+1の間をカットしている
		//カットされている場合は2つのカットポイントが存在する

		Vec2& fpos=p.cutEdges[0].second.pos;
		Vec2& spos=p.cutEdges[1].second.pos;

		if((_touchedPos-fpos).length()>(_touchedPos-spos).length()){
			//切るエフェクトの発生
			CreateSlushParticle(spos,fpos);
		}else{
			//切るエフェクトの発生
			CreateSlushParticle(fpos,spos);
		}

		//とりあえず複製を一つ用意する

		//頂点数も変わる。エッジ番号の差が1なら残りの頂点数は1つまり差=残り頂点数となる

		//↑2つが新たな頂点となる(ソートが必要)
		if(p.cutEdges[0].first > p.cutEdges[1].first){
			std::swap(p.cutEdges[0],p.cutEdges[1]);
		}

		auto nnode = getChildByTag(p.tag);
		auto& polyPos = nnode->getPosition();
		auto psp=(MyPhysicsShape*)(nnode->getPhysicsBody()->getFirstShape());
		auto cps=(cpPolyShape*)(psp->getPolyShape());

		//sort完了
		//差を算出
		int diff = p.cutEdges[1].first-p.cutEdges[0].first;
		Vec2 pos=p.position;
		MyPolygon poly;
		std::vector<Vec2>& tmpUvs=p.uvs;

		poly.vertices.clear();
		poly.uvs.clear();
		
		poly.tag = p.tag;
		poly.texId = p.texId;
		poly.wasCut=p.wasCut;

		Vec2 newpos = p.cutEdges[0].second.pos-polyPos;
		poly.vertices.push_back(newpos);
		poly.uvs.push_back(p.cutEdges[0].second.uv);//切断端点
		for(int i=1;i<=diff;++i){
			int idx=p.cutEdges[0].first+i;
			cpVect& ve=cps->tVerts[idx];//元の座標を利用
			newpos = Vec2(ve.x,ve.y)-polyPos;
			poly.vertices.push_back(newpos);
			poly.uvs.push_back(tmpUvs[idx]);
		}
		newpos = p.cutEdges[1].second.pos-polyPos;
		poly.vertices.push_back(newpos);
		poly.uvs.push_back(p.cutEdges[1].second.uv);//切断端点
		poly.position = polyPos;
		addedpolygons.push_back(poly);

		poly.vertices.clear();
		poly.uvs.clear();

		//もうひとつのポリゴン
		diff=p.vertices.size()-diff;
		poly.texId = p.texId;
		poly.wasCut=p.wasCut;
		newpos = p.cutEdges[1].second.pos-polyPos;
		poly.vertices.push_back(newpos);
		poly.uvs.push_back(p.cutEdges[1].second.uv);//切断端点
		for(int i=1;i<=diff;++i){
			int idx = (p.cutEdges[1].first+i)%p.vertices.size();
			cpVect& ve=cps->tVerts[idx];//元の座標を利用
			newpos = Vec2(ve.x,ve.y)-polyPos;
			poly.vertices.push_back(newpos);
			poly.uvs.push_back(tmpUvs[idx]);
		}
		newpos = p.cutEdges[0].second.pos-polyPos;
		poly.vertices.push_back(newpos);
		poly.uvs.push_back(p.cutEdges[0].second.uv);//切断端点
		poly.position = polyPos;
		addedpolygons.push_back(poly);
	}

	//切れてなければリターンする
	if(cutcount==0){
		removeChild(stigma);
		return;
	}

	for(auto& p : _polygons){
		auto node = getChildByTag(p.tag);
		if(node==nullptr){
			continue;
		}
		auto& polyPos = node->getPosition();
		if(!p.wasCut){
			p.position=polyPos;
		}
	}

	//切れてしまっている奴は、別の2つに生まれ変わっているので、元のは消す。
	for(auto& p : _polygons){
		if(p.wasCut){
			removeChild(getChildByTag(p.tag));
		}
	}

	class IFunction{
	public:
		bool operator()(MyPolygon& a){
			return a.wasCut;
		}
	};

	_polygons.erase(std::remove_if(_polygons.begin(),_polygons.end(),IFunction()),_polygons.end());

	std::copy(addedpolygons.begin(),addedpolygons.end(),std::back_inserter(_polygons));
	
	///実際のポリゴン生成
	for(auto& pl : _polygons){
		if(!pl.wasCut){
			continue;
		}
		auto& v=pl.vertices;
		auto& uvs=pl.uvs;
		auto node = DrawNodeWithTex::create();
		node->SetTexture(pl.texId);
		//重心の計算(疑似)
		Vec2 center=Vec2(0,0);
		for(auto& vert : v){
			center+=vert;
		}
		center = center/v.size();
		for(auto& vert : v){
			vert-=center;
		}

		auto grave=PhysicsBody::createPolygon(&v[0],v.size(),_pm);

		node->drawPolygonT(&v[0],&uvs[0],v.size(),cocos2d::Color4F::YELLOW,0,Color4F::WHITE);
		
		for(Vec2&  uv : uvs){
			log("u=%f,v=%f",uv.x,uv.y);
		}

		pl.position+=center;
		node->setPosition(pl.position);
		node->setPhysicsBody(grave);
		node->setTag(_tag++);
		pl.tag=node->getTag();
		pl.wasCut=false;
		addChild(node);
		DrawNode* border=DrawNode::create();
		border->drawPolygon(&v[0],v.size(),Color4F(0,0,0,0.0),BORDER_WIDTH,Color4F::WHITE);
		node->addChild(border);
	}
	--_slushLimit;
}