static StackObject *Ctor_2(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 3);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            UnityEngine.Vector3 c = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);
            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            UnityEngine.Vector3 b = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);
            ptr_of_this_method = ILIntepreter.Minus(__esp, 3);
            UnityEngine.Vector3 a = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);

            var result_of_this_method = new UnityEngine.Plane(a, b, c);

            if (!isNewObj)
            {
                __ret--;
                WriteBackInstance(__domain, __ret, __mStack, ref result_of_this_method);
                return(__ret);
            }
            return(ILIntepreter.PushObject(__ret, __mStack, result_of_this_method));
        }
        static object PerformMemberwiseClone(ref object o)
        {
            var ins = new UnityEngine.Plane();

            ins = (UnityEngine.Plane)o;
            return(ins);
        }
Beispiel #3
0
        public static bool GetNodesInFrustum(Frustum frustum, int visibleLayers, ref HashSet <CSGTreeNode> rectFoundNodes)
        {
            var     planes = new Plane[6];
            Vector4 srcVector;
            var     allTrees = CSGManager.AllTrees;

            for (var t = 0; t < allTrees.Length; t++)
            {
                var tree  = allTrees[t];
                var model = CSGNodeHierarchyManager.FindCSGNodeByTreeNode(tree) as ChiselModel;
                if (!model || !model.isActiveAndEnabled)
                {
                    continue;
                }

                if (((1 << model.gameObject.layer) & visibleLayers) == 0)
                {
                    continue;
                }

                var query = CSGMeshQueryManager.GetMeshQuery(model);

                // We only accept RayCasts into this model if it's visible
                if (!CSGMeshQueryManager.IsVisible(query))
                {
                    continue;
                }

                // Transform the frustum into the space of the tree
                var transform = model.transform;
                var worldToLocalMatrixInversed           = transform.localToWorldMatrix;                 // localToWorldMatrix == worldToLocalMatrix.inverse
                var worldToLocalMatrixInversedTransposed = worldToLocalMatrixInversed.transpose;
                for (int p = 0; p < 6; p++)
                {
                    var srcPlane = frustum.Planes[p];
                    srcVector.x = srcPlane.normal.x;
                    srcVector.y = srcPlane.normal.y;
                    srcVector.z = srcPlane.normal.z;
                    srcVector.w = srcPlane.distance;

                    srcVector = worldToLocalMatrixInversedTransposed * srcVector;

                    planes[p].normal   = srcVector;
                    planes[p].distance = srcVector.w;
                }

                var treeNodesInFrustum = tree.GetNodesInFrustum(planes);
                if (treeNodesInFrustum == null)
                {
                    continue;
                }

                for (int n = 0; n < treeNodesInFrustum.Length; n++)
                {
                    var treeNode = treeNodesInFrustum[n];
                    rectFoundNodes.Add(treeNode);
                }
            }
            return(rectFoundNodes.Count > 0);
        }
Beispiel #4
0
 /// <summary>Create a plane with a normal and the distance to the origin</summary>
 /// <param name="inNormal">The normal of the plane</param>
 /// <param name="inD">The distance to the origin</param>
 public CSGPlane(UnityEngine.Plane plane)
 {
     a = plane.normal.x;
     b = plane.normal.y;
     c = plane.normal.z;
     d = -plane.distance;
 }
        static StackObject *SameSide_13(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 3);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            UnityEngine.Vector3 @inPt1 = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            UnityEngine.Vector3 @inPt0 = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 3);
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            UnityEngine.Plane instance_of_this_method = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));

            var result_of_this_method = instance_of_this_method.SameSide(@inPt0, @inPt1);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 3);
            WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);

            __intp.Free(ptr_of_this_method);
            __ret->ObjectType = ObjectTypes.Integer;
            __ret->Value      = result_of_this_method ? 1 : 0;
            return(__ret + 1);
        }
        static StackObject *Set3Points_5(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 4);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            UnityEngine.Vector3 @c = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            UnityEngine.Vector3 @b = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 3);
            UnityEngine.Vector3 @a = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 4);
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            UnityEngine.Plane instance_of_this_method = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));

            instance_of_this_method.Set3Points(@a, @b, @c);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 4);
            WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);

            __intp.Free(ptr_of_this_method);
            return(__ret);
        }
    public void ReplacePlayerPlane(UnityEngine.Plane newValue)
    {
        var index     = GameComponentsLookup.PlayerPlane;
        var component = CreateComponent <PlayerPlaneComponent>(index);

        component.value = newValue;
        ReplaceComponent(index, component);
    }
Beispiel #8
0
        public PlanePolygonBuilder(Plane plane)
        {
#if UNITY_EDITOR || UNITY_STANDALONE
            var rotation = Quaternion.FromToRotation(plane.normal, new Vector3(0, 0, -1));
#else
            var rotation = IdendityQuaternion;
#endif
            this.edgesToPolygon = new EdgesToPolygonBuilder(rotation);
        }
Beispiel #9
0
 /// <summary>Write a plane (16 bytes) to the writer.</summary>
 /// <param name="value">Plane to write.</param>
 public void Write(UnityEngine.Plane value)
 {
     if (Disposed)
     {
         throw new ObjectDisposedException(GetType().FullName);
     }
     Internal = Allocator.ExpandMessage(Internal, Position, 16);
     Serializer.WriteSingle(Internal, Position, value.normal.x);
     Serializer.WriteSingle(Internal, Position + 4, value.normal.y);
     Serializer.WriteSingle(Internal, Position + 8, value.normal.z);
     Serializer.WriteSingle(Internal, Position + 12, value.distance);
     Position += 16;
 }
Beispiel #10
0
        public static Vector2 TempScreenToWorld(this Vector2 screenPos)
        {
            var cam   = UnityEngine.Camera.main;
            var ray   = cam.ScreenPointToRay(new UnityEngine.Vector3(screenPos.X, screenPos.Y));
            var plane = new UnityEngine.Plane(UnityEngine.Vector3.up, UnityEngine.Vector3.zero);

            float d;

            if (plane.Raycast(ray, out d))
            {
                return(new Vector2(ray.GetPoint(d).x, ray.GetPoint(d).z));
            }

            return(Vector2.Zero);
        }
        static void WriteBackInstance(CSHotFix.Runtime.Enviorment.AppDomain __domain, StackObject *ptr_of_this_method, IList <object> __mStack, ref UnityEngine.Plane instance_of_this_method)
        {
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            switch (ptr_of_this_method->ObjectType)
            {
            case ObjectTypes.Object:
            {
                __mStack[ptr_of_this_method->Value] = instance_of_this_method;
            }
            break;

            case ObjectTypes.FieldReference:
            {
                var ___obj = __mStack[ptr_of_this_method->Value];
                if (___obj is ILTypeInstance)
                {
                    ((ILTypeInstance)___obj)[ptr_of_this_method->ValueLow] = instance_of_this_method;
                }
                else
                {
                    var t = __domain.GetType(___obj.GetType()) as CLRType;
                    t.SetFieldValue(ptr_of_this_method->ValueLow, ref ___obj, instance_of_this_method);
                }
            }
            break;

            case ObjectTypes.StaticFieldReference:
            {
                var t = __domain.GetType(ptr_of_this_method->Value);
                if (t is ILType)
                {
                    ((ILType)t).StaticInstance[ptr_of_this_method->ValueLow] = instance_of_this_method;
                }
                else
                {
                    ((CLRType)t).SetStaticFieldValue(ptr_of_this_method->ValueLow, instance_of_this_method);
                }
            }
            break;

            case ObjectTypes.ArrayReference:
            {
                var instance_of_arrayReference = __mStack[ptr_of_this_method->Value] as UnityEngine.Plane[];
                instance_of_arrayReference[ptr_of_this_method->ValueLow] = instance_of_this_method;
            }
            break;
            }
        }
Beispiel #12
0
        static int __CreateInstance(RealStatePtr L)
        {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);

            try {
                if (LuaAPI.lua_gettop(L) == 3 && translator.Assignable <UnityEngine.Vector3>(L, 2) && translator.Assignable <UnityEngine.Vector3>(L, 3))
                {
                    UnityEngine.Vector3 inNormal; translator.Get(L, 2, out inNormal);
                    UnityEngine.Vector3 inPoint; translator.Get(L, 3, out inPoint);

                    UnityEngine.Plane __cl_gen_ret = new UnityEngine.Plane(inNormal, inPoint);
                    translator.Push(L, __cl_gen_ret);

                    return(1);
                }
                if (LuaAPI.lua_gettop(L) == 3 && translator.Assignable <UnityEngine.Vector3>(L, 2) && LuaTypes.LUA_TNUMBER == LuaAPI.lua_type(L, 3))
                {
                    UnityEngine.Vector3 inNormal; translator.Get(L, 2, out inNormal);
                    float d = (float)LuaAPI.lua_tonumber(L, 3);

                    UnityEngine.Plane __cl_gen_ret = new UnityEngine.Plane(inNormal, d);
                    translator.Push(L, __cl_gen_ret);

                    return(1);
                }
                if (LuaAPI.lua_gettop(L) == 4 && translator.Assignable <UnityEngine.Vector3>(L, 2) && translator.Assignable <UnityEngine.Vector3>(L, 3) && translator.Assignable <UnityEngine.Vector3>(L, 4))
                {
                    UnityEngine.Vector3 a; translator.Get(L, 2, out a);
                    UnityEngine.Vector3 b; translator.Get(L, 3, out b);
                    UnityEngine.Vector3 c; translator.Get(L, 4, out c);

                    UnityEngine.Plane __cl_gen_ret = new UnityEngine.Plane(a, b, c);
                    translator.Push(L, __cl_gen_ret);

                    return(1);
                }

                if (LuaAPI.lua_gettop(L) == 1)
                {
                    translator.Push(L, default(UnityEngine.Plane));
                    return(1);
                }
            }
            catch (System.Exception __gen_e) {
                return(LuaAPI.luaL_error(L, "c# exception:" + __gen_e));
            }
            return(LuaAPI.luaL_error(L, "invalid arguments to UnityEngine.Plane constructor!"));
        }
        int __CreateInstanceUnityEnginePlane(RealStatePtr L, int gen_param_count)
        {
            ObjectTranslator translator = this;

            if (gen_param_count == 3 && translator.Assignable <UnityEngine.Vector3>(L, 2) && translator.Assignable <UnityEngine.Vector3>(L, 3))
            {
                UnityEngine.Vector3 _inNormal; translator.Get(L, 2, out _inNormal);
                UnityEngine.Vector3 _inPoint; translator.Get(L, 3, out _inPoint);

                UnityEngine.Plane gen_ret = new UnityEngine.Plane(_inNormal, _inPoint);
                translator.Push(L, gen_ret);

                return(1);
            }
            if (gen_param_count == 3 && translator.Assignable <UnityEngine.Vector3>(L, 2) && LuaTypes.LUA_TNUMBER == LuaAPI.lua_type(L, 3))
            {
                UnityEngine.Vector3 _inNormal; translator.Get(L, 2, out _inNormal);
                float _d = (float)LuaAPI.lua_tonumber(L, 3);

                UnityEngine.Plane gen_ret = new UnityEngine.Plane(_inNormal, _d);
                translator.Push(L, gen_ret);

                return(1);
            }
            if (gen_param_count == 4 && translator.Assignable <UnityEngine.Vector3>(L, 2) && translator.Assignable <UnityEngine.Vector3>(L, 3) && translator.Assignable <UnityEngine.Vector3>(L, 4))
            {
                UnityEngine.Vector3 _a; translator.Get(L, 2, out _a);
                UnityEngine.Vector3 _b; translator.Get(L, 3, out _b);
                UnityEngine.Vector3 _c; translator.Get(L, 4, out _c);

                UnityEngine.Plane gen_ret = new UnityEngine.Plane(_a, _b, _c);
                translator.Push(L, gen_ret);

                return(1);
            }

            if (gen_param_count == 1)
            {
                translator.Push(L, default(UnityEngine.Plane));
                return(1);
            }


            return(LuaAPI.luaL_error(L, "invalid arguments to UnityEngine.Plane constructor!"));
        }
        int UnityEnginePlane_m_Translate_xlua_st_(RealStatePtr L, int gen_param_count)
        {
            ObjectTranslator translator = this;



            {
                UnityEngine.Plane   _plane; translator.Get(L, 1, out _plane);
                UnityEngine.Vector3 _translation; translator.Get(L, 2, out _translation);

                UnityEngine.Plane gen_ret = UnityEngine.Plane.Translate(_plane, _translation);
                translator.Push(L, gen_ret);



                return(1);
            }
        }
        static StackObject *ToString_15(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 1);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            UnityEngine.Plane instance_of_this_method = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));

            var result_of_this_method = instance_of_this_method.ToString();

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);

            __intp.Free(ptr_of_this_method);
            return(ILIntepreter.PushObject(__ret, __mStack, result_of_this_method));
        }
        static StackObject *Translate_9(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 2);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            UnityEngine.Vector3 @translation = (UnityEngine.Vector3) typeof(UnityEngine.Vector3).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            UnityEngine.Plane @plane = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);


            var result_of_this_method = UnityEngine.Plane.Translate(@plane, @translation);

            return(ILIntepreter.PushObject(__ret, __mStack, result_of_this_method));
        }
        static StackObject *get_distance_2(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 1);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            UnityEngine.Plane instance_of_this_method = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));

            var result_of_this_method = instance_of_this_method.distance;

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);

            __intp.Free(ptr_of_this_method);
            __ret->ObjectType       = ObjectTypes.Float;
            *(float *)&__ret->Value = result_of_this_method;
            return(__ret + 1);
        }
        static StackObject *set_distance_3(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 2);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            System.Single @value = *(float *)&ptr_of_this_method->Value;

            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            UnityEngine.Plane instance_of_this_method = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));

            instance_of_this_method.distance = value;

            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);

            __intp.Free(ptr_of_this_method);
            return(__ret);
        }
Beispiel #19
0
        static StackObject *SetCullingPlane_3(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 3);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            UnityEngine.Plane plane = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);
            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            System.Int32 index = ptr_of_this_method->Value;
            ptr_of_this_method = ILIntepreter.Minus(__esp, 3);
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            UnityEngine.Experimental.Rendering.CullingParameters instance_of_this_method;
            instance_of_this_method = (UnityEngine.Experimental.Rendering.CullingParameters) typeof(UnityEngine.Experimental.Rendering.CullingParameters).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));

            instance_of_this_method.SetCullingPlane(index, plane);

            WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);

            return(__ret);
        }
Beispiel #20
0
        static int _m_Translate_xlua_st_(RealStatePtr L)
        {
            try {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);



                {
                    UnityEngine.Plane   _plane; translator.Get(L, 1, out _plane);
                    UnityEngine.Vector3 _translation; translator.Get(L, 2, out _translation);

                    UnityEngine.Plane gen_ret = UnityEngine.Plane.Translate(_plane, _translation);
                    translator.Push(L, gen_ret);



                    return(1);
                }
            } catch (System.Exception gen_e) {
                return(LuaAPI.luaL_error(L, "c# exception:" + gen_e));
            }
        }
        static StackObject *Raycast_14(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 3);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            System.Single @enter = __intp.RetriveFloat(ptr_of_this_method, __mStack);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            UnityEngine.Ray @ray = (UnityEngine.Ray) typeof(UnityEngine.Ray).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));

            ptr_of_this_method = ILIntepreter.Minus(__esp, 3);
            ptr_of_this_method = ILIntepreter.GetObjectAndResolveReference(ptr_of_this_method);
            UnityEngine.Plane instance_of_this_method = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));

            var result_of_this_method = instance_of_this_method.Raycast(@ray, out @enter);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            switch (ptr_of_this_method->ObjectType)
            {
            case ObjectTypes.StackObjectReference:
            {
                var ___dst = *(StackObject **)&ptr_of_this_method->Value;
                ___dst->ObjectType       = ObjectTypes.Float;
                *(float *)&___dst->Value = @enter;
            }
            break;

            case ObjectTypes.FieldReference:
            {
                var ___obj = __mStack[ptr_of_this_method->Value];
                if (___obj is ILTypeInstance)
                {
                    ((ILTypeInstance)___obj)[ptr_of_this_method->ValueLow] = @enter;
                }
                else
                {
                    var ___type = __domain.GetType(___obj.GetType()) as CLRType;
                    ___type.SetFieldValue(ptr_of_this_method->ValueLow, ref ___obj, @enter);
                }
            }
            break;

            case ObjectTypes.StaticFieldReference:
            {
                var ___type = __domain.GetType(ptr_of_this_method->Value);
                if (___type is ILType)
                {
                    ((ILType)___type).StaticInstance[ptr_of_this_method->ValueLow] = @enter;
                }
                else
                {
                    ((CLRType)___type).SetStaticFieldValue(ptr_of_this_method->ValueLow, @enter);
                }
            }
            break;

            case ObjectTypes.ArrayReference:
            {
                var instance_of_arrayReference = __mStack[ptr_of_this_method->Value] as System.Single[];
                instance_of_arrayReference[ptr_of_this_method->ValueLow] = @enter;
            }
            break;
            }

            __intp.Free(ptr_of_this_method);
            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            __intp.FreeStackValueType(ptr_of_this_method);
            __intp.Free(ptr_of_this_method);
            ptr_of_this_method = ILIntepreter.Minus(__esp, 3);
            WriteBackInstance(__domain, ptr_of_this_method, __mStack, ref instance_of_this_method);

            __intp.Free(ptr_of_this_method);
            __ret->ObjectType = ObjectTypes.Integer;
            __ret->Value      = result_of_this_method ? 1 : 0;
            return(__ret + 1);
        }
Beispiel #22
0
        static bool CreateExtrudedSubMesh(CSGBrushSubMesh subMesh, int segments, int[] segmentDescriptionIndices, int[] segmentAssetIndices, int segmentTopIndex, int segmentBottomIndex, Vector3[] vertices, CSGSurfaceAsset[] surfaceAssets, SurfaceDescription[] surfaceDescriptions)
        {
            if (vertices.Length < 3)
            {
                return(false);
            }

            // TODO: vertex reverse winding when it's not clockwise
            // TODO: handle duplicate vertices, remove them or avoid them being created in the first place (maybe use indices?)

            var segmentTopology = new SegmentTopology[segments];
            var edgeIndices     = new int[segments * 2];

            var polygonCount = 2;
            var edgeOffset   = segments + segments;

            for (int p = segments - 2, e = segments - 1, n = 0; n < segments; p = e, e = n, n++)
            {
                //			      t0
                //	 ------>   ------->   ----->
                //        v0 *          * v1
                //	 <-----    <-------   <-----
                //			^ |   e2   ^ |
                //          | |        | |
                //	   q1 p0| |e3 q2 e5| |n0 q3
                //          | |        | |
                //			| v   e4   | v
                //	 ------>   ------->   ----->
                //        v3 *          * v2
                //	 <-----    <-------   <-----
                //			      b0
                //
                var v0 = vertices[p];
                var v1 = vertices[e];
                var v2 = vertices[e + segments];
                var v3 = vertices[p + segments];

                var equals03 = (v0 - v3).sqrMagnitude < 0.0001f;
                var equals12 = (v1 - v2).sqrMagnitude < 0.0001f;
                if (equals03)
                {
                    if (equals12)
                    {
                        segmentTopology[n] = SegmentTopology.None;
                    }
                    else
                    {
                        segmentTopology[n] = SegmentTopology.TriangleNegative;
                    }
                }
                else
                if (equals12)
                {
                    segmentTopology[n] = SegmentTopology.TrianglePositive;
                }
                else
                {
                    var plane = new Plane(v0, v1, v3);
                    var dist  = plane.GetDistanceToPoint(v2);
                    if (UnityEngine.Mathf.Abs(dist) < 0.001f)
                    {
                        segmentTopology[n] = SegmentTopology.Quad;
                    }
                    else
                    {
                        segmentTopology[n] = (SegmentTopology)UnityEngine.Mathf.Sign(dist);
                    }
                }

                switch (segmentTopology[n])
                {
                case SegmentTopology.Quad:
                {
                    edgeIndices[(n * 2) + 0] = edgeOffset + 1;
                    polygonCount++;
                    edgeOffset += 4;
                    edgeIndices[(n * 2) + 1] = edgeOffset - 1;
                    break;
                }

                case SegmentTopology.TrianglesNegative:
                case SegmentTopology.TrianglesPositive:
                {
                    edgeIndices[(n * 2) + 0] = edgeOffset + 1;
                    polygonCount            += 2;
                    edgeOffset += 6;
                    edgeIndices[(n * 2) + 1] = edgeOffset - 1;
                    break;
                }

                case SegmentTopology.TriangleNegative:
                case SegmentTopology.TrianglePositive:
                {
                    edgeIndices[(n * 2) + 0] = edgeOffset + 1;
                    polygonCount++;
                    edgeOffset += 3;
                    edgeIndices[(n * 2) + 1] = edgeOffset - 1;
                    break;
                }

                case SegmentTopology.None:
                    edgeIndices[(n * 2) + 0] = 0;
                    edgeIndices[(n * 2) + 1] = 0;
                    break;
                }
            }

            var polygons = new CSGBrushSubMesh.Polygon[polygonCount];

            var surfaceDescription0 = surfaceDescriptions[segmentTopIndex];
            var surfaceDescription1 = surfaceDescriptions[segmentBottomIndex];
            var surfaceAsset0       = surfaceAssets[segmentTopIndex];
            var surfaceAsset1       = surfaceAssets[segmentBottomIndex];

            polygons[0] = new CSGBrushSubMesh.Polygon {
                surfaceID = 0, firstEdge = 0, edgeCount = segments, description = surfaceDescription0, surfaceAsset = surfaceAsset0
            };
            polygons[1] = new CSGBrushSubMesh.Polygon {
                surfaceID = 1, firstEdge = segments, edgeCount = segments, description = surfaceDescription1, surfaceAsset = surfaceAsset1
            };

            for (int s = 0, surfaceID = 2; s < segments; s++)
            {
                var descriptionIndex = (segmentDescriptionIndices == null) ? s + 2 : (segmentDescriptionIndices[s]);
                var assetIndex       = (segmentAssetIndices == null) ? 2 : (segmentAssetIndices[s]);
                var firstEdge        = edgeIndices[(s * 2) + 0] - 1;
                switch (segmentTopology[s])
                {
                case SegmentTopology.Quad:
                {
                    polygons[surfaceID] = new CSGBrushSubMesh.Polygon {
                        surfaceID = surfaceID, firstEdge = firstEdge, edgeCount = 4, description = surfaceDescriptions[descriptionIndex], surfaceAsset = surfaceAssets[assetIndex]
                    };
                    polygons[surfaceID].description.smoothingGroup = (uint)0;
                    surfaceID++;
                    break;
                }

                case SegmentTopology.TrianglesNegative:
                case SegmentTopology.TrianglesPositive:
                {
                    var smoothingGroup = surfaceID + 1;     // TODO: create an unique smoothing group for faceted surfaces that are split in two,
                                                            //			unless there's already a smoothing group for this edge; then use that

                    polygons[surfaceID + 0] = new CSGBrushSubMesh.Polygon {
                        surfaceID = surfaceID + 0, firstEdge = firstEdge, edgeCount = 3, description = surfaceDescriptions[descriptionIndex], surfaceAsset = surfaceAssets[assetIndex]
                    };
                    polygons[surfaceID + 0].description.smoothingGroup = (uint)smoothingGroup;
                    polygons[surfaceID + 1] = new CSGBrushSubMesh.Polygon {
                        surfaceID = surfaceID + 1, firstEdge = firstEdge + 3, edgeCount = 3, description = surfaceDescriptions[descriptionIndex], surfaceAsset = surfaceAssets[assetIndex]
                    };
                    polygons[surfaceID + 1].description.smoothingGroup = (uint)smoothingGroup;
                    surfaceID += 2;
                    break;
                }

                case SegmentTopology.TriangleNegative:
                case SegmentTopology.TrianglePositive:
                {
                    polygons[surfaceID] = new CSGBrushSubMesh.Polygon {
                        surfaceID = surfaceID, firstEdge = firstEdge, edgeCount = 3, description = surfaceDescriptions[descriptionIndex], surfaceAsset = surfaceAssets[assetIndex]
                    };
                    polygons[surfaceID].description.smoothingGroup = (uint)0;
                    surfaceID++;
                    break;
                }

                case SegmentTopology.None:
                {
                    break;
                }
                }
            }

            var halfEdges = new BrushMesh.HalfEdge[edgeOffset];

            for (int p = segments - 2, e = segments - 1, n = 0; n < segments; p = e, e = n, n++)
            {
                //var vi0 = p;
                var vi1 = e;
                var vi2 = e + segments;
                var vi3 = p + segments;

                var t0 = e;
                var b0 = ((segments - 1) - e) + segments;

                switch (segmentTopology[n])
                {
                case SegmentTopology.None:
                {
                    halfEdges[t0] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };
                    halfEdges[b0] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = t0
                    };
                    break;
                }

                case SegmentTopology.TrianglePositive:
                {
                    halfEdges[t0] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = -1
                    };
                    halfEdges[b0] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = -1
                    };
                    break;
                }

                case SegmentTopology.TriangleNegative:
                default:
                {
                    halfEdges[t0] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = -1
                    };
                    halfEdges[b0] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = -1
                    };
                    break;
                }
                }
            }

            for (int p = segments - 2, e = segments - 1, n = 0; n < segments; p = e, e = n, n++)
            {
                var vi0 = p;
                var vi1 = e;
                var vi2 = e + segments;
                var vi3 = p + segments;

                var t0 = e;
                var b0 = ((segments - 1) - e) + segments;

                var nn = (n + 1) % segments;

                var p0 = edgeIndices[(e * 2) + 1];
                var n0 = edgeIndices[(nn * 2) + 0];

                switch (segmentTopology[n])
                {
                case SegmentTopology.None:
                {
                    continue;
                }

                case SegmentTopology.Quad:
                {
                    //			      t0
                    //	 ------>   ------->   ----->
                    //        v0 *          * v1
                    //	 <-----    <-------   <-----
                    //			^ |   e2   ^ |
                    //          | |        | |
                    //	   q1 p0| |e3 q2 e5| |n0 q3
                    //          | |        | |
                    //			| v   e4   | v
                    //	 ------>   ------->   ----->
                    //        v3 *          * v2
                    //	 <-----    <-------   <-----
                    //			      b0
                    //

                    var q2 = edgeIndices[(n * 2) + 0];
                    var e2 = q2 - 1;
                    var e3 = q2 + 0;
                    var e4 = q2 + 1;
                    var e5 = q2 + 2;

                    halfEdges[t0].twinIndex = e2;
                    halfEdges[b0].twinIndex = e4;

                    halfEdges[e2] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = t0
                    };
                    halfEdges[e3] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = p0
                    };

                    halfEdges[e4] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };
                    halfEdges[e5] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = n0
                    };
                    break;
                }

                case SegmentTopology.TrianglesNegative:
                {
                    //			        t0
                    //	 ------>   ----------->   ----->
                    //        v0 *              * v1
                    //	 <-----    <-----------   <-----
                    //			^ |     e2   ^ ^ |
                    //          | |        / / | |
                    //          | |    e4/ /   | |
                    //	   q1 p0| |e3   / /  e7| |n0 q3
                    //          | |   / /e5    | |
                    //          | | / /        | |
                    //			| v/v   e6     | v
                    //	 ------>   ----------->   ----->
                    //        v3 *              * v2
                    //	 <-----    <-----------   <-----
                    //			        b0
                    //

                    var q2 = edgeIndices[(n * 2) + 0];
                    var e2 = q2 - 1;
                    var e3 = q2 + 0;
                    var e4 = q2 + 1;
                    var e5 = q2 + 2;
                    var e6 = q2 + 3;
                    var e7 = q2 + 4;

                    halfEdges[t0].twinIndex = e2;
                    halfEdges[b0].twinIndex = e6;

                    halfEdges[e2] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = t0
                    };
                    halfEdges[e3] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = p0
                    };
                    halfEdges[e4] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = e5
                    };

                    halfEdges[e5] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = e4
                    };
                    halfEdges[e6] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };
                    halfEdges[e7] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = n0
                    };
                    break;
                }

                case SegmentTopology.TrianglesPositive:
                {
                    //			        t0
                    //	 ------>   ----------->   ----->
                    //        v0 *              * v1
                    //	 <-----    <-----------   <-----
                    //			^ |^\   e5     ^ |
                    //          | | \ \        | |
                    //          | |   \ \ e6   | |
                    //	   q1 p0| |e3 e2\ \  e7| |n0 q3
                    //          | |       \ \  | |
                    //          | |        \ \ | |
                    //			| v   e4    \ v| v
                    //	 ------>   ----------->   ----->
                    //        v3 *              * v2
                    //	 <-----    <-----------   <-----
                    //			        b0
                    //

                    var q2 = edgeIndices[(n * 2) + 0];
                    var e2 = q2 - 1;
                    var e3 = q2 + 0;
                    var e4 = q2 + 1;
                    var e5 = q2 + 2;
                    var e6 = q2 + 3;
                    var e7 = q2 + 4;

                    halfEdges[t0].twinIndex = e5;
                    halfEdges[b0].twinIndex = e4;

                    halfEdges[e2] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = e6
                    };
                    halfEdges[e3] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = p0
                    };
                    halfEdges[e4] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };

                    halfEdges[e5] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = t0
                    };
                    halfEdges[e6] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = e2
                    };
                    halfEdges[e7] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = n0
                    };
                    break;
                }

                case SegmentTopology.TriangleNegative:
                {
                    //			      t0
                    //	 --->                      ------->
                    //       \                  ^ * v1
                    //	 <--- \                /  ^   <-----
                    //	     \ \              / / | |
                    //	      \ \            / /  | |
                    //	       \ \      t0  / /   | |
                    //	        \ \        / /e2  | | n0
                    //           \ \      / /     | |
                    //	          \ \    / / q2 e4| |   q3
                    //             \ \  / /       | |
                    //	            v \/ v   e3   | v
                    //	 ------------>   ------->   ----->
                    //              v3 *          * v2
                    //	 <-----------    <-------   <-----
                    //			            b0
                    //

                    var q2 = edgeIndices[(n * 2) + 0];
                    var e2 = q2 - 1;
                    var e3 = q2 + 0;
                    var e4 = q2 + 1;

                    halfEdges[t0].twinIndex = e2;
                    halfEdges[b0].twinIndex = e3;

                    // vi0 / vi3
                    halfEdges[e2] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = t0
                    };

                    halfEdges[e3] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };
                    halfEdges[e4] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = n0
                    };
                    break;
                }

                case SegmentTopology.TrianglePositive:
                {
                    //
                    //	 ------->                            ---->
                    //        v0 * \                       ^
                    //	 <-----     \                     /  <---
                    //			^ |^ \                   / /
                    //          | | \ \                 / /
                    //          | |  \ \               / /
                    //          | |   \ \ t0          / /
                    //   q1     | | e2 \ \           / /
                    //          | |     \ \         / /
                    //	      p0| |e3    \ \       / /
                    //          | |   q2  \ \     / /
                    //          | |        \ \   / /
                    //			| v   e4    \ v / v
                    //	 ------>   ----------->    ----->
                    //        v3 *              * v2
                    //	 <-----    <-----------    <-----
                    //			        b0
                    //

                    var q2 = edgeIndices[(n * 2) + 0];
                    var e2 = q2 - 1;
                    var e3 = q2 + 0;
                    var e4 = q2 + 1;

                    halfEdges[t0].twinIndex = e2;
                    halfEdges[b0].twinIndex = e4;

                    halfEdges[e2] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = t0
                    };
                    halfEdges[e3] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = p0
                    };

                    // vi1 / vi2
                    halfEdges[e4] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };
                    break;
                }
                }
            }

            subMesh.Polygons  = polygons;
            subMesh.HalfEdges = halfEdges;
            subMesh.Vertices  = vertices;
            subMesh.CreateOrUpdateBrushMesh();
            return(true);
        }
Beispiel #23
0
        static StackObject *TryCreatePlaneFromPolygon_5(ILIntepreter __intp, StackObject *__esp, IList <object> __mStack, CLRMethod __method, bool isNewObj)
        {
            CSHotFix.Runtime.Enviorment.AppDomain __domain = __intp.AppDomain;
            StackObject *ptr_of_this_method;
            StackObject *__ret = ILIntepreter.Minus(__esp, 2);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            UnityEngine.Plane @plane = (UnityEngine.Plane) typeof(UnityEngine.Plane).CheckCLRTypes(__intp.RetriveObject(ptr_of_this_method, __mStack));

            ptr_of_this_method = ILIntepreter.Minus(__esp, 2);
            UnityEngine.Vector3[] @vertices = (UnityEngine.Vector3[]) typeof(UnityEngine.Vector3[]).CheckCLRTypes(StackObject.ToObject(ptr_of_this_method, __domain, __mStack));
            __intp.Free(ptr_of_this_method);


            var result_of_this_method = UnityEngine.GeometryUtility.TryCreatePlaneFromPolygon(@vertices, out @plane);

            ptr_of_this_method = ILIntepreter.Minus(__esp, 1);
            switch (ptr_of_this_method->ObjectType)
            {
            case ObjectTypes.StackObjectReference:
            {
                var    ___dst = *(StackObject **)&ptr_of_this_method->Value;
                object ___obj = plane;
                if (___dst->ObjectType >= ObjectTypes.Object)
                {
                    if (___obj is CrossBindingAdaptorType)
                    {
                        ___obj = ((CrossBindingAdaptorType)___obj).ILInstance;
                    }
                    __mStack[___dst->Value] = ___obj;
                }
                else
                {
                    ILIntepreter.UnboxObject(___dst, ___obj, __mStack, __domain);
                }
            }
            break;

            case ObjectTypes.FieldReference:
            {
                var ___obj = __mStack[ptr_of_this_method->Value];
                if (___obj is ILTypeInstance)
                {
                    ((ILTypeInstance)___obj)[ptr_of_this_method->ValueLow] = plane;
                }
                else
                {
                    var ___type = __domain.GetType(___obj.GetType()) as CLRType;
                    ___type.SetFieldValue(ptr_of_this_method->ValueLow, ref ___obj, plane);
                }
            }
            break;

            case ObjectTypes.StaticFieldReference:
            {
                var ___type = __domain.GetType(ptr_of_this_method->Value);
                if (___type is ILType)
                {
                    ((ILType)___type).StaticInstance[ptr_of_this_method->ValueLow] = plane;
                }
                else
                {
                    ((CLRType)___type).SetStaticFieldValue(ptr_of_this_method->ValueLow, plane);
                }
            }
            break;

            case ObjectTypes.ArrayReference:
            {
                var instance_of_arrayReference = __mStack[ptr_of_this_method->Value] as UnityEngine.Plane[];
                instance_of_arrayReference[ptr_of_this_method->ValueLow] = plane;
            }
            break;
            }

            __ret->ObjectType = ObjectTypes.Integer;
            __ret->Value      = result_of_this_method ? 1 : 0;
            return(__ret + 1);
        }
Beispiel #24
0
        static void CreateExtrudedSubMesh(CSGBrushSubMesh subMesh, Vector3[] sideVertices, Vector3 extrusion, int[] segmentDescriptionIndices, int[] segmentAssetIndices, CSGSurfaceAsset[] surfaceAssets, SurfaceDescription[] surfaceDescriptions)
        {
            const float distanceEpsilon = 0.0000001f;

            for (int i = sideVertices.Length - 1; i >= 0; i--)
            {
                var j         = (i - 1 + sideVertices.Length) % sideVertices.Length;
                var magnitude = (sideVertices[j] - sideVertices[i]).sqrMagnitude;
                if (magnitude < distanceEpsilon)
                {
                    // TODO: improve on this
                    var tmp = sideVertices.ToList();
                    tmp.RemoveAt(i);
                    sideVertices = tmp.ToArray();
                }
            }

            var segments        = sideVertices.Length;
            var isSegmentConvex = new sbyte[segments];
            var edgeIndices     = new int[segments * 2];
            var vertices        = new Vector3[segments * 2];

            var polygonCount = 2;
            var edgeOffset   = segments + segments;

            for (int p = segments - 2, e = segments - 1, n = 0; n < segments; p = e, e = n, n++)
            {
                //			      t0
                //	 ------>   ------->   ----->
                //        v0 *          * v1
                //	 <-----    <-------   <-----
                //			^ |   e2   ^ |
                //          | |        | |
                //	   q1 p0| |e3 q2 e5| |n0 q3
                //          | |        | |
                //			| v   e4   | v
                //	 ------>   ------->   ----->
                //        v3 *          * v2
                //	 <-----    <-------   <-----
                //			      b0
                //

                var v0 = sideVertices[p];
                var v1 = sideVertices[e];
                var v2 = sideVertices[e] + extrusion;
                var v3 = sideVertices[p] + extrusion;

                vertices[p]            = v0;
                vertices[e]            = v1;
                vertices[e + segments] = v2;
                vertices[p + segments] = v3;

                var plane = new Plane(v0, v1, v3);
                var dist  = plane.GetDistanceToPoint(v2);

                if (UnityEngine.Mathf.Abs(dist) < 0.001f)
                {
                    isSegmentConvex[n] = 0;
                }
                else
                {
                    isSegmentConvex[n] = (sbyte)UnityEngine.Mathf.Sign(dist);
                }

                edgeIndices[(n * 2) + 0] = edgeOffset + 1;

                if (isSegmentConvex[n] == 0)
                {
                    polygonCount++;
                    edgeOffset += 4;
                }
                else
                {
                    polygonCount += 2;
                    edgeOffset   += 6;
                }
                edgeIndices[(n * 2) + 1] = edgeOffset - 1;
            }

            var polygons = new CSGBrushSubMesh.Polygon[polygonCount];

            var descriptionIndex0   = (segmentDescriptionIndices == null) ? 0 : (segmentDescriptionIndices[0]);
            var descriptionIndex1   = (segmentDescriptionIndices == null) ? 1 : (segmentDescriptionIndices[1]);
            var assetIndex0         = (segmentAssetIndices == null) ? 0 : (segmentAssetIndices[0]);
            var assetIndex1         = (segmentAssetIndices == null) ? 1 : (segmentAssetIndices[1]);
            var surfaceDescription0 = surfaceDescriptions[descriptionIndex0];
            var surfaceDescription1 = surfaceDescriptions[descriptionIndex1];
            var surfaceAsset0       = surfaceAssets[assetIndex0];
            var surfaceAsset1       = surfaceAssets[assetIndex1];

            polygons[0] = new CSGBrushSubMesh.Polygon {
                surfaceID = 0, firstEdge = 0, edgeCount = segments, description = surfaceDescription0, surfaceAsset = surfaceAsset0
            };
            polygons[1] = new CSGBrushSubMesh.Polygon {
                surfaceID = 1, firstEdge = segments, edgeCount = segments, description = surfaceDescription1, surfaceAsset = surfaceAsset1
            };

            for (int s = 0, surfaceID = 2; s < segments; s++)
            {
                var descriptionIndex = (segmentDescriptionIndices == null) ? s + 2 : (segmentDescriptionIndices[s + 2]);
                var assetIndex       = (segmentAssetIndices == null) ? 2     : (segmentAssetIndices[s + 2]);
                var firstEdge        = edgeIndices[(s * 2) + 0] - 1;
                if (isSegmentConvex[s] == 0)
                {
                    polygons[surfaceID] = new CSGBrushSubMesh.Polygon {
                        surfaceID = surfaceID, firstEdge = firstEdge, edgeCount = 4, description = surfaceDescriptions[descriptionIndex], surfaceAsset = surfaceAssets[assetIndex]
                    };
                    polygons[surfaceID].description.smoothingGroup = (uint)0;
                    surfaceID++;
                }
                else
                {
                    var smoothingGroup = surfaceID + 1; // TODO: create an unique smoothing group for faceted surfaces that are split in two,
                                                        //			unless there's already a smoothing group for this edge; then use that

                    polygons[surfaceID + 0] = new CSGBrushSubMesh.Polygon {
                        surfaceID = surfaceID + 0, firstEdge = firstEdge, edgeCount = 3, description = surfaceDescriptions[descriptionIndex], surfaceAsset = surfaceAssets[assetIndex]
                    };
                    polygons[surfaceID + 0].description.smoothingGroup = (uint)smoothingGroup;
                    polygons[surfaceID + 1] = new CSGBrushSubMesh.Polygon {
                        surfaceID = surfaceID + 1, firstEdge = firstEdge + 3, edgeCount = 3, description = surfaceDescriptions[descriptionIndex], surfaceAsset = surfaceAssets[assetIndex]
                    };
                    polygons[surfaceID + 1].description.smoothingGroup = (uint)smoothingGroup;
                    surfaceID += 2;
                }
            }

            var halfEdges = new BrushMesh.HalfEdge[edgeOffset];

            for (int p = segments - 2, e = segments - 1, n = 0; n < segments; p = e, e = n, n++)
            {
                var vi1 = e;
                var vi3 = p + segments;

                var t0 = e;
                var b0 = ((segments - 1) - e) + segments;

                halfEdges[t0] = new BrushMesh.HalfEdge {
                    vertexIndex = vi1, twinIndex = -1
                };
                halfEdges[b0] = new BrushMesh.HalfEdge {
                    vertexIndex = vi3, twinIndex = -1
                };
            }

            for (int p = segments - 2, e = segments - 1, n = 0; n < segments; p = e, e = n, n++)
            {
                var vi0 = p;
                var vi1 = e;
                var vi2 = e + segments;
                var vi3 = p + segments;

                var t0 = e;
                var b0 = ((segments - 1) - e) + segments;

                var p0 = edgeIndices[(p * 2) + 1];
                var n0 = edgeIndices[(n * 2) + 0];

                if (isSegmentConvex[e] == 0)
                {
                    //			      t0
                    //	 ------>   ------->   ----->
                    //        v0 *          * v1
                    //	 <-----    <-------   <-----
                    //			^ |   e2   ^ |
                    //          | |        | |
                    //	   q1 p0| |e3 q2 e5| |n0 q3
                    //          | |        | |
                    //			| v   e4   | v
                    //	 ------>   ------->   ----->
                    //        v3 *          * v2
                    //	 <-----    <-------   <-----
                    //			      b0
                    //

                    var q2 = edgeIndices[(e * 2) + 0];
                    var e2 = q2 - 1;
                    var e3 = q2 + 0;
                    var e4 = q2 + 1;
                    var e5 = q2 + 2;

                    halfEdges[t0].twinIndex = e2;
                    halfEdges[b0].twinIndex = e4;

                    halfEdges[e2] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = t0
                    };
                    halfEdges[e3] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = p0
                    };

                    halfEdges[e4] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };
                    halfEdges[e5] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = n0
                    };
                }
                else
                if (isSegmentConvex[e] == -1)
                {
                    //			        t0
                    //	 ------>   ----------->   ----->
                    //        v0 *              * v1
                    //	 <-----    <-----------   <-----
                    //			^ |     e2   ^ ^ |
                    //          | |        / / | |
                    //          | |    e4/ /   | |
                    //	   q1 p0| |e3   / /  e7| |n0 q3
                    //          | |   / /e5    | |
                    //          | | / /        | |
                    //			| v/v   e6     | v
                    //	 ------>   ----------->   ----->
                    //        v3 *              * v2
                    //	 <-----    <-----------   <-----
                    //			        b0
                    //

                    var q2 = edgeIndices[(e * 2) + 0];
                    var e2 = q2 - 1;
                    var e3 = q2 + 0;
                    var e4 = q2 + 1;
                    var e5 = q2 + 2;
                    var e6 = q2 + 3;
                    var e7 = q2 + 4;

                    halfEdges[t0].twinIndex = e2;
                    halfEdges[b0].twinIndex = e6;

                    halfEdges[e2] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = t0
                    };
                    halfEdges[e3] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = p0
                    };
                    halfEdges[e4] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = e5
                    };

                    halfEdges[e5] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = e4
                    };
                    halfEdges[e6] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };
                    halfEdges[e7] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = n0
                    };
                }
                else
                if (isSegmentConvex[e] == 1)
                {
                    //			        t0
                    //	 ------>   ----------->   ----->
                    //        v0 *              * v1
                    //	 <-----    <-----------   <-----
                    //			^ |^\   e5     ^ |
                    //          | | \ \        | |
                    //          | |   \ \ e6   | |
                    //	   q1 p0| |e3 e2\ \  e7| |n0 q3
                    //          | |       \ \  | |
                    //          | |        \ \ | |
                    //			| v   e4    \ v| v
                    //	 ------>   ----------->   ----->
                    //        v3 *              * v2
                    //	 <-----    <-----------   <-----
                    //			        b0
                    //

                    var q2 = edgeIndices[(e * 2) + 0];
                    var e2 = q2 - 1;
                    var e3 = q2 + 0;
                    var e4 = q2 + 1;
                    var e5 = q2 + 2;
                    var e6 = q2 + 3;
                    var e7 = q2 + 4;

                    halfEdges[t0].twinIndex = e5;
                    halfEdges[b0].twinIndex = e4;

                    halfEdges[e2] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = e6
                    };
                    halfEdges[e3] = new BrushMesh.HalfEdge {
                        vertexIndex = vi3, twinIndex = p0
                    };
                    halfEdges[e4] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = b0
                    };

                    halfEdges[e5] = new BrushMesh.HalfEdge {
                        vertexIndex = vi0, twinIndex = t0
                    };
                    halfEdges[e6] = new BrushMesh.HalfEdge {
                        vertexIndex = vi2, twinIndex = e2
                    };
                    halfEdges[e7] = new BrushMesh.HalfEdge {
                        vertexIndex = vi1, twinIndex = n0
                    };
                }
            }

            subMesh.Polygons  = polygons;
            subMesh.HalfEdges = halfEdges;
            subMesh.Vertices  = vertices;
            subMesh.CreateOrUpdateBrushMesh();
        }
 public static extern void obb_face_plane(
     [In][Out] OrientedBoundingBox box,
     int index, out Plane plane
     );