⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obb.hpp

📁 机甲指挥官2源代码
💻 HPP
字号:
//===========================================================================//
// Copyright (C) Microsoft Corporation. All rights reserved.                 //
//===========================================================================//

#pragma once

#include "Stuff.hpp"
#include "LinearMatrix.hpp"
#include "Sphere.hpp"

namespace Stuff {class OBB;}

#if !defined(Spew)
	void
		Spew(
			const char* group,
			const Stuff::OBB &box
		);
#endif

namespace Stuff {

	class Line3D;

	class OBB
	{
	public:
		void
			TestInstance() const;

		static OBB
			Identity;

		LinearMatrix4D
			localToParent;
		Vector3D
			axisExtents;
		Scalar
			sphereRadius;

		#if !defined(Spew)
			friend void
				::Spew(
					const char* group,
					const OBB &box
				);
		#endif

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Construction
	//
	public:
		OBB()
			{}
		OBB(const OBB& obb):
			localToParent(obb.localToParent),
			axisExtents(obb.axisExtents),
			sphereRadius(obb.sphereRadius)
				{}
		OBB(
			const LinearMatrix4D &origin,
			const Vector3D &extents
		):
			localToParent(origin),
			axisExtents(extents),
			sphereRadius(extents.GetLength())
				{}
		OBB(
			const LinearMatrix4D &origin,
			const Vector3D &extents,
			Scalar radius
		):
			localToParent(origin),
			axisExtents(extents),
			sphereRadius(radius)
				{}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Assignment
	//
	public:
		OBB&
			operator =(const OBB& obb)
				{
					Check_Pointer(this); Check_Object(&obb);
					localToParent = obb.localToParent;
					axisExtents = obb.axisExtents;
					sphereRadius = obb.sphereRadius;
					return *this;
				}

		OBB&
			BuildSphere(const Sphere& sphere)
				{
					Check_Pointer(this); Check_Object(&sphere);
					sphereRadius = sphere.radius;
					localToParent.BuildTranslation(sphere.center);
					return *this;
				}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Transforms
	//
	public:
		OBB&
			Multiply(
				const OBB& obb,
				const LinearMatrix4D &matrix
			);
		inline OBB&
			MultiplySphereOnly(
				const OBB& obb,
				const LinearMatrix4D &matrix
			)
			{
				Check_Pointer(this);
				Check_Object(&obb);
				Check_Object(&matrix);

#if USE_ASSEMBLER_CODE

				Scalar *f = localToParent.entries;

				_asm {
					mov         edx, matrix
					push        esi
					mov         esi, obb.localToParent
					
					mov         eax, f

					fld         dword ptr [edx+4]		//	m[1][0]
					fmul        dword ptr [esi+01ch]	//	obb.localToParent(3,1)
					
					fld         dword ptr [edx+8]		//	m[2][0]
					fmul        dword ptr [esi+02Ch]	//	obb.localToParent(3,2)

					fxch		st(1)
					fadd        dword ptr [edx+0Ch]		//	m[3][0]
					
					fld         dword ptr [edx]			//	m[0][0]
					fmul        dword ptr [esi+0Ch]		//	obb.localToParent(3,0)

					fxch		st(2)
					faddp       st(1),st

					fld         dword ptr [edx+14h]		//	m[1][1]
					fmul        dword ptr [esi+01ch]	//	obb.localToParent(3,1)

					fxch		st(2)
					faddp       st(1),st

					fld         dword ptr [edx+18h]		//	m[2][1]
					fmul        dword ptr [esi+02ch]	//	obb.localToParent(3,2)
					
					fxch		st(1)
					fstp        dword ptr [eax+0ch]		//	localToParent(3,0)

					fadd        dword ptr [edx+1Ch]		//	m[3][1]

					fld         dword ptr [edx+10h]		//	m[0][1]
					fmul        dword ptr [esi+0ch]		//	obb.localToParent(3,0)

					fxch		st(2)
					faddp       st(1),st

					fld         dword ptr [edx+24h]		//	m[1][2]
					fmul        dword ptr [esi+01ch]	//	obb.localToParent(3,1)

					fxch		st(2)
					faddp       st(1),st

					fld         dword ptr [edx+28h]		//	m[2][2]
					fmul        dword ptr [esi+02ch]	//	obb.localToParent(3,2)
					
					fxch		st(1)
					fstp        dword ptr [eax+01ch]	//	localToParent(3,1)

					fadd        dword ptr [edx+2Ch]		//	m[3][2]
					
					fld         dword ptr [edx+20h]		//	m[0][2]
					fmul        dword ptr [esi+0ch]		//	obb.localToParent(3,0)

					fxch		st(2)
					faddp       st(1),st

					pop         esi

					faddp       st(1),st

					fstp        dword ptr [eax+02ch]	//	localToParent(3,2)
				}
#else
				localToParent(3,0) =
					obb.localToParent(3,0)*matrix(0,0)
					 + obb.localToParent(3,1)*matrix(1,0)
					 + obb.localToParent(3,2)*matrix(2,0)
					 + matrix(3,0);
				localToParent(3,1) =
					obb.localToParent(3,0)*matrix(0,1)
					 + obb.localToParent(3,1)*matrix(1,1)
					 + obb.localToParent(3,2)*matrix(2,1)
					 + matrix(3,1);
				localToParent(3,2) =
					obb.localToParent(3,0)*matrix(0,2)
					 + obb.localToParent(3,1)*matrix(1,2)
					 + obb.localToParent(3,2)*matrix(2,2)
					 + matrix(3,2);
#endif

				sphereRadius = obb.sphereRadius;
				return *this;
			}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Intersection functions
	//
	public:
		enum SeparatingAxis {
			NoSeparation = 0,
			A0,
			A1,
			A2,
			B0,
			B1,
			B2,
			A0xB0,
			A0xB1,
			A0xB2,
			A1xB0,
			A1xB1,
			A1xB2,
			A2xB0,
			A2xB1,
			A2xB2
		};

		SeparatingAxis
			FindSeparatingAxis(const OBB& box) const;
		//
		// Intersection functions
		//
		bool
			Contains(const Point3D &point) const;
		bool
			Intersects(const Plane &plane) const;

		void
			Union(
				const OBB &first,
				const OBB &second
			);
	};

	inline Sphere&
		Sphere::operator =(const OBB &obb)
	{
		Check_Pointer(this); Check_Object(&obb);
		center = obb.localToParent;
		radius = obb.sphereRadius;
		return *this;
	}

}

namespace MemoryStreamIO {

	inline Stuff::MemoryStream&
		Read(
			Stuff::MemoryStream* stream,
			Stuff::OBB *output
		)
			{return stream->ReadBytes(output, sizeof(*output));}
	inline Stuff::MemoryStream&
		Write(
			Stuff::MemoryStream* stream,
			const Stuff::OBB *input
		)
			{return stream->WriteBytes(input, sizeof(*input));}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -