void Start()
 {
     // hypercube.shapeType = Shape4D.ShapeType.HyperCube;
     // hypercube.operation = Shape4D.Operation.Union;
     for (int i = 0; i < 10; ++i)
     {
         float x = Random.Range(-2.0f, 2.0f);
         float y = Random.Range(-2.0f, 2.0f);
         float z = Random.Range(-2.0f, 2.0f);
         hyperellipse = Instantiate(hyperellipse, new Vector3(x, y, z), Quaternion.identity);
         hyperellipse.transform.localScale = float3(Random.Range(0.0f, 2.0f), Random.Range(0.0f, 2.0f), Random.Range(0.0f, 2.0f));
         hyperellipse.positionW            = Random.Range(-2.0f, 2.0f);
         // hyperellipse.Scale.y = rnd.NextDouble()*5;
         // hyperellipse.Scale.z = rnd.NextDouble()*5;
         hyperellipse.scaleW = Random.Range(0.0f, 2.0f);
         hyperellipse.colour = new Vector4((x + 2) / 4, (y + 2) / 4, (z + 2) / 4, 0);
     }
 }
        // the distancefunction for the shapes
        public float GetShapeDistance(Shape4D shape, float4 p4D)
        {
            p4D -= (float4)shape.Position();

            p4D.xz = mul(p4D.xz, float2x2(cos(shape.Rotation().y), sin(shape.Rotation().y), -sin(shape.Rotation().y), cos(shape.Rotation().y)));
            p4D.yz = mul(p4D.yz, float2x2(cos(shape.Rotation().x), -sin(shape.Rotation().x), sin(shape.Rotation().x), cos(shape.Rotation().x)));
            p4D.xy = mul(p4D.xy, float2x2(cos(shape.Rotation().z), -sin(shape.Rotation().z), sin(shape.Rotation().z), cos(shape.Rotation().z)));

            p4D.xw = mul(p4D.xw, float2x2(cos(shape.RotationW().x), sin(shape.RotationW().x), -sin(shape.RotationW().x), cos(shape.RotationW().x)));
            p4D.zw = mul(p4D.zw, float2x2(cos(shape.RotationW().z), -sin(shape.RotationW().z), sin(shape.RotationW().z), cos(shape.RotationW().z)));
            p4D.yw = mul(p4D.yw, float2x2(cos(shape.RotationW().y), -sin(shape.RotationW().y), sin(shape.RotationW().y), cos(shape.RotationW().y)));

            //Debug.Log("p4D: " + p4D);

            switch (shape.shapeType)
            {
            case Shape4D.ShapeType.HyperCube:
                return(Df.sdHypercube(p4D, shape.Scale()));

            case Shape4D.ShapeType.HyperSphere:
                return(Df.sdHypersphere(p4D, shape.Scale().x));

            case Shape4D.ShapeType.DuoCylinder:
                return(Df.sdDuoCylinder(p4D, ((float4)shape.Scale()).xy));

            case Shape4D.ShapeType.plane:
                return(Df.sdPlane(p4D, shape.Scale()));

            case Shape4D.ShapeType.Cone:
                return(Df.sdCone(p4D, shape.Scale()));

            case Shape4D.ShapeType.FiveCell:
                return(Df.sd5Cell(p4D, shape.Scale()));

            case Shape4D.ShapeType.SixteenCell:
                return(Df.sd16Cell(p4D, shape.Scale().x));

            case Shape4D.ShapeType.Torus:
                return(Df.sdTorus(p4D, ((float4)shape.Scale()).xy));
            }

            return(Camera.main.farClipPlane);
        }
        public float DistanceField(float3 p)
        {
            float4  p4D  = float4(p, cameraScript._wPosition);
            Vector3 wRot = cameraScript._wRotation * Mathf.Deg2Rad;

            if ((wRot).magnitude != 0)
            {
                p4D.xw = mul(p4D.xw, float2x2(cos(wRot.x), -sin(wRot.x), sin(wRot.x), cos(wRot.x)));
                p4D.yw = mul(p4D.yw, float2x2(cos(wRot.y), -sin(wRot.y), sin(wRot.y), cos(wRot.y)));
                p4D.zw = mul(p4D.zw, float2x2(cos(wRot.z), -sin(wRot.z), sin(wRot.z), cos(wRot.z)));
            }

            float globalDst = Camera.main.farClipPlane;

            for (int i = 0; i < cameraScript.orderedShapes.Count; i++)
            {
                //Debug.Log(cameraScript.orderedShapes.Count);
                Shape4D shape = cameraScript.orderedShapes[i];
                if (cameraScript.orderedShapes[i].collide)
                {
                    int numChildren = shape.numChildren;

                    ///Debug.Log("p4D: " + p4D);
                    float localDst = GetShapeDistance(shape, p4D);


                    for (int j = 0; j < numChildren; j++)
                    {
                        Shape4D childShape = cameraScript.orderedShapes[i + j + 1];
                        float   childDst   = GetShapeDistance(childShape, p4D);

                        localDst = Df.Combine(localDst, childDst, childShape.operation, childShape.smoothRadius);
                    }
                    i += numChildren; // skip over children in outer loop

                    globalDst = Df.Combine(globalDst, localDst, shape.operation, shape.smoothRadius);
                }
            }

            return(globalDst);
        }
 void Start()
 {
     // hypercube.shapeType = Shape4D.ShapeType.HyperCube;
     // hypercube.operation = Shape4D.Operation.Union;
     for (int x = -1; x <= 1; ++x)
     {
         for (int y = -1; y <= 1; ++y)
         {
             for (int z = -1; z <= 1; ++z)
             {
                 for (int w = -1; w <= 1; ++w)
                 {
                     if ((abs(x) + abs(y) + abs(z) + abs(w)) > 2)
                     {
                         hypercube           = Instantiate(hypercube, new Vector3(x, y, z), Quaternion.identity);
                         hypercube.scaleW    = 0.5f;
                         hypercube.positionW = w;
                     }
                 }
             }
         }
     }
 }