Created
August 26, 2014 07:08
-
-
Save XProger/da9a74ae8b37905b421a to your computer and use it in GitHub Desktop.
Simple float3 vector operations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| TVec3f = {$IFDEF FPC} object {$ELSE} record {$ENDIF} | |
| x, y, z : Single; | |
| {$IFNDEF FPC} | |
| class operator Equal(const a, b: TVec3f): Boolean; | |
| class operator Add(const a, b: TVec3f): TVec3f; | |
| class operator Subtract(const a, b: TVec3f): TVec3f; | |
| class operator Multiply(const a, b: TVec3f): TVec3f; | |
| class operator Multiply(const v: TVec3f; x: Single): TVec3f; | |
| {$ENDIF} | |
| function Dot(const v: TVec3f): Single; | |
| function Cross(const v: TVec3f): TVec3f; | |
| function Reflect(const n: TVec3f): TVec3f; | |
| function Refract(const n: TVec3f; Factor: Single): TVec3f; | |
| function Length: Single; | |
| function LengthQ: Single; | |
| function Normal: TVec3f; | |
| function Dist(const v: TVec3f): Single; | |
| function DistQ(const v: TVec3f): Single; | |
| function Lerp(const v: TVec3f; t: Single): TVec3f; | |
| function MinV(const v: TVec3f): TVec3f; | |
| function MaxV(const v: TVec3f): TVec3f; | |
| function ClampV(const MinClamp, MaxClamp: TVec3f): TVec3f; | |
| function Rotate(Angle: Single; const Axis: TVec3f): TVec3f; | |
| function Angle(const v: TVec3f): Single; | |
| function MultiOp(out r: TVec3f; const v1, v2, op1, op2: TVec3f): Single; | |
| end; | |
| {$IFDEF FPC} | |
| operator = (const a, b: TVec3f): Boolean; | |
| operator + (const a, b: TVec3f): TVec3f; | |
| operator - (const a, b: TVec3f): TVec3f; | |
| operator * (const a, b: TVec3f): TVec3f; | |
| operator * (const v: TVec3f; x: Single): TVec3f; | |
| {$ENDIF} | |
| {$IFDEF FPC}operator = {$ELSE}class operator TVec3f.Equal{$ENDIF} | |
| (const a, b: TVec3f): Boolean; | |
| begin | |
| with b - a do | |
| Result := (abs(x) <= EPS) and (abs(y) <= EPS) and (abs(z) <= EPS); | |
| end; | |
| {$IFDEF FPC}operator + {$ELSE}class operator TVec3f.Add{$ENDIF} | |
| (const a, b: TVec3f): TVec3f; | |
| begin | |
| Result.x := a.x + b.x; | |
| Result.y := a.y + b.y; | |
| Result.z := a.z + b.z; | |
| end; | |
| {$IFDEF FPC}operator - {$ELSE}class operator TVec3f.Subtract{$ENDIF} | |
| (const a, b: TVec3f): TVec3f; | |
| begin | |
| Result.x := a.x - b.x; | |
| Result.y := a.y - b.y; | |
| Result.z := a.z - b.z; | |
| end; | |
| {$IFDEF FPC}operator * {$ELSE}class operator TVec3f.Multiply{$ENDIF} | |
| (const a, b: TVec3f): TVec3f; | |
| begin | |
| Result.x := a.x * b.x; | |
| Result.y := a.y * b.y; | |
| Result.z := a.z * b.z; | |
| end; | |
| {$IFDEF FPC}operator * {$ELSE}class operator TVec3f.Multiply{$ENDIF} | |
| (const v: TVec3f; x: Single): TVec3f; | |
| begin | |
| Result.x := v.x * x; | |
| Result.y := v.y * x; | |
| Result.z := v.z * x; | |
| end; | |
| function TVec3f.Dot(const v: TVec3f): Single; | |
| begin | |
| Result := x * v.x + y * v.y + z * v.z; | |
| end; | |
| function TVec3f.Cross(const v: TVec3f): TVec3f; | |
| begin | |
| Result.x := y * v.z - z * v.y; | |
| Result.y := z * v.x - x * v.z; | |
| Result.z := x * v.y - y * v.x; | |
| end; | |
| function TVec3f.Reflect(const n: TVec3f): TVec3f; | |
| begin | |
| Result := Self - n * (2 * Dot(n)); | |
| end; | |
| function TVec3f.Refract(const n: TVec3f; Factor: Single): TVec3f; | |
| var | |
| d, s : Single; | |
| begin | |
| d := Dot(n); | |
| s := (1 - sqr(Factor)) * (1 - sqr(d)); | |
| if s < 0 then | |
| Result := Reflect(n) | |
| else | |
| Result := Self * Factor - n * (sqrt(s) + d * Factor); | |
| end; | |
| function TVec3f.Length: Single; | |
| begin | |
| Result := sqrt(LengthQ); | |
| end; | |
| function TVec3f.LengthQ: Single; | |
| begin | |
| Result := sqr(x) + sqr(y) + sqr(z); | |
| end; | |
| function TVec3f.Normal: TVec3f; | |
| var | |
| Len : Single; | |
| begin | |
| Len := Length; | |
| if Len = 0 then | |
| Result := Vec3f(0, 0, 0) | |
| else | |
| Result := Self * (1 / Len); | |
| end; | |
| function TVec3f.Dist(const v: TVec3f): Single; | |
| var | |
| p : TVec3f; | |
| begin | |
| p := v - Self; | |
| Result := p.Length; | |
| end; | |
| function TVec3f.DistQ(const v: TVec3f): Single; | |
| var | |
| p : TVec3f; | |
| begin | |
| p := v - Self; | |
| Result := p.LengthQ; | |
| end; | |
| function TVec3f.Lerp(const v: TVec3f; t: Single): TVec3f; | |
| begin | |
| Result := Self + (v - Self) * t; | |
| end; | |
| function TVec3f.MinV(const v: TVec3f): TVec3f; | |
| begin | |
| Result.x := Min(x, v.x); | |
| Result.y := Min(y, v.y); | |
| Result.z := Min(z, v.z); | |
| end; | |
| function TVec3f.MaxV(const v: TVec3f): TVec3f; | |
| begin | |
| Result.x := Max(x, v.x); | |
| Result.y := Max(y, v.y); | |
| Result.z := Max(z, v.z); | |
| end; | |
| function TVec3f.ClampV(const MinClamp, MaxClamp: TVec3f): TVec3f; | |
| begin | |
| Result := Vec3f(Clamp(x, MinClamp.x, MaxClamp.x), | |
| Clamp(y, MinClamp.y, MaxClamp.y), | |
| Clamp(z, MinClamp.z, MaxClamp.z)); | |
| end; | |
| function TVec3f.Rotate(Angle: Single; const Axis: TVec3f): TVec3f; | |
| var | |
| s, c : Single; | |
| v0, v1, v2 : TVec3f; | |
| begin | |
| SinCos(Angle, s, c); | |
| v0 := Axis * Dot(Axis); | |
| v1 := Self - v0; | |
| v2 := Axis.Cross(v1); | |
| Result.x := v0.x + v1.x * c + v2.x * s; | |
| Result.y := v0.y + v1.y * c + v2.y * s; | |
| Result.z := v0.z + v1.z * c + v2.z * s; | |
| end; | |
| function TVec3f.Angle(const v: TVec3f): Single; | |
| begin | |
| Result := ArcCos(Dot(v) / sqrt(LengthQ * v.LengthQ)) | |
| end; | |
| function TVec3f.MultiOp(out r: TVec3f; const v1, v2, op1, op2: TVec3f): Single; | |
| begin | |
| r.x := v1.x * op1.x + v2.x * op2.x; | |
| r.y := v1.y * op1.y + v2.y * op2.y; | |
| r.z := v1.z * op1.z + v2.z * op2.z; | |
| Result := r.x + r.y + r.z; | |
| // add = (v1, v2, 1, 1) | |
| // sub = (v1, v2, 1, -1) | |
| // neg = (v1, 0, -1, 0) | |
| // dot = (v1, 0, v2, 0) | |
| // cross = (v1.yzx, v2.yzx, v2.zxy, -v1.zxy) | |
| // lenq = (v1, 0, v1, 0) | |
| // lerp = (v1, v2, 1 - t, t) | |
| // etc. | |
| end; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment