Ejemplo n.º 1
0
	//	壁との当たり判定
	bool	Collision::CheckWall( iexMesh* org, const Vector3& pos, Vector3& p_move )
	{
		//org->Update();
		const	float	DIST = 2.0f;	//	壁との距離
		Vector3	p_pos = Vector3(pos.x, pos.y + 1.0f, pos.z);
		Vector3	vec = Vector3(p_move.x, 0.0f, p_move.z);
		vec.Normalize();
		Vector3	takePos;
		float	dist = 100.0f;

		// オブジェクトの逆行列を算出

		if ( org->RayPick( &takePos, &p_pos, &vec, &dist ) != -1 ){
			float	disToWall = Vector3( Vector3( takePos.x, 0.0f, takePos.z ) - Vector3( p_pos.x, 0.0f, p_pos.z ) ).Length();
			if ( disToWall <= DIST )
			{
				//	移動量
				float	move = Vector3( p_move.x, 0.0f, p_move.z ).Length();

				//	プレイヤーからレイの交差点へのベクトル
				Vector3	vPtoWall( takePos - p_pos );
				vPtoWall.y = 0.0f;	vPtoWall.Normalize();
				vec.y = 0.0f;	vec.Normalize();

				//	法線の上方向(?)を求める
				Vector3	vCrossUp;
				Vector3Cross( vCrossUp, vec, vPtoWall );
				vCrossUp.Normalize();

				//	法線の上方向(?)と法線の外積から滑る方向を計算
				Vector3	vCrossSide;
				Vector3Cross( vCrossSide, vCrossUp, vec );
				vCrossSide.Normalize();

				//	法線とプレーヤーからレイの交差点へのベクトルの内積
				float	dotNP = Vector3Dot( vec, vPtoWall );

				//	移動量の調整
				p_move.x = vCrossSide.x * move * ( dotNP + 1.0f );
				p_move.z = vCrossSide.z * move * ( dotNP + 1.0f );

				return	true;
			}
		}

		return	false;
	}
Ejemplo n.º 2
0
	// 線分と線分の距離の平方を返す(カプセル用)
	float	Collision::DistanceSegmentSegmentSq( const Vector3& l1p1, const Vector3& l1p2, const Vector3& l2p1, const Vector3& l2p2 )
	{
		// ねじれの位置の判定
		Vector3 v1 = l1p2 - l1p1;
		Vector3 v2 = l2p2 - l2p1;
		Vector3 n;
		Vector3Cross( n, v1, v2 );
		float nn = n.LengthSq();
		if ( nn ) {
			// 平行ではない
			Vector3 v12 = l2p1 - l1p1;
			float nv12 = Vector3Dot( n, v12 );
			Vector3 vd = n * ( nv12 / nn );
			Vector3 q1 = l2p1 - vd;
			Vector3 q2 = l2p2 - vd;
			Vector3 p1q1 = q1 - l1p1;
			Vector3 p1q2 = q2 - l1p1;
			Vector3 r1, r2;
			Vector3Cross( r1, v1, p1q1 );
			Vector3Cross( r2, v1, p1q2 );
			if ( Vector3Dot( r1, r2 ) < 0 ) {
				Vector3 v3 = q2 - q1;
				Vector3 q1p1 = l1p1 - q1;
				Vector3 q1p2 = l1p2 - q1;
				Vector3Cross( r1, v3, q1p1 );
				Vector3Cross( r2, v3, q1p2 );
				if (Vector3Dot( r1, r2 ) < 0 ) {
					// ねじれの位置
					return nv12 * nv12 / nn;
				}
			}
		}
		// ねじれじゃない位置
		return min(
			min( DistancePointSegmentSq( l1p1, l2p1, l2p2 ),
			DistancePointSegmentSq( l1p2, l2p1, l2p2 ) ),
			min(DistancePointSegmentSq( l2p1, l1p1, l1p2 ),
			DistancePointSegmentSq( l2p2, l1p1, l1p2 ) )
			);
	}
Ejemplo n.º 3
0
//	ハイパーアーツ
bool	Thief::HyperArts(void)
{

	//空中で発動しても停止する
	move = Vector3(0, -GRAVITY, 0);

	if ( !initflag )
	{
		sound->PlaySE( SE::HYPER_ATTACK );
		sound->PlaySE( SE::KAITO_HYPER );
		initflag = true;
	}

	attackInfo.power = OFFENSIVE_POWER::HYPER;
	attackInfo.dropPower = DROP_POWER::HYPER;
	attackInfo.coinDropType = DROP_TYPE::SUCTION;

	SetParameterState(PARAMETER_STATE::UNRIVALED);
	move = Vector3(0, 0 - GRAVITY, 0);	//撃ってる間は静止させる
	SetMotion(THIEF::MOTION_DATA::HYPERARTS);


	//	行列から情報取得
	Vector3	front = GetFront();
	Vector3	right = GetRight();
	Vector3	p_pos = GetPos();
	SetMove(Vector3(0.0f, move.y, 0.0f));


	if (obj->GetFrame() >= THIEF::MOTION_FRAME::HYPERARTS_ATTACKSTART/* && obj->GetFrame() < THIEF::MOTION_FRAME::HYPERARTS_ATTACKEND*/)
	{
		float t = GetBezier(ePrm_t::eRapid_Lv5, ePrm_t::eSlow_Lv1, attackInfo.t);
		Vector3 f = front * (2.0f * sinf(D3DX_PI * t));
		Vector3 r = -right * (2.0f * cosf(D3DX_PI * t));
		attackInfo.bottom = p_pos + f + r;

		switch (HyperStep)
		{
		case 0:
			//	あたり判定のパラメータを与える
			attackInfo.top = attackInfo.bottom + r * HyperRate;
			attackInfo.r = 2.5f;
			HyperRate += 1.0;
			if (HyperRate > 20.0f) HyperStep++;
			break;
		case 1:
			//	パラメータ加算
			attackInfo.top = attackInfo.bottom + f * HyperRate + r * HyperRate;
			attackInfo.t += 0.03f;
			if (attackInfo.t >= 1.0f)
			{
				HyperStep++;
			}
			break;
		case 2:
			//attackInfo.top = attackInfo.bottom + r * rate;
			attackInfo.t = 0.0f;
			HyperRate -= 1.0f;
			break;
		}
		armRenderflag = true;
	}

	Vector3 v1, v2;
	v1 = front;
	v2 = attackInfo.top - attackInfo.bottom;
	v1.Normalize();
	v2.Normalize();
	float armAngle = GetAngle(v1, v2);
	Vector3 cross;
	Vector3Cross(cross, v1, v2);
	if (cross.y < 0) armAngle = -armAngle;

	arm->SetPos(pos);
	arm->SetAngle(angle.y + armAngle);
	arm->SetScale(Vector3(0.03f, 0.03f, HyperRate * 0.01f));
	arm->Update();

	if (HyperRate < 0)
	{
		HyperStep = 0;
		HyperRate = 0;
		armRenderflag = false;
		initflag = false;
		return true;
	}
	return	false;
}
Ejemplo n.º 4
0
// 追加した関数
void iexMesh::NearestPoint( NearestPointOut *out, const Vector3 &inPos )
{
	//	情報取得	
	u32 fvf = lpMesh->GetFVF();
	//	頂点サイズ計算
	int vertexSize = D3DXGetFVFVertexSize( fvf ) / sizeof( float );
	//	バッファロック
	float	*pVertices;
	u16		*pIndices;
	u32 numIndices = lpMesh->GetNumFaces();
	lpMesh->LockVertexBuffer( D3DLOCK_READONLY, ( void** ) &pVertices );
	lpMesh->LockIndexBuffer( D3DLOCK_READONLY, ( void** ) &pIndices );

	struct
	{
		Vector3 vertex[3];
		Vector3	normal;
		Vector3 line[3];

		// 頂点情報から残りの情報を計算
		inline void ComputeFromVertex()
		{
			line[1] = vertex[2] - vertex[1];
			line[2] = vertex[3] - vertex[2];
			line[3] = vertex[1] - vertex[3];

			Vector3Cross( normal, line[1], line[2] );
			normal.Normalize();
		}
	}triangle; // 三角ポリゴン

	out->length = FLT_MAX;

	for( u32 j = 0; j < numIndices; j++ )
	{
		//	面頂点取得
		{
			int index = pIndices[j * 3 + 0] * vertexSize;
			triangle.vertex[1].x = pVertices[index];	triangle.vertex[1].y = pVertices[index + 1];	triangle.vertex[1].z = pVertices[index + 2];

			index = pIndices[j * 3 + 1] * vertexSize;
			triangle.vertex[2].x = pVertices[index];	triangle.vertex[2].y = pVertices[index + 1];	triangle.vertex[2].z = pVertices[index + 2];

			index = pIndices[j * 3 + 2] * vertexSize;
			triangle.vertex[3].x = pVertices[index];	triangle.vertex[3].y = pVertices[index + 1];	triangle.vertex[3].z = pVertices[index + 2];
		}

		// 法線と辺計算
		triangle.ComputeFromVertex();

		// 法線方向に距離計算
		FLOAT lengthNormal( 0 );
		lengthNormal = Vector3Dot( ( inPos - triangle.vertex[1] ), triangle.normal );

		// ポリゴンが裏向き
		if( lengthNormal <= 0 )
			continue;

		// 遠い
		if( lengthNormal > out->length )
			continue;

		Vector3 nearestPos( 0, 0, 0 );
		// とりあえず無限平面上で
		nearestPos = inPos - ( triangle.normal * lengthNormal );

		Vector3 decisionVector( 0, 0, 0 );
		// 内点判定
		for( unsigned int i = 0; i < 3; i++ )
		{
			Vector3Cross( decisionVector, ( triangle.vertex[i] - nearestPos ), triangle.line[i] );
			// 外にあった場合
			if( Vector3Dot( decisionVector, triangle.normal ) < 0 )
			{
				// nearestPosを辺上の最接近点へ移動
				float t = triangle.line[i].LengthSq();
				if( t != 0 ) // 辺上へ
					t = Vector3Dot( ( nearestPos - triangle.vertex[i] ), triangle.line[i] ) / t;
				// 頂点へ
				if( t < 0 ) t = 0;
				else if( t > 1 )t = 1;
				// 移動
				nearestPos = triangle.vertex[i] + triangle.line[i] * t;
			}
		}

		// 距離判定
		float length = ( nearestPos - inPos ).Length();
		if( length > out->length )
			continue;


		out->length = length;
		out->Normal = triangle.normal;
		out->Pos = nearestPos;
	}

	//	バッファアンロック
	lpMesh->UnlockVertexBuffer();
	lpMesh->UnlockIndexBuffer();
}
Ejemplo n.º 5
0
//------------------------------------------------------
//		上下最適化
//------------------------------------------------------
int	iexMesh::RayPickUD( Vector3* out, Vector3* pos, Vector3* vec, float *Dist )
{
	float	t, neart;
	float	vy;
	int		ret = -1;

	int		VertexSize;

	Vector3	p = *pos;
	vy = vec->y;

	neart = *Dist;

	//	情報取得	
	int fvf = lpMesh->GetFVF();
	//	頂点サイズ計算
	VertexSize = D3DXGetFVFVertexSize(fvf) / sizeof(float);

	//	バッファロック
	float	*pVertices;
	u16		*pIndices;
	int NumIndices = lpMesh->GetNumFaces();
	lpMesh->LockVertexBuffer( D3DLOCK_READONLY , (void**)&pVertices );
	lpMesh->LockIndexBuffer( D3DLOCK_READONLY , (void**)&pIndices );

	Vector	l1, l2, l3;
	Vector	p1, p2, p3;
	Vector v[3];
	Vector n;

	for( int j=0 ; j<NumIndices ; j++ )
	{
		//	面頂点取得
		int a = pIndices[j*3+0] * VertexSize;
		int b = pIndices[j*3+1] * VertexSize;
		int c = pIndices[j*3+2] * VertexSize;

		v[0].x = pVertices[a];	v[1].x = pVertices[b];	v[2].x = pVertices[c];
		if( v[0].x > p.x && v[1].x > p.x && v[2].x > p.x ) continue;

		v[0].z = pVertices[a+2];	v[1].z = pVertices[b+2];	v[2].z = pVertices[c+2];
		if( v[0].z > p.z && v[1].z > p.z && v[2].z > p.z ) continue;

		v[0].y = pVertices[a+1];	v[1].y = pVertices[b+1];	v[2].y = pVertices[c+1];

		//	内点判定(全外積がマイナス)		
		l1.x = v[1].x - v[0].x;
		l1.z = v[1].z - v[0].z;
		p1.x = v[0].x - p.x;
		p1.z = v[0].z - p.z;
		if( (p1.x*l1.z - p1.z*l1.x)*vy < 0 ) continue;

		l2.x = v[2].x - v[1].x;
		l2.z = v[2].z - v[1].z;
		p2.x = v[1].x - p.x;
		p2.z = v[1].z - p.z;
		if( (p2.x*l2.z - p2.z*l2.x)*vy < 0 ) continue;

		l3.x = v[0].x - v[2].x;
		l3.z = v[0].z - v[2].z;
		p3.x = v[2].x - p.x;
		p3.z = v[2].z - p.z;
		if( (p3.x*l3.z - p3.z*l3.x)*vy < 0 ) continue;

		//	外積による法線算出		
		l1.y = v[1].y - v[0].y;
		l2.y = v[2].y - v[1].y;
		Vector3Cross( n, l1, l2 );
		//	表裏判定
		if( vy*n.y >= 0 ) continue;

		//	交点算出
		p1.y = v[0].y - p.y;
		t = Vector3Dot( n, p1 ) / (n.y*vy);
		if( t < .0f || t > neart ) continue;

		*vec = n;
		ret = j;
		neart = t;
	}
	lpMesh->UnlockVertexBuffer();
	lpMesh->UnlockIndexBuffer();

	out->y = neart*vy + p.y;
	out->x = pos->x;
	out->z = pos->z;
	*Dist = neart;

	return	ret;
}
Ejemplo n.º 6
0
//**************************************************************************************************
//
//		レイピック
//
//**************************************************************************************************
//------------------------------------------------------
//		レイピック
//------------------------------------------------------
int	iexMesh::RayPick( Vector3* out, Vector3* pos, Vector3* vec, float *Dist )
{
	int		ret = -1;

	if( vec->x == .0f && vec->z == .0f ) return RayPickUD( out, pos, vec, Dist );

	Vector3 p = *pos;
	Vector3 vv = *vec;

	float neart = *Dist;
	float dist = *Dist;
	dist = dist*dist;
	*out = p;
	//	情報取得	
	u32 fvf = lpMesh->GetFVF();
	//	頂点サイズ計算
	int VertexSize = D3DXGetFVFVertexSize(fvf) / sizeof(float);

	//	バッファロック
	float	*pVertices;
	u16		*pIndices;
	u32 NumIndices = lpMesh->GetNumFaces();
	lpMesh->LockVertexBuffer( D3DLOCK_READONLY, (void**)&pVertices );
	lpMesh->LockIndexBuffer( D3DLOCK_READONLY, (void**)&pIndices );

	Vector3 v1, v2, v3;
	Vector3	n;
	Vector3	l1, l2, l3;
	Vector3	temp;
	Vector3	cp;

	Vector3 p1, p2, p3;

	for( u32 j=0 ; j<NumIndices ; j++ )
	{
		//	面頂点取得
		int a = pIndices[j*3+0] * VertexSize;
		v1.x = pVertices[a];	v1.y = pVertices[a+1];	v1.z = pVertices[a+2];

		int b = pIndices[j*3+1] * VertexSize;
		v2.x = pVertices[b];	v2.y = pVertices[b+1];	v2.z = pVertices[b+2];

		int c = pIndices[j*3+2] * VertexSize;
		v3.x = pVertices[c];	v3.y = pVertices[c+1];	v3.z = pVertices[c+2];
		
		//	距離判定
		//Vector3	ss = (v1 + v2 + v3) / 3.0f - p;
		//if( ss.LengthSq() > dist ) continue;
		l1.x = v2.x - v1.x;
		l1.y = v2.y - v1.y;
		l1.z = v2.z - v1.z;
		l2.x = v3.x - v2.x;
		l2.y = v3.y - v2.y;
		l2.z = v3.z - v2.z;
		
		//	外積による法線算出		
		Vector3Cross( n, l1, l2 );
		//	内積の結果がプラスならば裏向き
		float dot = Vector3Dot( vv, n );
		if( dot >= 0 ) continue;
		//	交点算出
		p1.x = v1.x - p.x;
		p1.y = v1.y - p.y;
		p1.z = v1.z - p.z;
		float t = Vector3Dot( n, p1 ) / dot;
		if( t < .0f || t > neart ) continue;

		cp.x = vv.x*t + p.x;
		cp.y = vv.y*t + p.y;
		cp.z = vv.z*t + p.z;
		//	内点判定
		p1.x = v1.x - cp.x;
		p1.y = v1.y - cp.y;
		p1.z = v1.z - cp.z;
		
		Vector3Cross( temp, p1, l1 );
		if( Vector3Dot(temp, n) < .0f ) continue;

		p2.x = v2.x - cp.x;
		p2.y = v2.y - cp.y;
		p2.z = v2.z - cp.z;
		Vector3Cross( temp, p2, l2 );
		if( Vector3Dot(temp, n) < .0f ) continue;

		l3.x = v1.x - v3.x;
		l3.y = v1.y - v3.y;
		l3.z = v1.z - v3.z;
		p3.x = v3.x - cp.x;
		p3.y = v3.y - cp.y;
		p3.z = v3.z - cp.z;
		Vector3Cross( temp, p3, l3 );
		if( Vector3Dot(temp, n) < .0f ) continue;

		*out = cp;
		*vec = n;
		ret = j;
		neart = t;
	}
	lpMesh->UnlockVertexBuffer();
	lpMesh->UnlockIndexBuffer();
	*Dist = neart;

	return	ret;
}