This Feature is made to mimic the Bill type but ignore the Y rotation of it. That way you can create even better SFX!

Example 1:

Example 2:

In order to support Bill Type XZ in your Neuz(source code), you need to be able to compile it and have some experience adding new code!

First, open your ..\_Common\sfxbase.h

You should see this:

enum SFXPARTBILLTYPE {
	SFXPARTBILLTYPE_BILL=1,
	SFXPARTBILLTYPE_BOTTOM=2,
	SFXPARTBILLTYPE_POLE=3,
	SFXPARTBILLTYPE_NORMAL=4,
};

Change it to this:

enum SFXPARTBILLTYPE {
	SFXPARTBILLTYPE_BILL=1,
	SFXPARTBILLTYPE_BOTTOM=2,
	SFXPARTBILLTYPE_POLE=3,
	SFXPARTBILLTYPE_NORMAL=4,
	SFXPARTBILLTYPE_BILLXZ = 5,
};

Next, open your ..\_Common\sfxbase.cpp

Inside void CSfxPartBill::Render2( D3DXVECTOR3 vPos, WORD nFrame, D3DXVECTOR3 fAngle, D3DXVECTOR3 vScale ), you can see this:

	case SFXPARTBILLTYPE_NORMAL: // º¸ÅëÀ̸é.
		{ // ±×³É º¸Åë ¿ÀºêÁ§Æ®Ã³·³...
			D3DXMATRIX mRot;
			D3DXVECTOR3 vRot  = DEGREETORADIAN(fAngle);
			D3DXVECTOR3 vTemp2=DEGREETORADIAN( Key.vRotate );
			D3DXMatrixRotationYawPitchRoll( &matAngle, vTemp2.y, vTemp2.x, vTemp2.z );
			D3DXMatrixRotationYawPitchRoll(&mRot,vRot.y,vRot.x,vRot.z);
			D3DXMatrixScaling( &matScale, vScaleTemp.x, vScaleTemp.y, vScaleTemp.z );
			matTemp = matScale * matAngle * mRot;
			break;
		}

Add the following BELOW it:

case SFXPARTBILLTYPE_BILLXZ:
{
	D3DXMATRIX mRot;
	D3DXVECTOR3 vRot = DEGREETORADIAN(fAngle);
	D3DXVECTOR3 vTemp2 = DEGREETORADIAN(Key.vRotate);
	D3DXMatrixRotationYawPitchRoll(&matAngle, vTemp2.y, vTemp2.x, vTemp2.z);
	D3DXMatrixRotationYawPitchRoll(&mRot, vRot.y, vRot.x, vRot.z);
	D3DXMatrixScaling(&matScale, vScaleTemp.x, vScaleTemp.y, vScaleTemp.z);
        D3DXMATRIX normalOrient;
        D3DXMatrixMultiply(&normalOrient, &matScale, &matAngle);
        D3DXMatrixMultiply(&normalOrient, &normalOrient, &mRot);
	D3DXMATRIX billRotation = g_matView;
	billRotation._41 = billRotation._42 = billRotation._43 = 0.0f;

	
	billRotation._21 = 0.0f;
	billRotation._22 = 1.0f;
	billRotation._23 = 0.0f;

	D3DXMATRIX billOrient;
	D3DXMatrixInverse(&billOrient, NULL, &billRotation);

	D3DXMATRIX scaledBillOrient;
	D3DXMatrixScaling(&scaledBillOrient, vScaleTemp.x, vScaleTemp.y, vScaleTemp.z);
	scaledBillOrient = scaledBillOrient * billOrient;

	D3DXVECTOR3 normUp(normalOrient._21, normalOrient._22, normalOrient._23);
	D3DXVECTOR3 billRight(scaledBillOrient._11, scaledBillOrient._12, scaledBillOrient._13);
	D3DXVECTOR3 billForward(scaledBillOrient._31, scaledBillOrient._32, scaledBillOrient._33);

	matTemp._11 = billRight.x; matTemp._12 = billRight.y; matTemp._13 = billRight.z; matTemp._14 = 0.0f;
	matTemp._21 = normUp.x; matTemp._22 = normUp.y; matTemp._23 = normUp.z; matTemp._24 = 0.0f;
	matTemp._31 = billForward.x; matTemp._32 = billForward.y; matTemp._33 = billForward.z; matTemp._34 = 0.0f;
	matTemp._41 = normalOrient._41; matTemp._42 = normalOrient._42; matTemp._43 = normalOrient._43; matTemp._44 = 1.0f;

	break;
}

Next, locate void CSfxPartBill::Render( D3DXVECTOR3 vPos, WORD nFrame, FLOAT fAngle, D3DXVECTOR3 vScale ) and you will see this:

	case SFXPARTBILLTYPE_NORMAL:
		{
			D3DXVECTOR3 vTemp2=DEGREETORADIAN( Key.vRotate + D3DXVECTOR3( .0f, fAngle, .0f ) );
			D3DXMatrixRotationYawPitchRoll( &matAngle, vTemp2.y, vTemp2.x, vTemp2.z );
			D3DXMatrixScaling( &matScale, vScaleTemp.x, vScaleTemp.y, vScaleTemp.z );
			matTemp = matScale * matAngle;
			break;
		}

Add the following BELOW it:

case SFXPARTBILLTYPE_BILLXZ:
{
	D3DXVECTOR3 temp = Key.vRotate;
	temp.y += fAngle; 
	D3DXVECTOR3 vTemp2 = DEGREETORADIAN(temp);
	D3DXMatrixRotationYawPitchRoll(&matAngle, vTemp2.y, vTemp2.x, vTemp2.z);
	D3DXMatrixScaling(&matScale, vScaleTemp.x, vScaleTemp.y, vScaleTemp.z);
	D3DXMATRIX normalOrient = matScale * matAngle;

	D3DXMATRIX billRotation = g_matView;
	billRotation._41 = billRotation._42 = billRotation._43 = 0.0f;

	billRotation._21 = 0.0f;
	billRotation._22 = 1.0f;
	billRotation._23 = 0.0f;

	D3DXMATRIX billOrient;
	D3DXMatrixInverse(&billOrient, NULL, &billRotation);

	D3DXMATRIX scaledBillOrient;
	D3DXMatrixScaling(&scaledBillOrient, vScaleTemp.x, vScaleTemp.y, vScaleTemp.z);
	scaledBillOrient = scaledBillOrient * billOrient;

	D3DXVECTOR3 normUp(normalOrient._21, normalOrient._22, normalOrient._23);
	D3DXVECTOR3 billRight(scaledBillOrient._11, scaledBillOrient._12, scaledBillOrient._13);
	D3DXVECTOR3 billForward(scaledBillOrient._31, scaledBillOrient._32, scaledBillOrient._33);

	matTemp._11 = billRight.x; matTemp._12 = billRight.y; matTemp._13 = billRight.z; matTemp._14 = 0.0f;
	matTemp._21 = normUp.x; matTemp._22 = normUp.y; matTemp._23 = normUp.z; matTemp._24 = 0.0f;
	matTemp._31 = billForward.x; matTemp._32 = billForward.y; matTemp._33 = billForward.z; matTemp._34 = 0.0f;
	matTemp._41 = normalOrient._41; matTemp._42 = normalOrient._42; matTemp._43 = normalOrient._43; matTemp._44 = 1.0f;

	break;
}

Next, locate void CSfxPartParticle::Render( D3DXVECTOR3 vPos, WORD nFrame, FLOAT fAngle, D3DXVECTOR3 vScale ) and you will see this:

	case SFXPARTBILLTYPE_NORMAL:
		{
			D3DXVECTOR3 vTemp2=DEGREETORADIAN(Key.vRotate);
			D3DXMatrixRotationYawPitchRoll(&matAngle,vTemp2.y,vTemp2.x,vTemp2.z);
			D3DXMatrixScaling(&matScale,Key.vScale.x,Key.vScale.y,1.0f);
			matTemp=matScale*matAngle;
			break;
		}

Add the following BELOW it:

case SFXPARTBILLTYPE_BILLXZ:
{
	D3DXVECTOR3 vTemp2 = DEGREETORADIAN(Key.vRotate);
	D3DXMatrixRotationYawPitchRoll(&matAngle, vTemp2.y, vTemp2.x, vTemp2.z);
	D3DXMatrixScaling(&matScale, Key.vScale.x, Key.vScale.y, 1.0f);

	D3DXMATRIX normalOrient = matScale * matAngle;
	D3DXMATRIX billRotation = g_matView;
	billRotation._41 = billRotation._42 = billRotation._43 = 0.0f;

	billRotation._21 = 0.0f;
	billRotation._22 = 1.0f;
	billRotation._23 = 0.0f;

	D3DXMATRIX billOrient;
	D3DXMatrixInverse(&billOrient, NULL, &billRotation);

	D3DXVECTOR3 normUp(normalOrient._21, normalOrient._22, normalOrient._23);
	D3DXVECTOR3 billRight(billOrient._11, billOrient._12, billOrient._13);
	D3DXVECTOR3 billForward(billOrient._31, billOrient._32, billOrient._33);

	matTemp._11 = billRight.x; matTemp._12 = billRight.y; matTemp._13 = billRight.z; matTemp._14 = 0.0f;
	matTemp._21 = normUp.x; matTemp._22 = normUp.y; matTemp._23 = normUp.z; matTemp._24 = 0.0f;
	matTemp._31 = billForward.x; matTemp._32 = billForward.y; matTemp._33 = billForward.z; matTemp._34 = 0.0f;
	matTemp._41 = normalOrient._41; matTemp._42 = normalOrient._42; matTemp._43 = normalOrient._43; matTemp._44 = 1.0f;

	break;
}

Next, locate void CSfxPartCustomMesh::Render( D3DXVECTOR3 vPos, WORD nFrame, FLOAT fAngle, D3DXVECTOR3 vScale ) and you will see this:

	case SFXPARTBILLTYPE_NORMAL:
		{
			D3DXVECTOR3 vTemp2=DEGREETORADIAN(Key.vRotate+D3DXVECTOR3(.0f,fAngle,.0f));
			D3DXMatrixRotationYawPitchRoll(&matAngle,vTemp2.y,vTemp2.x,vTemp2.z);
//			D3DXMatrixScaling(&matScale,Key.vScale.x,Key.vScale.y,1.0f);
			matTemp=matAngle;
			break;
		}

Add the following BELOW it:

case SFXPARTBILLTYPE_BILLXZ:
{
	D3DXVECTOR3 temp = Key.vRotate;
	temp.y += fAngle;
	D3DXVECTOR3 vTemp2 = DEGREETORADIAN(temp);
	D3DXMatrixRotationYawPitchRoll(&matAngle, vTemp2.y, vTemp2.x, vTemp2.z);

	D3DXMATRIX normalOrient = matAngle;

	D3DXMATRIX billRotation = g_matView;
	billRotation._41 = billRotation._42 = billRotation._43 = 0.0f;

	billRotation._21 = 0.0f;
	billRotation._22 = 1.0f;
	billRotation._23 = 0.0f;

	D3DXMATRIX billOrient;
	D3DXMatrixInverse(&billOrient, NULL, &billRotation);

	D3DXMATRIX scaledBillOrient;
	D3DXMatrixScaling(&scaledBillOrient, Key.vScale.x, Key.vScale.y, Key.vScale.z);
	scaledBillOrient = scaledBillOrient * billOrient;

	D3DXVECTOR3 normUp(normalOrient._21, normalOrient._22, normalOrient._23);
	D3DXVECTOR3 billRight(scaledBillOrient._11, scaledBillOrient._12, scaledBillOrient._13);
	D3DXVECTOR3 billForward(scaledBillOrient._31, scaledBillOrient._32, scaledBillOrient._33);

	matTemp._11 = billRight.x; matTemp._12 = billRight.y; matTemp._13 = billRight.z; matTemp._14 = 0.0f;
	matTemp._21 = normUp.x; matTemp._22 = normUp.y; matTemp._23 = normUp.z; matTemp._24 = 0.0f;
	matTemp._31 = billForward.x; matTemp._32 = billForward.y; matTemp._33 = billForward.z; matTemp._34 = 0.0f;
	matTemp._41 = normalOrient._41; matTemp._42 = normalOrient._42; matTemp._43 = normalOrient._43; matTemp._44 = 1.0f;

	break;
}

Next, locate void CSfxPartCustomMesh::Render2( D3DXVECTOR3 vPos, WORD nFrame, D3DXVECTOR3 fAngle, D3DXVECTOR3 vScale ) and you will see this:

	case SFXPARTBILLTYPE_NORMAL:
		{
			D3DXMATRIX mRot;
			D3DXVECTOR3 vRot  = DEGREETORADIAN(fAngle);
			D3DXVECTOR3 vTemp2=DEGREETORADIAN(Key.vRotate);
			D3DXMatrixRotationYawPitchRoll(&matAngle,vTemp2.y,vTemp2.x,vTemp2.z);
			D3DXMatrixRotationYawPitchRoll(&mRot,vRot.y,vRot.x,vRot.z);
			matTemp=matAngle * mRot;
			break;
		}

Add the following BELOW it:

case SFXPARTBILLTYPE_BILLXZ:
{
	D3DXMATRIX mRot;
	D3DXVECTOR3 temp = Key.vRotate;
	temp.y += fAngle.y; 
	D3DXVECTOR3 vTemp2 = DEGREETORADIAN(temp);
	D3DXMatrixRotationYawPitchRoll(&matAngle, vTemp2.y, vTemp2.x, vTemp2.z);

	D3DXMATRIX normalOrient = matAngle;

	D3DXMATRIX billRotation = g_matView;
	billRotation._41 = billRotation._42 = billRotation._43 = 0.0f;

	billRotation._21 = 0.0f;
	billRotation._22 = 1.0f;
	billRotation._23 = 0.0f;

	D3DXMATRIX billOrient;
	D3DXMatrixInverse(&billOrient, NULL, &billRotation);

	D3DXMATRIX scaledBillOrient;
	D3DXMatrixScaling(&scaledBillOrient, Key.vScale.x, Key.vScale.y, Key.vScale.z);
	scaledBillOrient = scaledBillOrient * billOrient;

	D3DXVECTOR3 normUp(normalOrient._21, normalOrient._22, normalOrient._23);
	D3DXVECTOR3 billRight(scaledBillOrient._11, scaledBillOrient._12, scaledBillOrient._13);
	D3DXVECTOR3 billForward(scaledBillOrient._31, scaledBillOrient._32, scaledBillOrient._33);

	matTemp._11 = billRight.x; matTemp._12 = billRight.y; matTemp._13 = billRight.z; matTemp._14 = 0.0f;
	matTemp._21 = normUp.x; matTemp._22 = normUp.y; matTemp._23 = normUp.z; matTemp._24 = 0.0f;
	matTemp._31 = billForward.x; matTemp._32 = billForward.y; matTemp._33 = billForward.z; matTemp._34 = 0.0f;
	matTemp._41 = normalOrient._41; matTemp._42 = normalOrient._42; matTemp._43 = normalOrient._43; matTemp._44 = 1.0f;

	break;
}

Next, locate void CSfxModel::RenderParticles2( D3DXVECTOR3 vPos, WORD nFrame, D3DXVECTOR3 fAngle, CSfxPartParticle* pPartParticle, CPtrArray* pParticles, D3DXVECTOR3 vScale ) and you will see this:

	case SFXPARTBILLTYPE_NORMAL:
		{
			D3DXMATRIX mRot;
			D3DXVECTOR3 vRot  = DEGREETORADIAN(fAngle);
			D3DXVECTOR3 vTemp2=DEGREETORADIAN(Key.vRotate);
			D3DXMatrixRotationYawPitchRoll(&matAngle,vTemp2.y,vTemp2.x,vTemp2.z);
			D3DXMatrixRotationYawPitchRoll(&mRot,vRot.y,vRot.x,vRot.z);
			//			D3DXMatrixScaling(&matScale,Key.vScale.x,Key.vScale.y,1.0f);
			matTemp=matAngle * mRot;
			break;
		}

Add the following BELOW it:

case SFXPARTBILLTYPE_BILLXZ:
{
	D3DXMATRIX mRot;
	D3DXVECTOR3 vRot = DEGREETORADIAN(fAngle);
	D3DXVECTOR3 vTemp2 = DEGREETORADIAN(Key.vRotate);
	D3DXMatrixRotationYawPitchRoll(&matAngle, vTemp2.y, vTemp2.x, vTemp2.z);
	D3DXMatrixRotationYawPitchRoll(&mRot, vRot.y, vRot.x, vRot.z);
	D3DXVECTOR3 vScaleTemp;
	vScaleTemp.x = Key.vScale.x;
	vScaleTemp.y = Key.vScale.y;
	vScaleTemp.z = Key.vScale.z;
	D3DXMatrixScaling(&matScale, vScaleTemp.x, vScaleTemp.y, vScaleTemp.z);

        D3DXMATRIX normalOrient;
        D3DXMatrixMultiply(&normalOrient, &matScale, &matAngle);
        D3DXMatrixMultiply(&normalOrient, &normalOrient, &mRot);

	D3DXMATRIX billRotation = g_matView;
	billRotation._41 = billRotation._42 = billRotation._43 = 0.0f;

	billRotation._21 = 0.0f;
	billRotation._22 = 1.0f;
	billRotation._23 = 0.0f;

	D3DXMATRIX billOrient;
	D3DXMatrixInverse(&billOrient, NULL, &billRotation);

	D3DXVECTOR3 normRight(normalOrient._11, normalOrient._12, normalOrient._13);
	D3DXVECTOR3 normUp(normalOrient._21, normalOrient._22, normalOrient._23);
	D3DXVECTOR3 normForward(normalOrient._31, normalOrient._32, normalOrient._33);

	D3DXVECTOR3 billRight(billOrient._11, billOrient._12, billOrient._13);
	D3DXVECTOR3 billForward(billOrient._31, billOrient._32, billOrient._33);

	matTemp._11 = billRight.x; matTemp._12 = billRight.y; matTemp._13 = billRight.z; matTemp._14 = 0.0f;
	matTemp._21 = normUp.x; matTemp._22 = normUp.y; matTemp._23 = normUp.z; matTemp._24 = 0.0f;
	matTemp._31 = billForward.x; matTemp._32 = billForward.y; matTemp._33 = billForward.z; matTemp._34 = 0.0f;
	matTemp._41 = normalOrient._41; matTemp._42 = normalOrient._42; matTemp._43 = normalOrient._43; matTemp._44 = 1.0f;

	break;
}

Lastly, locate void CSfxModel::RenderParticles( D3DXVECTOR3 vPos, WORD nFrame, FLOAT fAngle, CSfxPartParticle* pPartParticle, CPtrArray* pParticles, D3DXVECTOR3 vScale ) and you will see this:

	case SFXPARTBILLTYPE_NORMAL:
		{
			D3DXVECTOR3 vTemp2=DEGREETORADIAN(Key.vRotate+D3DXVECTOR3(.0f,fAngle,.0f));
			D3DXMatrixRotationYawPitchRoll(&matAngle,vTemp2.y,vTemp2.x,vTemp2.z);
			matTemp=matAngle;
			break;
		}

Add the following BELOW it:

case SFXPARTBILLTYPE_BILLXZ:
{
	D3DXMATRIX mRot;
	D3DXVECTOR3 vRot(0.0f, DEGREETORADIAN(fAngle), 0.0f);
	D3DXVECTOR3 vTemp2 = DEGREETORADIAN(Key.vRotate);
	D3DXMatrixRotationYawPitchRoll(&matAngle, vTemp2.y, vTemp2.x, vTemp2.z);
	D3DXMatrixRotationYawPitchRoll(&mRot, vRot.y, vRot.x, vRot.z);
	D3DXVECTOR3 vScaleTemp;
	vScaleTemp.x = Key.vScale.x;
	vScaleTemp.y = Key.vScale.y;
	vScaleTemp.z = Key.vScale.z;
	D3DXMatrixScaling(&matScale, vScaleTemp.x, vScaleTemp.y, vScaleTemp.z);

        D3DXMATRIX normalOrient;
        D3DXMatrixMultiply(&normalOrient, &matScale, &matAngle);
        D3DXMatrixMultiply(&normalOrient, &normalOrient, &mRot);

	D3DXMATRIX billRotation = g_matView;
	billRotation._41 = billRotation._42 = billRotation._43 = 0.0f;

	billRotation._21 = 0.0f;
	billRotation._22 = 1.0f;
	billRotation._23 = 0.0f;

	D3DXMATRIX billOrient;
	D3DXMatrixInverse(&billOrient, NULL, &billRotation);

	D3DXVECTOR3 normRight(normalOrient._11, normalOrient._12, normalOrient._13);
	D3DXVECTOR3 normUp(normalOrient._21, normalOrient._22, normalOrient._23);
	D3DXVECTOR3 normForward(normalOrient._31, normalOrient._32, normalOrient._33);

	D3DXVECTOR3 billRight(billOrient._11, billOrient._12, billOrient._13);
	D3DXVECTOR3 billForward(billOrient._31, billOrient._32, billOrient._33);

	matTemp._11 = billRight.x; matTemp._12 = billRight.y; matTemp._13 = billRight.z; matTemp._14 = 0.0f;
	matTemp._21 = normUp.x; matTemp._22 = normUp.y; matTemp._23 = normUp.z; matTemp._24 = 0.0f;
	matTemp._31 = billForward.x; matTemp._32 = billForward.y; matTemp._33 = billForward.z; matTemp._34 = 0.0f;
	matTemp._41 = normalOrient._41; matTemp._42 = normalOrient._42; matTemp._43 = normalOrient._43; matTemp._44 = 1.0f;

	break;
}

That's it! Your Neuz should now support Bill Type XZ! Make sure to compile your Neuz and try it - enjoy!

Last updated