Triangle2D.IsPointInside C# (CSharp) Method

IsPointInside() public method

public IsPointInside ( Vector2D, pt ) : bool
pt Vector2D,
return bool
    public bool IsPointInside(Vector2D pt)
    {
        Vector2D v1 = points [0];
        Vector2D v2 = points [1];
        Vector2D v3 = points [2];
        bool b1, b2, b3;

        b1 = sign(pt, v1, v2) < 0.0f;
        b2 = sign(pt, v2, v3) < 0.0f;
        b3 = sign(pt, v3, v1) < 0.0f;

        return ((b1 == b2) && (b2 == b3));
    }

Usage Example

コード例 #1
0
    private const float spotFalloff = 2.5f; ///<The outer range where spot light begins to falloff

    void OnWizardCreate()
    {
        //Find all lights
        Light[] lights = Object.FindObjectsOfType(typeof(Light)) as Light[];

        //Find all renderers with a lightmap that should be lightmapped and all lightmaps that will be used (This is primarily done to show the progress bar)
        List <Renderer>  models    = new List <Renderer>();  //List of all renderers with a lightmap
        List <Texture2D> lightmaps = new List <Texture2D>(); //List of all lightmaps that will be used

        foreach (Renderer renderer in Object.FindObjectsOfType(typeof(Renderer)))
        {
            if (renderer.sharedMaterial.HasProperty("_LightMap"))
            {
                if ((lightmapMode == LightmapMode.ALL) ||
                    (lightmapMode == LightmapMode.SELECTION && Selected(renderer.transform)) ||
                    (lightmapMode == LightmapMode.SELECTION_OR_CHILD && SelectedOrChild(renderer.transform))
                    )
                {
                    Texture2D lightmap = renderer.sharedMaterial.GetTexture("_LightMap") as Texture2D;

                    if (lightmap)
                    {
                        models.Add(renderer);

                        if (!lightmaps.Contains(lightmap))
                        {
                            lightmaps.Add(lightmap);
                        }
                    }
                }
            }
        }

        //This is just for the progressbar
        int totalSteps  = lightmaps.Count + models.Count + lightmaps.Count; //Clear + Lightmap + Smoothing
        int currentStep = 0;

        //Clear all lightmaps
        for (int lightmapIndex = 0; lightmapIndex < lightmaps.Count; lightmapIndex++)
        {
            Texture2D lightmap = lightmaps[lightmapIndex];

            EditorUtility.DisplayProgressBar(
                "Lightmapping",
                string.Format("Clearing lightmaps: {0} ({1} of {2})", lightmap.name, lightmapIndex + 1, lightmaps.Count),
                currentStep++ / (float)totalSteps
                );

            lightmap.SetPixels(new Color[lightmap.width * lightmap.height]); //Set the lightmap to all black
        }

        for (int rendererIndex = 0; rendererIndex < models.Count; rendererIndex++)
        {
            Renderer renderer = models[rendererIndex];

            EditorUtility.DisplayProgressBar(
                "Lightmapping",
                string.Format("Calculating Light: {0} ({1} of {2})", renderer.name, rendererIndex + 1, models.Count),
                currentStep++ / (float)totalSteps
                );

            Mesh      mesh     = ((MeshFilter)renderer.GetComponent(typeof(MeshFilter))).sharedMesh;
            Texture2D lightmap = renderer.sharedMaterial.GetTexture("_LightMap") as Texture2D;
            Texture2D mainTex  = renderer.sharedMaterial.mainTexture as Texture2D; //For alpha lookup

            if (lightmap.format == TextureFormat.Alpha8 || lightmap.format == TextureFormat.ARGB32 || lightmap.format == TextureFormat.RGB24)
            {
                int[]     triangles = mesh.triangles;
                Vector3[] vertices  = mesh.vertices;
                Vector3[] normals   = mesh.normals;
                Vector2[] mainUV    = mesh.uv; //Used for alphaLookup
                Vector2[] lightUV   = mesh.uv2.Length > 0 ? mesh.uv2 : mesh.uv;

                //Transform vertices and normals to global coords
                Transform t = renderer.transform;
                for (int vert = 0; vert < vertices.Length; vert++)
                {
                    vertices[vert] = t.TransformPoint(vertices[vert]);
                }
                for (int normal = 0; normal < normals.Length; normal++)
                {
                    normals[normal] = t.TransformDirection(normals[normal]);
                }

                for (int i = 0; i < triangles.Length; i += 3)
                {
                    //Vertice indexs
                    int vi0 = triangles[i];
                    int vi1 = triangles[i + 1];
                    int vi2 = triangles[i + 2];

                    //Lightmap UV coords [pixel]
                    Vector2 pUV0 = new Vector2(lightUV[vi0].x * lightmap.width, lightUV[vi0].y * lightmap.height);
                    Vector2 pUV1 = new Vector2(lightUV[vi1].x * lightmap.width, lightUV[vi1].y * lightmap.height);
                    Vector2 pUV2 = new Vector2(lightUV[vi2].x * lightmap.width, lightUV[vi2].y * lightmap.height);

                    Triangle2D pUVTriangle = new Triangle2D(pUV0, pUV1, pUV2);

                    //mainTex UV coords [pixel]. These are only used (and computed) if alphaLookup is true (AND there is a mainTex)
                    Vector2 pMainUV0 = alphaLookup && mainTex ? new Vector2(mainUV[vi0].x * mainTex.width, mainUV[vi0].y * mainTex.height) : Vector2.zero;
                    Vector2 pMainUV1 = alphaLookup && mainTex ? new Vector2(mainUV[vi1].x * mainTex.width, mainUV[vi1].y * mainTex.height) : Vector2.zero;
                    Vector2 pMainUV2 = alphaLookup && mainTex ? new Vector2(mainUV[vi2].x * mainTex.width, mainUV[vi2].y * mainTex.height) : Vector2.zero;

                    //Square of pixels around triangle
                    Vector4 bounds = new Vector4(
                        Mathf.Floor(Mathf.Min(Mathf.Min(pUV0.x, pUV1.x), pUV2.x)),
                        Mathf.Ceil(Mathf.Max(Mathf.Max(pUV0.x, pUV1.x), pUV2.x)),
                        Mathf.Floor(Mathf.Min(Mathf.Min(pUV0.y, pUV1.y), pUV2.y)),
                        Mathf.Ceil(Mathf.Max(Mathf.Max(pUV0.y, pUV1.y), pUV2.y))
                        );

                    for (float x = bounds.x; x < bounds.y; x++)
                    {
                        for (float y = bounds.z; y < bounds.w; y++)
                        {
                            Vector2 texel = new Vector2(x + 0.5f, y + 0.5f); //Use the middel of the texel

                            //Check if the texel is inside the triangle
                            if (pUVTriangle.IsPointInside(texel))
                            {
                                Vector3 bCoords = pUVTriangle.PointToBaryCentric(texel);

                                Vector3 worldPosition = vertices[vi0] * bCoords.x + vertices[vi1] * bCoords.y + vertices[vi2] * bCoords.z;
                                Vector3 worldNormal   = normals[vi0] * bCoords.x + normals[vi1] * bCoords.y + normals[vi2] * bCoords.z;
                                Vector3 raycastOffset = worldNormal.normalized * 0.0001f; ///Vector added to worldposition when raycasting so that objects hit themself more consistently

                                Color texelColor = lightmap.GetPixel((int)x, (int)y);

                                //The modifier based on the surfaces alpha
                                float alpha = 1;
                                if (alphaLookup)
                                {
                                    if (mainTex && (mainTex.format == TextureFormat.Alpha8 || mainTex.format == TextureFormat.ARGB32))
                                    {
                                        Vector2 mainTexel = bCoords.x * pMainUV0 + bCoords.y * pMainUV1 + bCoords.z * pMainUV2;

                                        alpha = mainTex.GetPixel((int)mainTexel.x, (int)mainTexel.y).a;
                                    }
                                }

                                foreach (Light light in lights)
                                {
                                    Transform lightTransform = light.transform;
                                    float     alphaMod       = alpha;

                                    //POINT LIGHT
                                    if (light.type == LightType.Point)
                                    {
                                        Vector3 toLight         = lightTransform.position - worldPosition;
                                        float   distanceToLight = toLight.magnitude;

                                        if (light.range > distanceToLight && !Obstructed(worldPosition + raycastOffset, toLight, distanceToLight, ref alphaMod))
                                        {
                                            float angleMod       = AngleMod(toLight, worldNormal);
                                            float attenuationMod = 2 * Mathf.Pow(Mathf.Exp(-distanceToLight / light.range), 5);

                                            texelColor += light.color * light.intensity * angleMod * attenuationMod * alphaMod;
                                        }
                                    }
                                    //SPOT LIGHT
                                    else if (light.type == LightType.Spot)
                                    {
                                        Vector3 toLight         = lightTransform.position - worldPosition;
                                        float   distanceToLight = toLight.magnitude;

                                        float angleToSpot = Vector3.Angle(-toLight, lightTransform.forward);

                                        if (angleToSpot < light.spotAngle / 2)
                                        {
                                            float projectedDistance = Mathf.Cos(angleToSpot * Mathf.Deg2Rad) * distanceToLight; //Distance to light (projected onto light.forward)

                                            if (light.range > projectedDistance && !Obstructed(worldPosition + raycastOffset, toLight, distanceToLight, ref alphaMod))
                                            {
                                                //Edge falloff
                                                float edgeMod = (spotFalloff - Mathf.Max(angleToSpot - ((light.spotAngle / 2) - spotFalloff), 0)) / spotFalloff;

                                                float angleMod       = AngleMod(toLight, worldNormal);
                                                float attenuationMod = Mathf.Max(1 - Mathf.Pow(projectedDistance / light.range, 3), 0);

                                                texelColor += light.color * light.intensity * edgeMod * angleMod * attenuationMod * alphaMod;
                                            }
                                        }
                                    }
                                    //DIRECTIONAL
                                    else if (light.type == LightType.Directional)
                                    {
                                        if (Vector3.Angle(lightTransform.forward, worldNormal) > 90)
                                        {
                                            if (noDirectionalShadow || !Obstructed(worldPosition + raycastOffset, -lightTransform.forward, Mathf.Infinity, ref alphaMod))
                                            {
                                                float angleMod = AngleMod(-lightTransform.forward, worldNormal);

                                                texelColor += light.color * light.intensity * angleMod * alphaMod;
                                            }
                                        }
                                    }
                                } //END foreach light

                                lightmap.SetPixel((int)x, (int)y, texelColor);
                            }
                        }
                    }
                }
            } //END if (format)
            else
            {
                Debug.LogError(string.Format("Unsupported format of lightmap in object {0}", renderer.name));
            }
        } //END foreach (renderer)

        //Smooth and save lightmaps
        for (int lightmapIndex = 0; lightmapIndex < lightmaps.Count; lightmapIndex++)
        {
            Texture2D lightmap = lightmaps[lightmapIndex];

            EditorUtility.DisplayProgressBar(
                "Lightmapping",
                string.Format("Smoothing: {0} ({1} of {2})", lightmap.name, lightmapIndex + 1, lightmaps.Count),
                currentStep++ / (float)totalSteps
                );

            SmoothLightMaps(lightmap);

            lightmap.Apply();

            //Save to disk
            if (saveLightMaps)
            {
                File.WriteAllBytes(EditorUtility.GetAssetPath(lightmap), lightmap.EncodeToPNG());
            }
        }

        EditorUtility.ClearProgressBar();
    }