Giter VIP home page Giter VIP logo

unity.mathematics's Introduction

Unity.Mathematics

A C# math library providing vector types and math functions with a shader like syntax. Used by the Burst compiler to compile C#/IL to highly efficient native code.

The main goal of this library is to provide a friendly Math API familiar to SIMD and graphic/shaders developers, using the well known float4, float3 types...etc. with all intrinsics functions provided by a static class math that can be imported easily into your C# program with using static Unity.Mathematics.math.

In addition to this, the Burst compiler is able to recognize these types and provide the optimized SIMD type for the running CPU on all supported platforms (x64, ARMv7a...etc.)

NOTICE: The API is a work in progress and we may introduce breaking changes (API and underlying behavior)

Usage

You can use this library in your Unity game by using the Package Manager and referencing the package com.unity.mathematics. See the forum Welcome page for more details.

using static Unity.Mathematics.math;
namespace MyNamespace
{
    using Unity.Mathematics;
    
    ...
    var v1 = float3(1,2,3);
    var v2 = float3(4,5,6);
    v1 = normalize(v1);
    v2 = normalize(v2);
    var v3 = dot(v1, v2);
    ...
}

Building

Open the src\Unity.Mathematics.sln under Visual Studio 2015 or MonoDevelop and compile in Debug\Release.

Contributing

We don't yet accept PR on this repository. See the FAQ below.

The project is using editorconfig to keep files correctly formatted for EOL and spaces.

We assume that your IDE has support for editorconfig, you can download the following extensions if your IDE is listed:

Frequently Asked Question

Why developing another Math library instead of using existing Unity Vector3...etc.?

After years of feedback and experience with the previous API, we believe that providing an API that is closer to the way graphics developers have been using math libraries should better help its adoption and the ease of its usage. HLSL / GLSL math library is a very well designed, well understood math library leading to greater consistency.

Why not using System.Numerics.Vectors?

Mainly for the reason mentioned above, System.Numerics.Vectors is in many ways similar to our previous Vector library (more object oriented than graphics programming oriented). Also the fact that our Burst compiler is able to recognize a lot more patterns for SIMD types and math intrinsics makes it easier to work with a dedicated API that reflects this ability.

Naming convention

In C# int and float are considered builtin types. Burst extends this set of bultin types to also include vectors, matrices and quaternions. These types are bultin in the sense that Burst knows about them and is be able to generate better code using these types than what would be possible with equivalent code using custom types.

To signify that these types are bultin their type names are in all lower case. The operators on these bultin types found in Unity.Mathematics.math are considered intrinsics and are thus always in lower case.

There are no plans to extend the set of intrinsic types beyond the current set of vectors (typeN), matrices (typeNxN) and quaternions (quaternion).

This convention has the added benefit of making the library highly compatible with shader code and makes porting or sharing code between the two almost frictionless.

Why can't we send a PR yet?

We are working on providing a Contributor License Agreement (CLA) with a sign-over functionality and our UCL License doesn't cover this yet.

Licensing

Unity Companion License (“License”) Software Copyright © 2019 Unity Technologies ApS

For licensing details see LICENSE.md

unity.mathematics's People

Contributors

amechtley avatar andreasf-unity avatar aras-p avatar aspepex avatar barbara-wang avatar bmcnett avatar bogdancu avatar deplinenoise avatar etherelric avatar fabriziounity avatar icetigris avatar jmankinunity avatar jo-unity avatar jo3w4rd avatar joeante avatar jokubask avatar keijiro avatar kevinmv avatar kjellander-unity avatar leehammerton avatar lucasmeijer avatar macton avatar neonbevz avatar oldio avatar plu-unity avatar runestubbe avatar sw-unity avatar unpacklo avatar xoofx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unity.mathematics's Issues

devide int3 by float

Not really a biggy, but currently I can't devide an int3 by a float directly, without explicitly casting the int3 to a float3 first. (Is true for int2 and int4 aswell).

So basically, what I would like is this operator.

public static float3 operator / (int3 lhs, float rhs)
{ return new float3 (lhs.x / rhs, lhs.y / rhs, lhs.z / rhs); }

So that when I want to devide my int3 by a float, I don't have to explicitly cast my int3 to a float3 first.

Add ray and bounds types

Missing bool (bool1) type.

The "bool" type disappear at some point while updating the package.

Is this desired? Boolean is quite convenient and since there are bool4 and etc. I don't see why we can't have bool1 :)

Cheers!

Random isn't initialized properly

Consider the following code:

for (uint i = 1; i < 10; i++)
	Debug.Log(new Unity.Mathematics.Random(i).NextFloat());

It outputs the following:

6.29425E-05
0.000125885
0.0001888275
0.00025177
0.0003147125
0.000377655
0.0004405975
0.00050354
0.0005664825

This output does not look random. This is because the Xorshift PRNG Random() uses is supposed to be initialized with different type of PRNG, such as SplitMix. Wikipedia has an example: https://en.wikipedia.org/wiki/Xorshift#Initialization.

Use standard header for generated files

When the mathematics package is included as source in a project and the project is opened in Rider, Rider will run inspections on the generated files. This is probably not very useful, as these files are not intended to be maintained by hand, or modified by the end user.

The analysis can be automatically disabled by using the well known header:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

Rider will recognise this comment and treat the file as generated. This means it's not user code, so Rider doesn't run or show inspections in this file. Alternatively, Rider will also recognise files that match the filename pattern *.generated.cs as being generated.

0.0.12-preview.10 has a compiler warnings which causes projects with warnaserror on to fail

Our project has -warnaserror+ set in mcs.rsp.

Because of the following warning, we can not include the current release of Unity Mathematics as a dependency in our project (the warning gets converted to an error and the compile fails):

/packages/packages.unity.com/[email protected]/Unity.Mathematics/Noise/psrdnoise2D.cs(100,20): error CS0219: Warning as Error: The variable `i2' is assigned but its value is never used

Output of Mathf.Sign() and sign() differ in implementation

since Mathf.Sign returns -1 or 1, and sign() returns -1, 0 or 1 it creates problems for code
where the result sign is then multiplied by something, effectively setting that value to zero.

This probably wont change as it's how it should be in shaders (probably) but still
having a classic (-1, 1) would be very nice.

Example of what current sign leads to

float num2 = sign(normalized.x * normalized2.y - normalized.y * normalized2.x);
float result = num * (num2 >= 0f ? 1f : -1f);

Floating point math library

Currently functions redirect to System.Math, casting the input to a double and output to float. In .Net Core MathF is available to do native floating point math and speed this up.

I imagine System.MathF cannot be used in unity currently, but if this is possible at some point it might be impossible to switch without breaking code relying on exact precision.

I'm not sure what Burst compiles eg System.Math.Cos too anyway - would it internally already use 32 bit cosf routine?

Add support for math.near_equal or similar to Mathf.Approximately

There is currently no helper methods exposed to compare two floating points that are approximately the same

What needs to be determined:

  • name of these methods (e.g near_equal...)
  • what kind of implementation do we want? (taking into account ULP or not? one version with more parameters?...)

More implicit conversion

I would like to see implicit casting for:

  • int2 <=> Vector2Int
  • int3 <=> Vector3Int

(I have no idea why those don't exist)

  • Vector3 <=> float2
    (usefull when using vector functions like Camera.WorldToScreenPoint in 2D)

Second one will make my code a lot easier to read, instead of
(Vector2)camera.WorldToScreenPoint(float3(currentWorldspaceAimCentre, 0));
I will be able to just do
camera.WorldToScreenPoint(currentWorldspaceAimCentre)

Documentation folder name missing tilde

The package manager doc tools expect your documentation folder to have a ~ character at the end: Documentation~. (This is so it ignores the doc files when looking for resources actually used by a program importing the package.)

What about long and ulong vector types?

I wonder if there is any specific reason why no vector types for long and ulong were added.
I'm currently working with bit operations and a ulong4 would allow me to do more operations in parallel.

Comparing float2s in if(...) is awkward and cumbersome

Frequently, I will attempt to compare a float2 and a float2 in an if statement, only to find that the comparison yields a bool2 rather than a bool.

This seems like logical behavior, now that I'm used to it--but there doesn't seem to be any elegant way to convert bool2 to bool so it can be used like this.

I would expect one of the following:

  • Bool2 has methods And(), Or(), Xor() that can be called directly and return bools. Perhaps syntactically ugly--if ((myPos != otherPos).And())--but this would be my preferred behavior.
  • Bool2 automatically converts to bool by performing AND or some such on its components. I can understand why this is not done, given that no default behavior would work for every case.
  • Comparing bool2 and bool2 returns true if all components are equal, false otherwise, the same way Vector2 == Vector2 works.

But none of these appears to be the case.

At present, I am forced either to cache the bool2 in a variable and compare its components in the if (...) statement, or to directly compare the components of the float2s. Functional ways to code, certainly, but unpleasant to look at, especially given the prior compactness and understandibility of comparing Vector2 and Vector2.

Any thoughts on this? Am I missing some existing method to do this? And are these unpleasantly lengthy methods superior in some way, or at least intended?

Considerable performance fixes

Hi there!
I noticed two problems that reduce performance and can easily be fixed 😄

1. Not using throw helpers

The jit will never inline a method if it throws an exception, even if you add the AgressiveInlining attribute.

Example: int2.gen.cs line:775

The common fix for this is very simple, just use a "throw helper", like this:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int select_shuffle_component(int2 a, int2 b, ShuffleComponent component)
{
    switch(component)
    {
        case ShuffleComponent.LeftX:
            return a.x;
        case ShuffleComponent.LeftY:
            return a.y;
        case ShuffleComponent.RightX:
            return b.x;
        case ShuffleComponent.RightY:
            return b.y;
        default:
            ThrowInvalidArgument();
    }
}

static void ThrowInvalidArgument()
{
    throw new System.ArgumentException("Invalid shuffle component: " + component);
}

2. Using the "fixed" statement instead of a reinterpret cast

The code used for indexers can be improved a lot!
Example: int2.gen.cs line:616

The fixed statement is horrible because just like throwing exceptions, it prevents a ton of optimizations (it is implemented that way on all runtimes I tested!).

Take a look at the asm it generates:

Code:
example code

(z = test1[6] is there on purpose, not a typo)

Assembly:
asm old

This should instead be done using a reinterpret cast.

Keep in mind that even though the syntax of Unsafe can sometimes (fortunately not here) become really unwieldy, it pretty much always compiles down to very simple instructions. (In fact methods like Unsafe.As<TFrom, TTo>(ref source) are literally a nop because they only trick the C# compiler into accepting the type change).
It's really just the C# name for reinterpret_cast.

By simply casting ref this to a little helper struct all overhead is gone.

Btw Unsafe is defined in System.Runtime.CompilerServices.Unsafe. The As() method I'm using here has an extremely simple definition (in this case it does literally nothing as you can see). All other functions in there are just as trivial, so they should be really easy for Unity to add 👍

Here is what I did instead:

struct int2
{
	public int x;
	public int y;

	public unsafe int this[int index]
	{
		get
		{
			return Unsafe.As<int2, ArrayUnion>(ref this).ints[index];
		}
		set
		{
			Unsafe.As<int2, ArrayUnion>(ref this).ints[index] = value;
		}
	}
}

[StructLayout(LayoutKind.Explicit)]
internal unsafe struct ArrayUnion
{
	// The fixed array sizes are assuming a float4(x,y,z,w) as maximum
	// but their size doesn't even actually matter because we're only using
	// it to reinterpret the bits anyway!
	[FieldOffset(0)]
	public fixed int ints[4];
	[FieldOffset(0)]
	public fixed uint uints[4];
	[FieldOffset(0)]
	public fixed float floats[4];
	[FieldOffset(0)]
	public fixed short shorts[2 * 4]; // 2 shorts per field, 4 times
	[FieldOffset(0)]
	public fixed bool bools[4 * 4]; // 4 bools per field, 4 times
	// ...
}

And with the exact same C# code, this time the disassembly looks like this:

asm improved

This time the jit was able to absolutely decimate the code! Nice! Let me know what you think 😄

Design reason behind select() parameter ordering

So, math.select() essentially maps to a ternary operator. Is there a design reason why the parameters are exactly in the reverse order of a ternary operator? It was really counter intuitive to me when I first saw that.

I'm not sure I understand why it wouldn't use the same ordering as the ternary operator. Something like

select(condition, a, b) //a if true, otherwise b

It seems a lot more intuitive to follow the established order of the ternary since it's exactly what it does anyway.

GetHashCode should be overridden for int2,int3,int4 to reduce collisions(also for the floats but probably less important there)

example:
int3 val1 = new int3(3, 9,7);
int3 val2 = new int3(7, 3,9);
creates the same hash, I don't exactly know how the default hash code implementation looks like but from what I know it is really bad for structs and should never be used whenever Equals has been overridden.

the old Vector2Int and Vector3Int classes have overridden the GetHashCode methods:

Vector3Int: return x.GetHashCode() ^ (y.GetHashCode() << 2) ^ (z.GetHashCode() >> 2);
Vector2Int: return x.GetHashCode() ^ (y.GetHashCode() << 2);

those however also are rather bad implementations as they have tons of collisions too:
for example all these Vector3Int have a hash value of 12 (there are definitely even more than those)
(2, 3, 9)
(2, 3, 10)
(2, 3, 11)
(4, 2, 2)
(4, 2, 3)

3D snoise artifact on x=y=z

The "snoise(float3 v)" function has artefacts in a line exactly at x=y=z.
This artefact seems to repeat in multiple places (always along the line x=y=z relative to a noise cell maybe?).

This produces obvious artefacts when used in my voxel engine in Unity3D,
which currently uses marching cubes to display the isosurface at value 0 of the 3d noise.

bug_img01

The relevant code is this:
valueForMarchingCubes = Unity.Mathematics.noise.snoise(pos3d / 100f) + 0.42f;

A reproduceable Unity3D script:

using UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;

public class NoiseBugRepro : MonoBehaviour {
    // Start is called before the first frame update
    void Start () {
        string output = "";
        for (int i = 0; i<20; ++i) {
            float x = lerp(1.8f, 2.2f, i / 20f);
            float3 pos = float3(x, 2f, 2f);

            float val = noise.snoise(pos / 20f);

            output += string.Format("noise.snoise({0:F2}, {1:F2}, {2:F2}) -> {3:F6}\n", pos.x, pos.y, pos.z, val);
        }

        Debug.Log(output);
    }
}

Output that shows the artefact when exactly on the x=y=z line:

noise.snoise(1.80, 2.00, 2.00) -> -0.373848
noise.snoise(1.82, 2.00, 2.00) -> -0.372971
noise.snoise(1.84, 2.00, 2.00) -> -0.372090
noise.snoise(1.86, 2.00, 2.00) -> -0.371204
noise.snoise(1.88, 2.00, 2.00) -> -0.370314
noise.snoise(1.90, 2.00, 2.00) -> -0.369420
noise.snoise(1.92, 2.00, 2.00) -> -0.368521
noise.snoise(1.94, 2.00, 2.00) -> -0.367619
noise.snoise(1.96, 2.00, 2.00) -> -0.366712
noise.snoise(1.98, 2.00, 2.00) -> -0.365801
noise.snoise(2.00, 2.00, 2.00) -> -0.571772
noise.snoise(2.02, 2.00, 2.00) -> -0.363966
noise.snoise(2.04, 2.00, 2.00) -> -0.363043
noise.snoise(2.06, 2.00, 2.00) -> -0.362115
noise.snoise(2.08, 2.00, 2.00) -> -0.361184
noise.snoise(2.10, 2.00, 2.00) -> -0.360248
noise.snoise(2.12, 2.00, 2.00) -> -0.359309
noise.snoise(2.14, 2.00, 2.00) -> -0.358365
noise.snoise(2.16, 2.00, 2.00) -> -0.357418
noise.snoise(2.18, 2.00, 2.00) -> -0.356467

Compiling for Linux

Hi, I'm currently in the process of rewriting my game's math, and I'm using Unity.Mathematics to do so. Since my game requires the same formulas to be implemented in C# and HLSL, having a consistent syntax helps immensely.

My game is multiplayer, however, and I'd like to be able to use the same code on the server side, which is in a Linux environment. I've been implementing the server side code in .NET Core to ensure portability. Is there a way to use Unity.Mathematics in that project? Since Unity does support Linux, I'm assuming there's a workflow. Would I have to switch to Mono?

Use plain constructors instead of function calls for static readonly

With the upcoming changes on our handling of static readonly, it is preferred to use only struct constructors instead of function calls to initialize static readonly.

Typically, these should be changed (they are in tests, so it's not a huge issue, but better keep it in mind for other cases through the codebase)

static internal readonly float3x3 test3x3_xyz = float3x3( 0.686179155968f, -0.684009078513f, -0.247567660300f,
0.555656924414f, 0.273213475262f, 0.785238676636f,
-0.469471562786f, -0.676377097075f, 0.567547772692f);
static internal readonly float3x3 test3x3_xzy = float3x3( 0.686179155968f, -0.716805468125f, -0.123887395569f,
0.629320391050f, 0.499539794942f, 0.595328345266f,
-0.364847929038f, -0.486466765705f, 0.793874092373f);
static internal readonly float3x3 test3x3_yxz = float3x3( 0.912505475649f, -0.404519349890f, -0.0608099701904f,
0.276167195792f, 0.499539794942f, 0.8210917568930f,
-0.301770503659f, -0.766044443119f, 0.5675477726920f);
static internal readonly float3x3 test3x3_yzx = float3x3( 0.68617915596800f, -0.629320391050f, 0.364847929038f,
-0.00246669562435f, 0.499539794942f, 0.866287428445f,
-0.72742840288700f, -0.595328345266f, 0.341221453011f);
static internal readonly float3x3 test3x3_zxy = float3x3( 0.459852836288f, -0.835146653037f, 0.301770503659f,
0.404519349890f, 0.499539794942f, 0.766044443119f,
-0.790505828266f, -0.230195701935f, 0.567547772692f);
static internal readonly float3x3 test3x3_zyx = float3x3( 0.686179155968f, -0.555656924414f, 0.469471562786f,
0.125029621267f, 0.725866114623f, 0.676377097075f,
-0.716607116711f, -0.405418013897f, 0.567547772692f);

Add samples for basic math operations to Unity Manual

At time of writing, this is the whole of the package manual for Mathematics

Unity's C# SIMD math library providing vector types and math functions with a shader like syntax. This package is still in experimental phase.

We need some examples on how to do basic common operations. Some ideas:

  • using Random
  • using Noise
  • quaternion multiplication

[Feature Request] Zeroed swizzle operators (e.g. float3.x__, float3._y_, float3.__z)

I'd find it handy to have zeroed swizzle operators that would let me do something like this:

float3 first = new float3(1f, 2f, 3f);
float3 second = new float3(7f, 8f, 9f);

float3 combined = first.x_z + second._y_; // == new float3(1f, 8f, 3f)

For me, this sometimes seems easier to understand at a glance than having something like:

float3 first = new float3(1f, 2f, 3f);
float3 second = new float3(7f, 8f, 9f);

float3 combined = new float3(first.x, second.y, first.z); // == new float3(1f, 8f, 3f)

[Feature Request] Add explicit conversion from euler to quaternion with rotation order

There is no explicit conversion from euler to quaternion, we need to convert to float3x3 first and then to quaternion.

As a first iteration we could only provide a methods that does the implicit conversion and improve it later.

public quaternion FromEuler(float3 xyz, RotationOrder order = RotationOrder.Default)
{
    return new quaternion( float3x3.Euler(xyz, order));
}

EulerXYZ to Quaternion is wrong

Using both UnityEngine code and an online calculator shows that the values given by quaternion.EulerXYZ() are so fundamentally wrong that it is hard to believe that I'm not making some terrible mistake.

For example, quaternion.EulerXYZ(45, 0, 0) = {-0.4871745, 0, 0, -0.8733047}, which converting back to eulers, gives {58.31, 0, 0} -- and that's closer than most comparisons, well, except {0,0,0} => {0,0,0,1} which seems right on.

using UnityEngine;
using Unity.Mathematics;

public class QTester : MonoBehaviour
{
    public Vector3 InEulers = Vector3.zero;
    public Quaternion DebugQ = new Quaternion();
    public Vector3 OutEulers = Vector3.zero;

    void Update()
    {
        //DebugQ = quaternion.EulerXYZ(InEulers);
        DebugQ = quaternion.EulerXYZ(InEulers.x, InEulers.y, InEulers.z);
        OutEulers = DebugQ.eulerAngles;
    }
}

At least one other variant of Euler* shows the same behavior, I didn't test further.

Visual inspection based on Using the RotationEulerXYZ components in an ECS project is consistent with the incorrect math -- that is setting a 45 degree rotation produces a result that looks closer to 60 degrees than to 45.

PacMan says my version of Mathematics is preview1-1.0.0
My Unity Editor version is 2019.1.0b8, Mac

3D snoise has artifacts and periodic tendencies

The provided 3D snoise function produces very low quality perlin noise and appears to be unusable for any practical application.

Here is a sample output of the algorithm, converted to PNG format:
Perlin

As you can see, there is a diagonal periodic nature to it at higher scales. And, if you look very closely, you can see a pattern of discontinuous individual pixels (stuck at values -1 or 1).

Here is the code I used to generate this texture. Perhaps I made a mistake somewhere?

    [BurstCompile]
    public struct PerlinNoiseGenJob : IJob, IDisposable
    {
        public PerlinNoiseGenJob(int2 seed, float frequency, int2 origin, int2 dimensions, float valueMultiplier=1)
        {
            this.seed = seed;
            this.frequency = frequency;
            this.origin = origin;
            this.dimensions = dimensions;
            this.valueMultiplier = valueMultiplier;
            perlinNoise = new NativeArray<float>(dimensions.x * dimensions.y, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
        }
        
        public int2 seed;

        public float frequency;

        public int2 origin;

        public int2 dimensions;

        public float valueMultiplier;

        public NativeArray<float> perlinNoise;
        
        public void Execute()
        {
//            float z = (float) hash(seed) / uint.MaxValue;
            float z = 0;
            for (int i = 0; i < perlinNoise.Length; i++)
            {
                int ox = i % dimensions.x;
                int oy = i / dimensions.x;
                float pnx = (origin.x + ox) * frequency;
                float pny = (origin.y + oy) * frequency;
                perlinNoise[i] = noise.snoise(float3(pnx, pny, z)) * valueMultiplier;
            }
        }

        public void Dispose()
        {
            perlinNoise.Dispose();
        }
    }
    public class PerlinNoiseTextureGenerator : MonoBehaviour
    {
        public Texture2D texture;
        
        private void Start()
        {
            var dimensions = int2(1000,1000);
            var job = new PerlinNoiseGenJob(int2(5,12), 1f/10, int2(0,0), dimensions);
            var startTime = Time.realtimeSinceStartup;
            var handle = job.Schedule();
            handle.Complete();
            Debug.Log("Run time: "+(Time.realtimeSinceStartup - startTime));
            
            Color[] colors = new Color[dimensions.y * dimensions.x];
            for (int i=0; i<job.perlinNoise.Length; i++)
            {
                colors[i] = new Color((job.perlinNoise[i]+1)/2, 0,0);
            }
            
            texture = new Texture2D(dimensions.x,dimensions.y);
            texture.SetPixels(colors);
            
            //AssetDatabase.CreateAsset(texture, "Assets/Generated/Perlin.asset");
            File.WriteAllBytes("D:\\Perlin2.png", texture.EncodeToPNG());
            
            job.Dispose();
        }
    }

IEqualityComparers and Floor/Round and CeilToInt methods.

Good to see that the vector components are public fields instead of meaningless properties this time around 👍 Also nice to see that they have gotten the Serializable attributes as well.

Using structs as keys in HashSets and Dictionaries is pretty slow even if the struct has the IEquatable interface - they are still getting boxed (EDIT: they are not getting boxed, virtcalls on structs is just expensive). Providing a custom IEqualityComparer instance makes .Nets hash-tables a lot faster.

I find myself making them a lot, so would be really convenient if one as included, perhaps like so:

public partial class int3 : ...
{
    public static readonly Int3EqualityComparer DefaultEqualityComparer = new Int3EqualityComparer();

    public class Int3EqualityComparer : IEqualityComparer<int3>
    {
        public bool Equals(int3 a, int3 b)
        {
            return a.x == b.x && a.y == b.y && a.z == b.z;
        }

        public int GetHashCode(int3 v)
        {
            return ...
        }
    }
}

Would also be really convenient if int2, int3, and int4 had the FloorToInt, RoundToInt(v3) and CeilToInt methods. Just like Vector3Int

Add operators for multiplication functions

Right now the only way to multiply quaternion by quaternion or float4 by float4x4 is with math.mul. This concept is familiar reasonably discoverable for developers with shader programming experience, but that does not make up the majority of our users. We need to either fix the discoverability problem or provide the operators most users would expect from the Vector3, etc API

Missing math.pi

Mathf.PI works just fine of course but that's a bit of a code smell

Implicit cast bonanza

Hi,
In my 2d grid system code I would like to have function overloads to let it's users provide grid coordinates in different formats, like:

void SetGridValue ( int x , int y , Value value ) => collection[ x , y ] = value;
void SetGridValue ( int2 xy , Value value ) => collection[ xy ] = value;//the same issue applies to indexer
void SetGridValue ( int i , Value value ) => collection[ i ] = value;

But since int can be implicitly cast to int2 without user knowledge I came to a conclusion that this would be a bad idea. My vote here thereby is to make this cast explicit since implicit introduces uncertainty between these types.

Suggestion to use properties for vector.zero, rather than static readonly

Hi, I know this is just a nice to have feature, but while static readonly might be faster than calling a constructor, it does break the burst compiler. I am not sure if it is the plan to add support for static field support to burst, but otherwise changing vector.zero to a static get property would save a few headaches I think.

/Jannek

[Feature Request] Ref column indexers for matrices.

Hi, I've been (ill-advisedly) using some of your codegen to create larger matrices for linear algebra stuff. Pretty cool so far. One thing I've found, is that the floatN this[int i] indexer on matrices does not allow setting of individual members due to returning a struct by value. e.g: this doesn't work:

myNxnMatrix[2][3] = 9;

This is fairly expected, but I've found that if you used a ref floatN this[int i] you'd be able to allow for that kind of nested indexing, and even use the indexed column as a modifiable lvalue. In my case, I use it to avoid copying float9 vectors.

This also removes the need for the setter.

Best of all, the indexer would still make copies at the call site unless the ref keyword is explicitly used, so as to avoid unintentional modifications of the matrix.

Importing Unity.Mathematics.math shadows type names

When using static Unity.Mathematics.math, type names get shadowed by functions of the same name (e.g. float3, float4x4, quaternion), making it imposible to access their static members without fully qualifying the type name.

This makes it really annoying to use static members such as float3.zero, float4x4.PerspectiveFov, quaternion.AxisAngle, etc. having to either qualify them with Unity.Mathematics. or dropping the using static altogether and qualify all math with math..

[Feature Request] projection function

I was playing with ECS today, and I was looking for a function to project a float3 onto a plane described by a normal float3. It looks like projection functions don't exist yet (?).

Double Precision Request

I'd like to see double precision options here as well. (math operations for doubles, double2, double3, double4, etc.)

Rename quaternion.RotateX() and friends -> quaternion.XRotation()

There is inconsistency right now in the naming of quaternion factory methods, which can lead to confusion (see https://unity.slack.com/archives/CE7DZN2H1/p1546448661023000).

quaternion.RotateX() is named in a such a way that implies the method is going to rotate something, rather than produce a rotation quaternion (cf https://docs.google.com/document/d/1RaGSTzE3d3AN-l73J18nxKlPgIwLCzVdQuWdhYKywbA/edit). To bring them in line with LookRotation(), please consider renaming:

  • RotateX() -> XRotation()
  • RotateY() -> YRotation()
  • RotateZ() -> ZRotation()

3D Math operations

Seeing this is supposed to be a HLSL/GLSL compliant math library, would be nice to see some 3D math functions supported such as GetPointClosestToPlane or similar sugar to aid 3D math operations.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.