Exemplo n.º 1
0
//-----------------------------------------------------------------------------
//! その座標から一番近い三角形との衝突点の取得
//!	@param	[in]	positon		チェックする位置
//!	@param	[in]	radius		半径
//!	@retval			衝突点
//-----------------------------------------------------------------------------
Vector3 CollisionWall::getHitPos(const Vector3& position, const f32 radius, bool isNear)
//Vector3 CollisionWall::getHitPos(const AABB aabb)
{
	// 接触点
	Vector3	 resultPos(0.0f,0.0f,0.0f);

	/*Vector3 v1 = aabb._max;
	v1._y = 0.0f;
	Vector3 v2 = aabb._min;
	v2._y = 0.0f;*/

	//f32 radius = abs((v1 - v2).length() * 0.5f);

	// 衝突点までの距離(二乗で比較)
	f32	nearestHitPosLength = radius * radius;
	//f32	nearestHitPosLength = FLT_MAX;
	// 衝突したかどうか
	static bool isHit	  = false;

	// オフセット値
	static s32 Count = 0;
	static Vector3 offsetList[5] =
	{
		Vector3(  0, 0,  0 ),	// 中央
		Vector3(  0, 0,  1 ),	// 前
		Vector3(  0, 0, -1 ),	// 後
		Vector3( -1, 0,  0 ),	// 左
		Vector3(  1, 0,  0 ),	// 右
	};


	// もらった座標をインデックス番号に変更
	s32 x = ( (s32)(position._x) + _offsetX ) / _divX;
	s32 y = ( (s32)(position._z) + _offsetZ ) / _divZ;


_checkIndex._x = (f32)( x );
_checkIndex._y = (f32)( y );

	//// 前回衝突がなくカウントが更新されてたら
	//if( !isHit )
	//{
	//	// 最大数をこえてたら処理終了
	//	if( Count >= 5 ) {
	//		// リセット
	//		Count = 0;
	//		return resultPos;
	//	}
	//	// オフセット分ずらす
	//	x += offsetList[Count]._x;
	//	y += offsetList[Count]._z;
	//	// つぎへ
	//	Count++;
	//}

	// 範囲外なら処理しない
	if( x >= _DivCount || y >= _DivCount || x < 0 || y < 0 ) return resultPos;
	

	static f32 prevMinLength = -1;

	// その番号のオブジェクトを調べる
	SystemCollision::Object* pObject = getObject(y * _DivCount + x);

	
	// 初期化
	isHit = false;

	// そのオブジェクトの当たり判定情報を調べる
	//for( s32 t=0; t<pObject->getTriangleCount(); t++ )
	for( s32 t=0; t<pObject->getColDataCount(); t++ )
	{
		//Triangle*	pTriangle = pObject->getTriangle(t);
		Triangle*	pTriangle = &pObject->getColData(t)->_triangle;
		// 三角形の法線取得
		Vector3 triNormal = pTriangle->getNormal();
		// この法線の逆ベクトルをポジションから伸ばす
		// 法線を正規化
		triNormal = triNormal.normalize();
		// 半径に伸ばす
		triNormal *= radius;

		// 当たり判定用ラインの作成
		Line	line;
		line._position[0] = position;
		line._position[1] = position + ( -triNormal );

				
		Vector3	hitPos;
		f32		h;

		// ラインが伸びてなかったら処理しない
		if( line._position[0] == line._position[1] ) continue;

		if( isNear ){
			// 三角形と当たってたら高さ記録
			collision::checkHitPos( *pTriangle, line, &hitPos );
			h = hitPos._y;
		}else{
			// 三角形と当たってたら高さ記録
			if( collision::isHit( *pTriangle, line, &hitPos ) )
			{
				h = hitPos._y;
			}else{
				continue;
			}
		}

		//-----------------------------------------------------------
		// 衝突あり
		//-----------------------------------------------------------
		
		// 頭上の高さ上限チェック
		if( h > position._y + radius * 2.0f ) {
			continue;
		}

		f32 checkLength = (position - hitPos).squareLength();
	
		if( prevMinLength == checkLength )
		{
			// 三角形と当たってたら高さ記録
			collision::checkHitPos( *pTriangle, line, &hitPos );
		}


		// 遠い点なら処理終了
		if(  checkLength >= nearestHitPosLength  )
		{
			continue;
		}

		// 接触点記録
		resultPos	  = hitPos;
		// 一番近い点までの距離を記録
		nearestHitPosLength = checkLength;
		// 当たった三角形の保存
		_LastHitTriangle = pTriangle;
		// 衝突済み
		isHit		  = true;
	}
	prevMinLength = nearestHitPosLength;
	// この時点で見つかったら処理終了
	if( isHit )return resultPos;
	//// 最大までいってなかったら
	////if( Count < 4 )
	//{
	//	resultPos = getHitPos(position, radius);
	//}
	// カウント初期化
	Count = 0;
	return resultPos;
}
// http://sourceforge.net/projects/assimp/forums/forum/817654/topic/3880745
void ofxAssimpModelLoader::updateGLResources(){
        
    // update mesh position for the animation
    for (unsigned int i = 0; i < modelMeshes.size(); ++i){

        // current mesh we are introspecting
        const aiMesh* mesh = modelMeshes[i].mesh;
        
        // calculate bone matrices
        std::vector<aiMatrix4x4> boneMatrices( mesh->mNumBones);
        for( size_t a = 0; a < mesh->mNumBones; ++a)
        {
            const aiBone* bone = mesh->mBones[a];
            
            // find the corresponding node by again looking recursively through the node hierarchy for the same name
            aiNode* node = scene->mRootNode->FindNode(bone->mName);
            
            // start with the mesh-to-bone matrix 
            boneMatrices[a] = bone->mOffsetMatrix;
            // and now append all node transformations down the parent chain until we're back at mesh coordinates again
            const aiNode* tempNode = node;
            while( tempNode)
            {
                // check your matrix multiplication order here!!!
                boneMatrices[a] = tempNode->mTransformation * boneMatrices[a];   
                // boneMatrices[a] = boneMatrices[a] * tempNode->mTransformation;
                tempNode = tempNode->mParent;
            }
        }
        
        // all using the results from the previous code snippet
        std::vector<aiVector3D> resultPos( mesh->mNumVertices); 
        std::vector<aiVector3D> resultNorm( mesh->mNumVertices);
        
        // loop through all vertex weights of all bones
        for( size_t a = 0; a < mesh->mNumBones; ++a)
        {
            const aiBone* bone = mesh->mBones[a];
            const aiMatrix4x4& posTrafo = boneMatrices[a];
            
            // 3x3 matrix, contains the bone matrix without the translation, only with rotation and possibly scaling
            aiMatrix3x3 normTrafo = aiMatrix3x3( posTrafo); 
            for( size_t b = 0; b < bone->mNumWeights; ++b)
            {
                const aiVertexWeight& weight = bone->mWeights[b];
                
                size_t vertexId = weight.mVertexId; 
                const aiVector3D& srcPos = mesh->mVertices[vertexId];
                const aiVector3D& srcNorm = mesh->mNormals[vertexId];
                
                resultPos[vertexId] += weight.mWeight * (posTrafo * srcPos);
                resultNorm[vertexId] += weight.mWeight * (normTrafo * srcNorm);
            }
        }
                
        // now upload the result position and normal along with the other vertex attributes into a dynamic vertex buffer, VBO or whatever
        
        // get mesh helper for this mesh;
        ofxAssimpMeshHelper meshHelper = modelMeshes[i];
        
        glBindBuffer(GL_ARRAY_BUFFER, meshHelper.vertexBuffer);
        aiVertex* verts = (aiVertex*)glMapBuffer(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
        
        for (unsigned int x = 0; x < mesh->mNumVertices; ++x)
        {
            //verts->vPosition = mesh->mVertices[x];
            verts->vPosition = resultPos[x];
            
            if (NULL == mesh->mNormals)
                verts->vNormal = aiVector3D(0.0f,0.0f,0.0f);
            else
                verts->vNormal = resultNorm[x];
            
            if (mesh->HasVertexColors(0))
            {
                verts->dColorDiffuse = mesh->mColors[0][x];
            }
            else
                verts->dColorDiffuse = aiColor4D(1.0, 1.0, 1.0, 1.0);
            
            // This varies slightly form Assimp View, we support the 3rd texture component.
            if (mesh->HasTextureCoords(0))
                verts->vTextureUV = mesh->mTextureCoords[0][x];
            else
                verts->vTextureUV = aiVector3D(0.5f,0.5f, 0.0f);
            
            // No longer in aiVertex VBO structure
            /*          
             if (NULL == mesh->mTangents)
             {
             verts->vTangent = aiVector3D(0.0f,0.0f,0.0f);
             verts->vBitangent = aiVector3D(0.0f,0.0f,0.0f);
             }
             else
             {
             verts->vTangent = mesh->mTangents[x];
             verts->vBitangent = mesh->mBitangents[x];
             }
             
             if (mesh->HasTextureCoords(1))
             verts->vTextureUV2 = mesh->mTextureCoords[1][x];
             else 
             verts->vTextureUV2 = aiVector3D(0.5f,0.5f, 0.0f);
             
             if( mesh->HasBones()){
             unsigned char boneIndices[4] = { 0, 0, 0, 0 };
             unsigned char boneWeights[4] = { 0, 0, 0, 0 };
             ai_assert( weightsPerVertex[x].size() <= 4);
             
             for( unsigned int a = 0; a < weightsPerVertex[x].size(); a++){
             boneIndices[a] = weightsPerVertex[x][a].mVertexId;
             boneWeights[a] = (unsigned char) (weightsPerVertex[x][a].mWeight * 255.0f);
             }
             
             memcpy( verts->mBoneIndices, boneIndices, sizeof( boneIndices));
             memcpy( verts->mBoneWeights, boneWeights, sizeof( boneWeights));
             }
             else{
             // memset( verts->mBoneIndices, 0, sizeof( verts->mBoneIndices));
             // memset( verts->mBoneWeights, 0, sizeof( verts->mBoneWeights));
             }
             */           
            ++verts;
        }
        
        glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); //invalidates verts
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }
}