/**
 *	Convert the handedness of the matrix, such that Z=-Z
 */
void		CFMat4x4::ConvertHandedness( void )
{
	// http://vfxbrain.com/questions/1/how-do-i-convert-a-transformation-matrix-from-right-handed-to-left-handed-coordin
	XMVECTOR* pVecs = reinterpret_cast<XMVECTOR*>( this );
	const static XMVECTOR vA = { 1.0f, 1.0f, -1.0f, 1.0f };
	const static XMVECTOR vB = { -1.0f, -1.0f, 1.0f, -1.0f };

	pVecs[0] = XMVectorMultiply( pVecs[0], vA );
	pVecs[1] = XMVectorMultiply( pVecs[1], vA );
	pVecs[2] = XMVectorMultiply( pVecs[2], vB );
	pVecs[3] = XMVectorMultiply( pVecs[3], vA );
}
Example #2
0
CFVec4&	CFVec4::operator *=	( CFVec4Arg vArg )
{
	XMVECTOR& v4V = *reinterpret_cast<XMVECTOR*>( this );
	const XMVECTOR& v4V2 = *reinterpret_cast<const XMVECTOR*>( &vArg );

	v4V = XMVectorMultiply( v4V, v4V2 );

	return *this;
}
Example #3
0
// scalar opertaors
CFVec4&	CFVec4::operator *=	( const FLOAT32 fArg )
{
	XMVECTOR v4Scaler;
	v4Scaler = XMVectorSet( fArg, fArg, fArg, fArg );

	XMVECTOR& v4V = *reinterpret_cast<XMVECTOR*>( this );

	//Negate
	v4V = XMVectorMultiply( v4V, v4Scaler );

	return *this;
}
Example #4
0
CFVec4		CFVec4::operator *	( CFVec4Arg vArg ) const
{
	CFVec4 v4Return;

	const XMVECTOR& v4V = *reinterpret_cast<const XMVECTOR*>( this );
	const XMVECTOR& v4V2 = *reinterpret_cast<const XMVECTOR*>( &vArg );
	XMVECTOR& v4Result = *reinterpret_cast<XMVECTOR*>( &v4Return );

	//Negate
	v4Result = XMVectorMultiply( v4V, v4V2 );

	return v4Return;
}
Example #5
0
CFVec4&	CFVec4::operator /=	( const FLOAT32 fArg )
{
	FLOAT32 fDivisor = 1.0f / fArg;

	XMVECTOR v4Scaler;
	v4Scaler = XMVectorSet( fDivisor, fDivisor, fDivisor, fDivisor );

	XMVECTOR& v4V = *reinterpret_cast<XMVECTOR*>( this );

	//Negate
	v4V = XMVectorMultiply( v4V, v4Scaler );

	return *this;
}
Example #6
0
CFVec4		CFVec4::operator *	( const FLOAT32 fArg ) const
{
	CFVec4 v4Return;

	XMVECTOR v4Scaler;
	v4Scaler = XMVectorSet( fArg, fArg, fArg, fArg );

	const XMVECTOR& v4V = *reinterpret_cast<const XMVECTOR*>( this );
	XMVECTOR& v4Result = *reinterpret_cast<XMVECTOR*>( &v4Return );

	//Negate
	v4Result = XMVectorMultiply( v4V, v4Scaler );

	return v4Return;
}
Example #7
0
// static
void ff::VectorKey::InitTangents(VectorKey *pKeys, size_t nKeys, float tension)
{
	tension = (1.0f - tension) / 2.0f;

	for (size_t i = 0; i < nKeys; i++)
	{
		const VectorKey &keyBefore = pKeys[i ? i - 1 : nKeys - 1];
		const VectorKey &keyAfter  = pKeys[i + 1 < nKeys ? i + 1 : 0];

		XMStoreFloat4(&pKeys[i]._tangent,
			XMVectorMultiply(
				XMVectorReplicate(tension),
				XMVectorSubtract(
					XMLoadFloat4(&keyAfter._value),
					XMLoadFloat4(&keyBefore._value))));
	}
}
Example #8
0
static HRESULT _PremultiplyAlpha( _In_ const Image& srcImage, _In_ const Image& destImage )
{
    assert( srcImage.width == destImage.width );
    assert( srcImage.height == destImage.height );

    ScopedAlignedArrayXMVECTOR scanline( reinterpret_cast<XMVECTOR*>( _aligned_malloc( (sizeof(XMVECTOR)*srcImage.width), 16 ) ) );
    if ( !scanline )
        return E_OUTOFMEMORY;

    const uint8_t *pSrc = srcImage.pixels;
    uint8_t *pDest = destImage.pixels;
    if ( !pSrc || !pDest )
        return E_POINTER;

    for( size_t h = 0; h < srcImage.height; ++h )
    {
        if ( !_LoadScanline( scanline.get(), srcImage.width, pSrc, srcImage.rowPitch, srcImage.format ) )
            return E_FAIL;

        XMVECTOR* ptr = scanline.get();
        for( size_t w = 0; w < srcImage.width; ++w )
        {
            XMVECTOR v = *ptr;
            XMVECTOR alpha = XMVectorSplatW( *ptr );
            alpha = XMVectorMultiply( v, alpha );
            *(ptr++) = XMVectorSelect( v, alpha, g_XMSelect1110 );
        }

        if ( !_StoreScanline( pDest, destImage.rowPitch, destImage.format, scanline.get(), srcImage.width ) )
            return E_FAIL;

        pSrc += srcImage.rowPitch;
        pDest += destImage.rowPitch;
    }

    return S_OK;
}
Example #9
0
	Vector3 Vector3::operator * (float other) const {
		Vector3 tmp(other, other, other);
		return Vector3(XMVectorMultiply(XMLoadFloat3(&mVector), XMLoadFloat3(&tmp.mVector)));
	}
Example #10
0
	Vector3& Vector3::operator *= (float other) {
		Vector3 tmp(other, other, other);
		XMStoreFloat3(&mVector, XMVectorMultiply(XMLoadFloat3(&mVector), XMLoadFloat3(&tmp.mVector)));
		return *this;
	}
Example #11
0
	bool RayTraceDataGenerator::CalcIntersect(const XMVECTOR& p1, const XMVECTOR& n, XMVECTOR* nResult, XMVECTOR* intersectLocation, float* depth)
	{
		/*
		// grid space
		vec3 grid = floor( pos ); //向下取整将坐标在网格中使用
		vec3 grid_step = sign( dir ); //获取dir(方向)的正负符号<-意思就是说获取网格的步进方向,虽然只是正负
		vec3 corner = max( grid_step, vec3( 0.0 ) );//负号->0 //应该是最后在步进方向上产生的偏差值,但是原因不明

		// ray space
		vec3 inv = vec3( 1.0 ) / dir; //取倒数使得各个方向的比值倒过来
		vec3 ratio = ( grid + corner - pos ) * inv;//corn+pos的小数部分
		vec3 ratio_step = grid_step * inv;//不懂
		//于是这个rayspace只是提供一个比值,来决定grid的步进么

		// dda <-数值微分法
		float hit = -1.0;
		for ( int i = 0; i < 128; i++ ) {
		if ( voxel( grid ) > 0.5 ) {

		hit = 1.0;
		break;   //这里应该是可以直接退出循环的,感觉没什么区别
		continue;
		}

		vec3 cp = step( ratio, ratio.yzx );//二维情况的搞清楚了,问题还有就是在三维空间上的扩展

		mask = cp * ( vec3( 1.0 ) - cp.zxy );

		grid  += grid_step  * mask;
		ratio += ratio_step * mask;
		}

		center = grid + vec3( 0.5 );//中心形式表示(跟grid应该没区别吧0 0)
		return dot(ratio - ratio_step,vec3(1.0)) * hit;//dot( ratio - ratio_step, mask ) * hit;
		//这里关心的是hit的深度好像
		*/
		//p1是起点
		XMVECTOR start = p1;
		XMVECTOR dir = n;
		XMVECTOR zero = XMVectorSetBinaryConstant(0, 0, 0, 0);
		XMVECTOR one = XMVectorSetBinaryConstant(1, 1, 1, 1);


		XMVECTOR grid;
		XMVECTOR grid_step;
		XMVECTOR grid_corner;
		grid = XMVectorFloor(start);//实际上w分量为0应该就不影响了吧(
		//好像DirectXMath没有提供Sign的函数(于是用了一个挺别扭的方法- -
		//grid_step 就是 sign_dir
		grid_step = DirectX::XMVectorOrInt(DirectX::XMVectorAndInt(dir, DirectX::XMVectorSplatSignMask()), DirectX::XMVectorSplatOne());
		grid_corner = XMVectorClamp(grid_step, zero, one);

		XMVECTOR inv;
		XMVECTOR ratio;
		XMVECTOR ratio_step;
		inv = XMVectorReciprocal(dir);
		ratio = XMVectorMultiply(XMVectorSubtract(XMVectorAdd(grid, grid_corner), start), inv);
		ratio_step = XMVectorMultiply(grid_step, inv);

		bool hit = false;
		XMVECTOR cp;
		XMVECTOR mask;
		XMVECTOR ratioyzx;
		XMVECTOR cpzxy;
		XMFLOAT4 tmp1;
		XMFLOAT4 tmp2;
		int i;
		for (i = 0; i < 128; ++i)//最大深度为128
		{
			XMStoreFloat4(&tmp1, grid);
			/*
			__try{
			if (map->At(tmp1.x, tmp1.y, tmp1.z).TexType != -1)
			{
			hit = true;
			break;
			}
			}
			__except ((GetExceptionCode() == EXCEPTION_ARRAY_BOUNDS_EXCEEDED)?EXCEPTION_EXECUTE_HANDLER:EXCEPTION_CONTINUE_SEARCH)
			{
			//捕获越界错误作为跳出条件,看看有没有问题...
			break;
			}
			*/
			//理论上来说异常的话处理代价太大,还是判断一下range吧= =
			if ((RangeCheck(tmp1.x, tmp1.y, tmp1.z)))
			{
				if (GetLocInfo(tmp1.x, tmp1.y, tmp1.z) != -1)
				{
					hit = true;
					break;
				}
			}
			/*
			修正:发生越界的时候并不一定就要终止,需要考虑到从值域外射出的射线.....
			不过就算不break效率应该也比原先的算法要高...(除了要限制一下最大遍历深度这方面
			*/


			XMStoreFloat4(&tmp1, ratio);
			tmp2.x = tmp1.y; tmp2.y = tmp1.z; tmp2.z = tmp1.x;
			ratioyzx = XMLoadFloat4(&tmp2);

			cp = XMVectorAndInt(XMVectorGreaterOrEqual(ratioyzx, ratio), XMVectorSplatOne());//1 or 0
			XMStoreFloat4(&tmp1, cp);
			tmp2.x = tmp1.z; tmp2.y = tmp1.x; tmp2.z = tmp1.y;
			cpzxy = XMLoadFloat4(&tmp2);
			mask = XMVectorMultiply(cp, XMVectorSubtract(one, cpzxy));

			grid += XMVectorMultiply(grid_step, mask);
			ratio += XMVectorMultiply(ratio_step, mask);
		}
		if (hit)
		{

			XMFLOAT4 result;
			result = tmp1; //所在方块
			if (i == 0)
			{
				//这是在方块内部的情况
				result.w = -1;
				return false;
			}
			XMVECTOR ftmp;
			ftmp = XMVectorSubtract(ratio, ratio_step);//因为取的只是mask方向的值,所以step在这里没必要乘mask
			*depth = XMVectorGetX(DirectX::XMVector3Dot(ftmp, mask));
			ftmp = XMVectorAdd(XMVectorScale(dir,*depth) , p1);
			XMStoreFloat4(&tmp1, ftmp);
			//需要全部反过来,因为上面的式子没有取反
			*intersectLocation = ftmp;
			result = tmp1;
			result.w = 0;

			XMVECTOR normal;
			normal = XMVectorMultiply(mask, grid_step);
			XMStoreFloat4(&tmp1, normal);
			//需要全部反过来,因为上面的式子没有取反
			if (tmp1.x > 0.5)
			{
				//法向量为1,0,0,后方
				*nResult = XMVectorSetBinaryConstant(1, 0, 0, 0);
			}
			else if (tmp1.x < -0.5)
			{
				//法向量为-1,0,0,前方
				*nResult = XMVectorSetBinaryConstant(-1, 0, 0, 0);
			}
			else if (tmp1.y < -0.5)
			{
				//法向量为0,-1,0,右方
				*nResult = XMVectorSetBinaryConstant(0, -1, 0, 0);
			}
			else if (tmp1.y > 0.5)
			{
				//法向量为0,1,0,左方
				*nResult = XMVectorSetBinaryConstant(0, 1, 0, 0);
			}
			else if (tmp1.z < -0.5)
			{
				//法向量为0,0,-1,上方
				*nResult = XMVectorSetBinaryConstant(0, 0, -1, 0);
			}
			else if (tmp1.z > 0.5)
			{
				//法向量为0,0,1,下方
				*nResult = XMVectorSetBinaryConstant(0, 0, 1, 0);
			}
			return true;
			//return result;
		}
		else
		{
			return false;
		}
		//上面成功的进行了判断,可以得出grid编号了,不过还要算一下相交面(
		return false;
	}
Example #12
0
_Use_decl_annotations_
__forceinline XMVECTOR __vectorcall FindSupportVectorAndReduce(XMVECTOR simplex[5], FXMVECTOR x, uint32_t* bits)
{
    uint32_t bit = 1;
    uint32_t i = 0;
    uint32_t bitCount = 0;
    XMVECTOR compact[4];
    uint32_t compactBits[4] = {};
    for (; i < 5; ++i, bit <<= 1)
    {
        if (((*bits) & bit) == bit)
        {
            compactBits[bitCount] = bit;
            compact[bitCount++] = simplex[i];
        }
    }

    XMVECTOR v;

    switch (bitCount)
    {
    case 0:     // Error, empty simplex!
        assert(false);
        return XMVectorZero();

    case 1:     // Point
        v = x - compact[0];
        break;

    case 2:     // Segment
    {
        XMVECTOR edge = compact[1] - compact[0];
        v = XMVector3Cross(edge, XMVector3Cross(x - compact[0], edge));
        break;
    }

    case 4:     // Tetrahedron
    {
        // Reduce. For each point, consider the triangle
        // formed by the other 3. If x & this point are on the same
        // side, then this point is valid. If x is on opposite side, we
        // drop this point
        XMVECTOR others[3];
        uint32_t count = 0;
        for (uint32_t i = 0; i < 4; ++i)
        {
            XMVECTOR p = compact[i];
            count = 0;
            for (uint32_t j = 0; j < 4; ++j)
            {
                if (i != j)
                {
                    others[count++] = compact[j];
                }
            }

            XMVECTOR edge0 = others[1] - others[0];
            XMVECTOR edge1 = others[2] - others[0];
            XMVECTOR n = XMVector3Cross(edge0, edge1);
            if (XMVector2LessOrEqual(XMVectorMultiply(XMVector3Dot(n, x - others[0]), XMVector3Dot(n, p - others[0])), XMVectorZero()))
            {
                (*bits) &= ~compactBits[i];
                for (uint32_t j = i; j < 3; ++j)
                {
                    compact[j] = compact[j + 1];
                }
                --bitCount;
                break;
            }
        }

        if (bitCount == 4)
        {
            // Couldn't reduce the simplex. Just drop the front most point and rotate
            simplex[0] = compact[0];
            simplex[1] = compact[1];
            simplex[2] = compact[2];
            *bits = 7;
        }

        __fallthrough;
    }

    case 3:     // Triangle
    {
        XMVECTOR edge0 = compact[1] - compact[0];
        XMVECTOR edge1 = compact[2] - compact[0];
        v = XMVector3Cross(edge0, edge1);
        if (XMVector2Less(XMVector3Dot(v, x - compact[0]), XMVectorZero()))
        {
            v = -v;
        }
        break;
    }

    default:
        assert(false);
        return XMVectorZero();
    }

    v = XMVector3Normalize(v);
    v *= XMVector3Dot(v, x - compact[0]);
    return v;
}
Example #13
0
void Transform::Scale(const XMFLOAT3& scale)
{
	XMStoreFloat3(&this->scale, XMVectorMultiply(XMLoadFloat3(&this->scale), XMLoadFloat3(&scale)));

	isDirty = true;
}
bool CollisionMesh::CheckCollisionsCustom(CollisionMesh &otherMesh)
{
  bool collision = false;
  std::vector<XMFLOAT3> convexHull;

  std::vector<VPCNTDesc> vertices = GetVertices();
  std::vector<VPCNTDesc> otherVertices = otherMesh.GetVertices();
  XMMATRIX otherWorld = otherMesh.GetWorldTransform();
  XMMATRIX world = GetWorldTransform();
  XMFLOAT3 origin = XMFLOAT3(0.0f, 0.0f, 0.0f);

  // Create a vector to ease the inversion calculation (we want the opposite direction for the translation vector).
  XMVECTOR inverse = XMVectorSet(-1.0f, -1.0f, -1.0f, 0.0f);
  
  XMVECTOR ourOriginDisplacement = XMVector3Transform(XMVectorSet(origin.x, origin.y, origin.z, 0.0f), world);
  XMMATRIX ourOriginTransform = XMMatrixTranslationFromVector(XMVectorMultiply(ourOriginDisplacement, inverse));

  // This is used for the purposes of moving the normals of the other object back to around (0, 0, 0).
  XMVECTOR theirOriginDisplacement = XMVector3Transform(XMVectorSet(origin.x, origin.y, origin.z, 0.0f), otherWorld);
  XMMATRIX theirOriginTransform = XMMatrixTranslationFromVector(XMVectorMultiply(theirOriginDisplacement, inverse));

  XMMATRIX ourOriginTranslatedWorld = world * ourOriginTransform;
  XMMATRIX theirOriginTranslatedWorld = otherWorld * ourOriginTransform;
  XMMATRIX theirOriginTranslatedWorldNormalAdjustment = theirOriginTransform * otherWorld;

  // Pre-multiply the model's vertices so as to avoid transforming them during comparison.
  for (int vertIndex = 0; vertIndex < vertices.size(); vertIndex++)
  {
    XMStoreFloat3(&vertices[vertIndex].Position, XMVector3Transform(XMLoadFloat3(&vertices[vertIndex].Position), ourOriginTranslatedWorld));
    XMStoreFloat3(&vertices[vertIndex].Normal, XMVector3Transform(XMLoadFloat3(&vertices[vertIndex].Normal), ourOriginTranslatedWorld));
  }

  for (int otherVertIndex = 0; otherVertIndex < otherVertices.size(); otherVertIndex++)
  {
    XMStoreFloat3(&otherVertices[otherVertIndex].Position, XMVector3Transform(XMLoadFloat3(&otherVertices[otherVertIndex].Position), theirOriginTranslatedWorld));
    XMStoreFloat3(&otherVertices[otherVertIndex].Normal, XMVector3Transform(XMLoadFloat3(&otherVertices[otherVertIndex].Normal), theirOriginTranslatedWorldNormalAdjustment));
  }

  int potentialCollisions = 0;
  std::vector<XMFLOAT3> positions;

  // Now that the pre-multiplication is done, time to do our first-case checking: are we inside of it?
  for (int vertIndex = 0; vertIndex < vertices.size(); vertIndex++)
  {
    bool localCollision = true;
    XMVECTOR ourVertex = XMLoadFloat3(&vertices[vertIndex].Position);
    XMVECTOR ourNormal = XMLoadFloat3(&vertices[vertIndex].Normal);

    // For each vertex in our mesh, we'll check to see if it resides inside our other mesh.
    for (int otherVertIndex = 0; otherVertIndex < otherVertices.size(); otherVertIndex++)
    {
      XMVECTOR otherVertex = XMLoadFloat3(&otherVertices[otherVertIndex].Position);
      XMVECTOR otherNormal = XMLoadFloat3(&otherVertices[otherVertIndex].Normal);

      XMVECTOR difference = XMVectorSubtract(ourVertex, otherVertex);
      XMFLOAT3 differenceDotValue, normalDotValue;
      XMVECTOR diffLength = XMVector3Length(difference);
      XMVECTOR normLength = XMVector3Length(otherNormal);
      XMVECTOR magnitude = XMVectorMultiply(diffLength, normLength);

      XMStoreFloat3(&differenceDotValue, XMVectorDivide(XMVector3Dot(difference, otherNormal), magnitude));
      // At this point, we should have the cosine of the angle.
      float angleInRads = acosf(differenceDotValue.x);
      float angleInDegs = XMConvertToDegrees(angleInRads);

      XMStoreFloat3(&normalDotValue, XMVector3Dot(ourNormal, otherNormal));

      if (angleInDegs < 90.0f)
      {
        localCollision = false;
      }
    }

    if (localCollision)
    {
      positions.push_back(vertices[vertIndex].Position);
    }
  }

  if (positions.empty())
  {
    // Time to do our second-case checking: is it inside of us?
    for (int otherVertIndex = 0; otherVertIndex < otherVertices.size(); otherVertIndex++)
    {
      bool localCollision = true;
      XMVECTOR otherVertex = XMLoadFloat3(&otherVertices[otherVertIndex].Position);
      XMVECTOR otherNormal = XMVector3Normalize(XMLoadFloat3(&otherVertices[otherVertIndex].Normal));

      // For each vertex in our mesh, we'll check to see if it resides inside our other mesh.
      for (int vertIndex = 0; vertIndex < vertices.size(); vertIndex++)
      {
        XMVECTOR ourVertex = XMLoadFloat3(&vertices[vertIndex].Position);
        XMVECTOR ourNormal = XMVector3Normalize(XMLoadFloat3(&vertices[vertIndex].Normal));

        XMVECTOR difference = XMVectorSubtract(otherVertex, ourVertex);
        XMFLOAT3 differenceDotValue, normalDotValue;
        XMVECTOR diffLength = XMVector3Length(difference);
        XMVECTOR normLength = XMVector3Length(ourNormal);
        XMVECTOR magnitude = XMVectorMultiply(diffLength, normLength);

        XMStoreFloat3(&differenceDotValue, XMVectorDivide(XMVector3Dot(difference, ourNormal), magnitude));
        // At this point, we should have the cosine of the angle.
        float angleInRads = acosf(differenceDotValue.x);
        float angleInDegs = XMConvertToDegrees(angleInRads);

        XMStoreFloat3(&normalDotValue, XMVector3Dot(ourNormal, otherNormal));

        if (angleInDegs < 90.0f)
        {
          localCollision = false;
        }
      }

      if (localCollision)
      {
        positions.push_back(otherVertices[otherVertIndex].Position);
      }
    }
  }

  if(positions.size())
  {
    mDelegate->CollisionOccurred(otherMesh.mDelegate);
    otherMesh.mDelegate->CollisionOccurred(mDelegate);
  }
  return positions.size();
}