Vector-Class

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Hellhound66
Beiträge: 476
Registriert: 23.03.2005 23:19

Beitrag von Hellhound66 »

Wahrscheinlich.

Wie gesagt, wenn ich mal viel Zeit habe, werde ich meine Objekte umbauen auf Interfaces, auch wenn ich jetzt schon graue Haare bekomme, nur beim drandenken ^^
Optimismus ist ein Mangel an Information.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Wenn jemand an einer ASM-Version Interesse hat (auch ein paar neue
Funktionen):

Code: Alles auswählen

Structure cOVECTORVT
	; Functions
	fSetXYZ.l
	fSetV.l
	fGetX.l
	fGetY.l
	fGetZ.l
	fGetLength.l
	fGetLengthSqr.l
	fSetX.l
	fSetY.l
	fSetZ.l
	fAddV.l
	fAddXYZ.l
	fSubV.l
	fSubXYZ.l
	fGetDotPV.l
	fCrossPV.l
	fCpy2OV.l
	FMUL.l
	FDIV.l
	fNormalize.l
	fGetDataPtr.l
	fGetDataFromMem.l
	fRotateAroundX.l
	fRotateAroundY.l
	fRotateAroundZ.l
	fRotateAroundV.l
EndStructure

Structure cOVECTOR
	VTable.l
	
	; Data
	x.f
	y.f
	z.f
EndStructure

Interface iOVECTOR
	SetXYZ(x.f, y.f, z.f)
	SetV(*v.cOVECTOR)
	GetX.f()
	GetY.f()
	GetZ.f()
	GetLength.f()
	GetLengthSqr.f()
	SetX(x.f)
	SetY(y.f)
	SetZ(z.f)
	AddV(*v.cOVECTOR)
	AddXYZ(x.f, y.f, z.f)
	SubV(*v.cOVECTOR)
	SubXYZ(x.f, y.f, z.f)
	GetDotPV.f(*v.cOVECTOR)
	CrossPV(*v.cOVECTOR)
	Cpy2OV.l()
	Mul(Factor.f)
	Div(Divisor.f)
	Normalize()
	GetDataPtr.l()
	GetDataFromMem(*mem)
	RotateAroundX(a.f)
	RotateAroundY(a.f)
	RotateAroundZ(a.f)
	RotateAroundV(*v.cOVECTOR, a.f)
EndInterface



Procedure vect_SetXYZ(*this.cOVECTOR, x.f, y.f, z.f)
	!MOV eax, dword[esp]
	!MOV ebx, dword[esp+4]
	!MOV ecx, dword[esp+8]
	!MOV edx, dword[esp+12]
	!MOV dword[eax+4], ebx
	!MOV dword[eax+8], ecx
	!MOV dword[eax+12], edx
	
	ProcedureReturn 
EndProcedure

Procedure vect_SetV(*this.cOVECTOR, *v.cOVECTOR)
	If *v
		!MOV eax, dword[esp+4]
		!MOV ecx, dword[eax+4]
		!MOV edx, dword[eax+8]
		!MOV edi, dword[eax+12]
		
		!MOV eax, dword[esp]
		!MOV dword[eax+4], ecx
		!MOV dword[eax+8], edx
		!MOV dword[eax+12], edi
	EndIf
	
	ProcedureReturn 
EndProcedure

Procedure.f vect_GetX(*this.cOVECTOR)
	ProcedureReturn *this\x
EndProcedure

Procedure.f vect_GetY(*this.cOVECTOR)
	ProcedureReturn *this\y
EndProcedure

Procedure.f vect_GetZ(*this.cOVECTOR)
	ProcedureReturn *this\z
EndProcedure

Procedure.f vect_GetLength(*this.cOVECTOR)
	!MOV eax, dword[esp]
	!FLD dword[eax+4]
	!FMUL dword[eax+4]
	!FLD dword[eax+8]
	!FMUL dword[eax+8]
	!FLD dword[eax+12]
	!FMUL dword[eax+12]
	!FADDP st1, st0
	!FADDP st1, st0
	!FSQRT
	ProcedureReturn 
EndProcedure

Procedure.f vect_GetLengthSqr(*this.cOVECTOR)
	!MOV eax, dword[esp]
	!FLD dword[eax+4]
	!FMUL dword[eax+4]
	!FLD dword[eax+8]
	!FMUL dword[eax+8]
	!FLD dword[eax+12]
	!FMUL dword[eax+12]
	!FADDP st1, st0
	!FADDP st1, st0
	ProcedureReturn
EndProcedure

Procedure vect_SetX(*this.cOVECTOR, x.f)
	*this\x = x
	ProcedureReturn *this + OffsetOf(cOVECTOR\x)
EndProcedure

Procedure vect_SetY(*this.cOVECTOR, y.f)
	*this\y = y
	ProcedureReturn *this + OffsetOf(cOVECTOR\x)
EndProcedure

Procedure vect_SetZ(*this.cOVECTOR, z.f)
	*this\z = z
	ProcedureReturn *this + OffsetOf(cOVECTOR\x)
EndProcedure

Procedure vect_AddV(*this.cOVECTOR, *v.cOVECTOR)
	If *v
		!MOV eax, dword[esp]
		!MOV ebx, dword[esp+4]
		
		!FLD dword[eax+4]
		!FADD dword[ebx+4]
		!FSTP dword[eax+4]
		!FLD dword[eax+8]
		!FADD dword[ebx+8]
		!FSTP dword[eax+8]
		!FLD dword[eax+12]
		!FADD dword[ebx+12]
		!FSTP dword[eax+12]
	EndIf
	
	ProcedureReturn 
EndProcedure

Procedure vect_AddXYZ(*this.cOVECTOR, x.f, y.f, z.f)
	!MOV eax, dword[esp]
	
	!FLD dword[eax+4]
	!FADD dword[esp+4]
	!FSTP dword[eax+4]
	!FLD dword[eax+8]
	!FADD dword[esp+8]
	!FSTP dword[eax+8]
	!FLD dword[eax+12]
	!FADD dword[esp+12]
	!FSTP dword[eax+12]
	
	ProcedureReturn 
EndProcedure

Procedure vect_SubV(*this.cOVECTOR, *v.cOVECTOR)
	If *v
		!MOV eax, dword[esp]
		!MOV ebx, dword[esp+4]
		
		!FLD dword[eax+4]
		!FSUB dword[ebx+4]
		!FSTP dword[eax+4]
		!FLD dword[eax+8]
		!FSUB dword[ebx+8]
		!FSTP dword[eax+8]
		!FLD dword[eax+12]
		!FSUB dword[ebx+12]
		!FSTP dword[eax+12]
	EndIf
	
	ProcedureReturn 
EndProcedure

Procedure vect_SubXYZ(*this.cOVECTOR, x.f, y.f, z.f)
	!MOV eax, dword[esp]
	
	!FLD dword[eax+4]
	!FSUB dword[esp+4]
	!FSTP dword[eax+4]
	!FLD dword[eax+8]
	!FSUB dword[esp+8]
	!FSTP dword[eax+8]
	!FLD dword[eax+12]
	!FSUB dword[esp+12]
	!FSTP dword[eax+12]
	
	ProcedureReturn 
EndProcedure

Procedure.f vect_GetDotPV(*this.cOVECTOR, *v.cOVECTOR)
	If *v
		!MOV eax, dword[esp]
		!MOV ebx, dword[esp+4]
		
		!FLD dword[eax+4]
		!FMUL dword[ebx+4]
		!FLD dword[eax+8]
		!FMUL dword[ebx+8]
		!FLD dword[eax+12]
		!FMUL dword[ebx+12]
		!FADDP st1, st0
		!FADDP st1, st0
		
		ProcedureReturn
	EndIf
	
	ProcedureReturn 0
EndProcedure

Procedure vect_CrossPV(*this.cOVECTOR, *v.cOVECTOR)
	If *v
		!MOV eax, dword[esp]
		!MOV ebx, dword[esp+4]
		
		!FLD dword[eax+8]
		!FMUL dword[ebx+12]
		!FLD dword[eax+12]
		!FMUL dword[ebx+8]
		!FSUBP st1, st0 ; x auf Stack
		
		!FLD dword[eax+12]
		!FMUL dword[ebx+4]
		!FLD dword[eax+4]
		!FMUL dword[ebx+12]
		!FSUBP st1, st0 ; y auf Stack
		
		!FLD dword[eax+4]
		!FMUL dword[ebx+8]
		!FLD dword[eax+8]
		!FMUL dword[ebx+4]
		!FSUBP st1, st0 ; z auf Stack
		
		; zurückspeichern
		!FSTP dword[eax+12]
		!FSTP dword[eax+8]
		!FSTP dword[eax+4]
		
		ProcedureReturn 
	EndIf
	
	ProcedureReturn 
EndProcedure

Declare new_ovector()
Procedure vect_Cpy2OV(*this.cOVECTOR)
	Protected *v.iOVECTOR
	
	*v.iOVECTOR = new_ovector()
	*v\SetV(*this)
	
	ProcedureReturn *v
EndProcedure

Procedure vect_Mul(*this.cOVECTOR, Factor.f)
	!MOV eax, dword[esp]
	
	!FLD dword[eax+4]
	!FMUL dword[esp+4]
	!FSTP dword[eax+4]
	!FLD dword[eax+8]
	!FMUL dword[esp+4]
	!FSTP dword[eax+8]
	!FLD dword[eax+12]
	!FMUL dword[esp+4]
	!FSTP dword[eax+12]
	
	ProcedureReturn 
EndProcedure

Procedure vect_Div(*this.cOVECTOR, Divisor.f)
	!FLD1
	!FDIV dword[esp+4]
	!FSTP dword[esp-4]
	
	!MOV eax, dword[esp]
	
	!FLD dword[eax+4]
	!FMUL dword[esp-4]
	!FSTP dword[eax+4]
	!FLD dword[eax+8]
	!FMUL dword[esp-4]
	!FSTP dword[eax+8]
	!FLD dword[eax+12]
	!FMUL dword[esp-4]
	!FSTP dword[eax+12]
	
	ProcedureReturn *this + OffsetOf(cOVECTOR\x)
EndProcedure

Procedure vect_Normalize(*this.cOVECTOR)
	Protected Len.f
	
	Len = 1.0 / vect_GetLength(*this)
	!MOV eax, dword[esp]
	!FLD dword[eax+4]
	!FMUL dword[esp-4]
	!FSTP dword[eax+4]
	!FLD dword[eax+8]
	!FMUL dword[esp-4]
	!FSTP dword[eax+8]
	!FLD dword[eax+12]
	!FMUL dword[esp-4]
	!FSTP dword[eax+12]
	
	ProcedureReturn 
EndProcedure

Procedure.l vect_GetDataPtr(*this.cOVECTOR)
	ProcedureReturn *this + OffsetOf(cOVECTOR\x)
EndProcedure

Procedure vect_GetDataFromMem(*this.cOVECTOR, *mem)
	CopyMemory(*mem, *this + OffsetOf(cOVECTOR\x), 3 * 4)
	
	ProcedureReturn 
EndProcedure

Procedure vect_RotateAroundX(*this.cOVECTOR, a.f)
	!FLD dword[esp+4]
	!FCOS
	!FLD dword[esp+4]
	!FSIN
	; st1: cos(a)
	; st0: sin(a)
	
	!MOV eax, dword[esp]
	
	!FLD st1 ;cosa
	!FMUL dword[eax+8]
	!FLD st1 ;sina
	!FMUL dword[eax+12]
	!FSUBP st1, st0
	; st2: cos(a)
	; st1: sin(a)
	; st0: y
	
	!FLD st1 ;sina
	!FMUL dword[eax+8]
	!FLD st3 ;cosa
	!FMUL dword[eax+12]
	!FADDP st1, st0
	
	!FSTP dword[eax+12]
	!FSTP dword[eax+8]
	
	!FSTP st0 ;sina
	!FSTP st0 ;cosa
	
	ProcedureReturn 
EndProcedure

Procedure vect_RotateAroundY(*this.cOVECTOR, a.f)
	!FLD dword[esp+4]
	!FCOS
	!FLD dword[esp+4]
	!FSIN
	; st1: cos(a)
	; st0: sin(a)
	
	!MOV eax, dword[esp]
	
	!FLD st1 ;cosa
	!FMUL dword[eax+4]
	!FLD st1 ;sina
	!FMUL dword[eax+12]
	!FADDP st1, st0
	; st2: cos(a)
	; st1: sin(a)
	; st0: x
	
	!FLD st2 ;cosa
	!FMUL dword[eax+12]
	!FLD st2 ;sina
	!FMUL dword[eax+4]
	!FSUBP st1, st0
	
	!FSTP dword[eax+12]
	!FSTP dword[eax+4]
	
	!FSTP st0 ;sina
	!FSTP st0 ;cosa
	
	ProcedureReturn 
EndProcedure

Procedure vect_RotateAroundZ(*this.cOVECTOR, a.f)
	!FLD dword[esp+4]
	!FCOS
	!FLD dword[esp+4]
	!FSIN
	; st1: cos(a)
	; st0: sin(a)
	
	!MOV eax, dword[esp]
	
	!FLD st1 ;cosa
	!FMUL dword[eax+4]
	!FLD st1 ;sina
	!FMUL dword[eax+8]
	!FSUBP st1, st0
	; st2: cos(a)
	; st1: sin(a)
	; st0: y
	
	!FLD st1 ;sina
	!FMUL dword[eax+4]
	!FLD st3 ;cosa
	!FMUL dword[eax+8]
	!FADDP st1, st0
	
	!FSTP dword[eax+8]
	!FSTP dword[eax+4]
	
	!FSTP st0 ;sina
	!FSTP st0 ;cosa
	
	ProcedureReturn 
EndProcedure

Procedure vect_RotateAroundV(*this.cOVECTOR, *v.cOVECTOR, a.f) ; *v has to be normalized
	
	!FLD dword[esp+8]
	!FCOS
	!FLD dword[esp+8]
	!FSIN
	!FLD1
	!FSUB st0, st2
	
	!MOV eax, dword[esp]
	!MOV ebx, dword[esp+4]
	
	; st2: cosa
	; st1: sina
	; st0: ecosa
	
	; eax = *this
	; ebx = *V
	
; 	*this\x = x * (cosa + *v\x * *v\x * ecosa) + y * (*v\x * *v\y * ecosa - *v\z * sina) + z * (*v\x * *v\z * ecosa + *v\y * sina)
	!FLD dword[ebx+4]
	!FMUL dword[ebx+4]
	!FMUL st0, st1 ;ecosa
	!FADD st0, st3 ;cosa
	!FMUL dword[eax+4]
	
	!FLD dword[ebx+4]
	!FMUL dword[ebx+8]
	!FMUL st0, st2 ;ecosa
	!FLD dword[ebx+12]
	!FMUL st0, st4 ;sina
	!FSUBP st1, st0
	!FMUL dword[eax+8]
	
	!FLD dword[ebx+4]
	!FMUL dword[ebx+12]
	!FMUL st0, st3 ;ecosa
	!FLD dword[ebx+8]
	!FMUL st0, st5 ;sina
	!FADDP st1, st0
	!FMUL dword[eax+12]
	!FADDP st1, st0
	!FADDP st1, st0
	!FSTP dword[esp-4]
	; this\x in esp-4
	
	; st2: cosa
	; st1: sina
	; st0: ecosa
	; eax = *this
	; ebx = *V
; 	*this\y = x * (*v\y * *v\x * ecosa + *v\z * sina) + y * (cosa + *v\y * *v\y * ecosa) + z * (*v\y * *v\z * ecosa - *v\x * sina)
	!FLD dword[ebx+4]
	!FMUL dword[ebx+8]
	!FMUL st0, st1 ;ecosa
	!FLD st2 ;sina
	!FMUL dword[ebx+12]
	!FADDP st1, st0
	!FMUL dword[eax+4]
	
	!FLD dword[ebx+8]
	!FMUL dword[ebx+8]
	!FMUL st0, st2 ;ecosa
	!FADD st0, st4 ;cosa
	!FMUL dword[eax+8]
	
	!FLD dword[ebx+8]
	!FMUL dword[ebx+12]
	!FMUL st0, st3 ;ecosa
	!FLD dword[ebx+4]
	!FMUL st0, st5 ;sina
	!FSUBP st1, st0
	!FMUL dword[eax+12]
	!FADDP st1, st0
	!FADDP st1, st0
	!FSTP dword[esp-8]
	; this\y in esp-8
	
; 	*this\z = x * (*v\z * *v\x * ecosa - *v\y * sina) + y * (*v\z * *v\y * ecosa + *v\x * sina) + z * (cosa + *v\z * *v\z * ecosa)
	!FLD dword[ebx+12]
	!FMUL dword[ebx+4]
	!FMUL st0, st1 ;ecosa
	!FLD st2 ;sina
	!FMUL dword[ebx+8]
	!FSUBP st1, st0
	!FMUL dword[eax+4]
	
	!FLD dword[ebx+12]
	!FMUL dword[ebx+8]
	!FMUL st0, st2 ;ecosa
	!FLD dword[ebx+4]
	!FMUL st0, st4 ;sina
	!FADDP st1, st0
	!FMUL dword[eax+8]
	
	!FLD dword[ebx+12]
	!FMUL dword[ebx+12]
	!FMUL st0, st3 ;ecosa
	!FADD st0, st5 ;cosa
	!FADDP st1, st0
	!FADDP st1, st0
	!FSTP dword[esp-12]
	; this\z in esp-12
	
	!FSTP st0
	!FSTP st0
	!FSTP st0
	
	!MOV ebx, [esp-4]
	!MOV [eax+4], ebx
	!MOV ebx, [esp-8]
	!MOV [eax+8], ebx
	!MOV ebx, [esp-12]
	!MOV [eax+12], ebx
	
	
	ProcedureReturn 
EndProcedure




Procedure.l new_ovector()
	Protected *v.cOVECTOR
	Static *VTable.cOVECTORVT
	
	If *VTable = 0
		*VTable = AllocateMemory(SizeOf(cOVECTORVT))
		*VTable\fSetXYZ				= @vect_SetXYZ()
		*VTable\fSetV					= @vect_SetV()
		*VTable\fGetX					= @vect_GetX()
		*VTable\fGetY					= @vect_GetY()
		*VTable\fGetZ					= @vect_GetZ()
		*VTable\fGetLength		= @vect_GetLength()
		*VTable\fGetLengthSqr	= @vect_GetLengthSqr()
		*VTable\fSetX					= @vect_SetX()
		*VTable\fSetY					= @vect_SetY()
		*VTable\fSetZ					= @vect_SetZ()
		*VTable\fAddV					= @vect_AddV()
		*VTable\fAddXYZ				= @vect_AddXYZ()
		*VTable\fSubV					= @vect_SubV()
		*VTable\fSubXYZ				= @vect_SubXYZ()
		*VTable\fGetDotPV			= @vect_GetDotPV()
		*VTable\fCrossPV			= @vect_CrossPV()
		*VTable\fCpy2OV				= @vect_Cpy2OV()
		*VTable\FMUL					= @vect_Mul()
		*VTable\FDIV					= @vect_Div()
		*VTable\fNormalize		= @vect_Normalize()
		*VTable\fGetDataPtr		= @vect_GetDataPtr()
		*VTable\fGetDataFromMem = @vect_GetDataFromMem()
		*VTable\fRotateAroundX	= @vect_RotateAroundX()
		*VTable\fRotateAroundY	= @vect_RotateAroundY()
		*VTable\fRotateAroundZ	= @vect_RotateAroundZ()
		*VTable\fRotateAroundV	= @vect_RotateAroundV()
	EndIf
	
	*v = AllocateMemory(SizeOf(cOVECTOR))
	*v\VTABLE = *VTable
		
	ProcedureReturn *v
EndProcedure



; DefType.iOVECTOR a, b
; 
; 
; a = new_ovector()
; b = new_ovector()
; 
; a\SetXYZ(1, 2, 0)
; b\SetXYZ(2, 3, 0)
; a\SubV(b)
; 
; Debug a\GetX()
; Debug a\GetY()
; Debug a\GetZ()
; 
; a\Normalize()
; Debug a\GetX()
; Debug a\GetY()
; Debug a\GetZ()
; 
; Debug a\GetLength()
; Debug a\GetLengthSqr()
; 
; NewList vec.iOVECTOR()
; AddElement(vec())
; vec() = new_ovector()
; vec()\SetXYZ(1, 2, 0)
; 
; AddElement(vec())
; vec() = new_ovector()
; vec()\SetXYZ(3, 21, 0)
; 
; Debug vec()\GetX()




DefType.iOVECTOR a, b

a = new_ovector()
b = new_ovector()

a\SetXYZ(0, 10, 0)
b\SetXYZ(1, 0, 0) ; X-Achse ^^
b\Normalize() ; wäre nicht nötig hier

Debug a\GetX()
Debug a\GetY()
Debug a\GetZ()

Debug "RotateX"
a\RotateAroundX(3.1415926 / 2.0)
Debug a\GetX()
Debug a\GetY()
Debug a\GetZ()

Debug "RotateY"
a\RotateAroundY(3.1415926 / 2.0)
Debug a\GetX()
Debug a\GetY()
Debug a\GetZ()

Debug "RotateZ"
a\RotateAroundZ(3.1415926 / 2.0)
Debug a\GetX()
Debug a\GetY()
Debug a\GetZ()

Debug "RotateV = RotateX"
a\RotateAroundV(b, 3.1415926 / 2.0)
Debug a\GetX()
Debug a\GetY()
Debug a\GetZ()
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Aha, die Rotate-Funktionen sind besonders interessant für angehende RayTracing-Coder. <)
Naja, ich hab meine Funktionen ja schon irgendwie selbst zusammengekriegt.
Antworten