예제 #1
0
파일: render.cpp 프로젝트: ema29/TemplePlus
bool ParticleRenderer::GetEmitterWorldMatrix(const PartSysEmitter* emitter, D3DMATRIX& worldMatrix) {
    D3DXMATRIX pM1;

    auto spec = emitter->GetSpec();
    auto particleSpace = spec->GetParticleSpace();
    auto emitterSpace = spec->GetSpace();
    if (particleSpace == PartSysParticleSpace::SameAsEmitter) {

        if (emitterSpace == PartSysEmitterSpace::ObjectPos || emitterSpace == PartSysEmitterSpace::ObjectYpr) {
            if (emitterSpace == PartSysEmitterSpace::ObjectYpr) {
                auto v6 = emitter->GetObjRotation() + 3.1415927f;
                D3DXMatrixRotationY(&pM1, v6);
            } else {
                D3DXMatrixIdentity(&pM1);
            }

            // SEt the translation component of the transformation matrix
            pM1._41 = emitter->GetObjPos().x;
            pM1._42 = emitter->GetObjPos().y;
            pM1._43 = emitter->GetObjPos().z;

            D3DXMatrixMultiply((D3DXMATRIX*)&worldMatrix, &pM1, (const D3DXMATRIX*)&renderStates->Get3dProjectionMatrix());
            ExtractScreenSpaceUnitVectors(worldMatrix);
            return true;
        }
        if (emitterSpace == PartSysEmitterSpace::NodePos || emitterSpace == PartSysEmitterSpace::NodeYpr) {
            auto external = IPartSysExternal::GetCurrent();

            if (emitterSpace == PartSysEmitterSpace::NodeYpr) {
                D3DXMATRIX boneMatrix;
                if (!external->GetBoneWorldMatrix(emitter->GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&)boneMatrix)) {
                    // This effectively acts as a fallback if the bone doesn't exist
                    auto x = emitter->GetObjPos().x;
                    auto y = emitter->GetObjPos().y;
                    auto z = emitter->GetObjPos().z;
                    D3DXMatrixTranslation(&boneMatrix, x, y, z);
                }

                D3DXMatrixMultiply((D3DXMATRIX*) &worldMatrix, &pM1, (const D3DXMATRIX*)&renderStates->Get3dProjectionMatrix());
                ExtractScreenSpaceUnitVectors(worldMatrix);
                return true;
            }

            D3DXMATRIX boneMatrix;
            if (external->GetBoneWorldMatrix(emitter->GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&)boneMatrix)) {
                auto x = boneMatrix._41;
                auto y = boneMatrix._42;
                auto z = boneMatrix._43;
                D3DXMatrixTranslation(&pM1, x, y, z); // TODO: This might not be needed...

                D3DXMatrixMultiply((D3DXMATRIX*)&worldMatrix,
                                   &pM1,
                                   (const D3DXMATRIX*)&renderStates->Get3dProjectionMatrix());

                ExtractScreenSpaceUnitVectors(worldMatrix);
                return true;
            }

            return false;
        }

        worldMatrix = renderStates->Get3dProjectionMatrix();
        ExtractScreenSpaceUnitVectors(worldMatrix);
        return true;
    }

    if (particleSpace == PartSysParticleSpace::World) {
        worldMatrix = renderStates->Get3dProjectionMatrix();
        ExtractScreenSpaceUnitVectors(worldMatrix);
        return true;
    }

    if (emitterSpace != PartSysEmitterSpace::ObjectPos && emitterSpace != PartSysEmitterSpace::ObjectYpr) {
        if (emitterSpace != PartSysEmitterSpace::NodePos && emitterSpace != PartSysEmitterSpace::NodeYpr)
            return true;

        auto external = IPartSysExternal::GetCurrent();
        D3DXMatrixIdentity(&pM1);

        if (emitterSpace == PartSysEmitterSpace::NodeYpr) {
            // Use the entire bone matrix if possible
            external->GetBoneWorldMatrix(emitter->GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&)pM1);
        } else {
            // Only use the bone translation part
            D3DXMATRIX boneMatrix;
            if (!external->GetBoneWorldMatrix(emitter->GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&) boneMatrix))
                return false;
            pM1._41 = boneMatrix._41;
            pM1._42 = boneMatrix._42;
            pM1._43 = boneMatrix._43;
        }
        worldMatrix = renderStates->Get3dProjectionMatrix();
        ExtractScreenSpaceUnitVectors2(pM1);
        return 1;
    }
    if (emitterSpace == PartSysEmitterSpace::ObjectYpr) {
        auto v6 = emitter->GetObjRotation() + 3.1415927f;
        D3DXMatrixRotationY(&pM1, v6);
    } else {
        D3DXMatrixIdentity(&pM1);
    }
    worldMatrix = renderStates->Get3dProjectionMatrix();
    ExtractScreenSpaceUnitVectors2(pM1);
    return true;
}
예제 #2
0
	bool ParticleRenderer::GetEmitterWorldMatrix(const PartSysEmitter& emitter, XMFLOAT4X4& worldMatrix) {

		auto spec = emitter.GetSpec();
		auto particleSpace = spec->GetParticleSpace();
		auto emitterSpace = spec->GetSpace();
		if (particleSpace == PartSysParticleSpace::SameAsEmitter) {

			if (emitterSpace == PartSysEmitterSpace::ObjectPos || emitterSpace == PartSysEmitterSpace::ObjectYpr) {
				XMMATRIX localMat;
				if (emitterSpace == PartSysEmitterSpace::ObjectYpr) {
					auto angle = emitter.GetObjRotation() + XM_PI;
					localMat = XMMatrixRotationY(angle);
				} else {
					localMat = XMMatrixIdentity();
				}

				// Set the translation component of the transformation matrix
				localMat.r[3] = XMVectorSet(emitter.GetObjPos().x,
					emitter.GetObjPos().y,
					emitter.GetObjPos().z,
					1
				);

				XMStoreFloat4x4(
					&worldMatrix,
					localMat * XMLoadFloat4x4(&mDevice.GetCamera().GetViewProj())
				);
				ExtractScreenSpaceUnitVectors(worldMatrix);
				return true;
			}
			if (emitterSpace == PartSysEmitterSpace::NodePos || emitterSpace == PartSysEmitterSpace::NodeYpr) {
				auto external = IPartSysExternal::GetCurrent();

				if (emitterSpace == PartSysEmitterSpace::NodeYpr) {
					XMFLOAT4X4 boneMatrix;
					if (!external->GetBoneWorldMatrix(emitter.GetAttachedTo(), spec->GetNodeName(), boneMatrix)) {
						// This effectively acts as a fallback if the bone doesn't exist
						auto x = emitter.GetObjPos().x;
						auto y = emitter.GetObjPos().y;
						auto z = emitter.GetObjPos().z;
						XMStoreFloat4x4(
							&boneMatrix, 
							XMMatrixTranslation(x, y, z)
						);
					}

					XMStoreFloat4x4(
						&worldMatrix,
						XMLoadFloat4x4(&boneMatrix) * XMLoadFloat4x4(&mDevice.GetCamera().GetViewProj())
						);
					ExtractScreenSpaceUnitVectors(worldMatrix);
					return true;
				}

				XMFLOAT4X4 boneMatrix;
				if (external->GetBoneWorldMatrix(emitter.GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&)boneMatrix)) {
					auto x = boneMatrix._41;
					auto y = boneMatrix._42;
					auto z = boneMatrix._43;

					XMStoreFloat4x4(
						&worldMatrix,
						XMMatrixTranslation(x, y, z) * XMLoadFloat4x4(&mDevice.GetCamera().GetViewProj())
						);

					ExtractScreenSpaceUnitVectors(worldMatrix);
					return true;
				}

				return false;
			}

			worldMatrix = mDevice.GetCamera().GetViewProj();
			ExtractScreenSpaceUnitVectors(worldMatrix);
			return true;
		}

		if (particleSpace == PartSysParticleSpace::World) {
			worldMatrix = mDevice.GetCamera().GetViewProj();
			ExtractScreenSpaceUnitVectors(worldMatrix);
			return true;
		}

		if (emitterSpace != PartSysEmitterSpace::ObjectPos && emitterSpace != PartSysEmitterSpace::ObjectYpr) {
			if (emitterSpace != PartSysEmitterSpace::NodePos && emitterSpace != PartSysEmitterSpace::NodeYpr)
				return true;

			auto external = IPartSysExternal::GetCurrent();

			XMFLOAT4X4 boneMatrix;
			if (emitterSpace == PartSysEmitterSpace::NodeYpr) {
				// Use the entire bone matrix if possible
				external->GetBoneWorldMatrix(emitter.GetAttachedTo(), spec->GetNodeName(), boneMatrix);
			} else {
				// Only use the bone translation part
				if (!external->GetBoneWorldMatrix(emitter.GetAttachedTo(), spec->GetNodeName(), (Matrix4x4&) boneMatrix))
					return false;
				XMStoreFloat4x4(
					&boneMatrix,
					XMMatrixTranslation(boneMatrix._41, 
						boneMatrix._42,
						boneMatrix._43)
					); // TODO: This might not be needed...
			}
			worldMatrix = mDevice.GetCamera().GetViewProj();
			ExtractScreenSpaceUnitVectors2(boneMatrix);
			return true;
		}

		XMFLOAT4X4 matrix;
		if (emitterSpace == PartSysEmitterSpace::ObjectYpr) {
			auto angle = emitter.GetObjRotation() + XM_PI;
			XMStoreFloat4x4(&matrix, XMMatrixRotationY(angle));
		} else {
			XMStoreFloat4x4(&matrix, XMMatrixIdentity());
		}
		worldMatrix = mDevice.GetCamera().GetViewProj();
		ExtractScreenSpaceUnitVectors2(matrix);
		return true;
	}