Пример #1
0
    static public bool RayVsSceneMaterial(Ray r, out APARaycastHit hit, out MaterialStruct material)
    {
        hit      = null;
        material = null;

        if (APARaycast.Raycast(r, out hit))
        {
            Debug.Log("Hit " + hit.transform.gameObject.name);

            // Find The Material
            var     go         = hit.transform.gameObject;
            var     goMat      = go.GetComponent <Renderer>().material;
            var     matMainTex = goMat.mainTexture as Texture2D;
            Vector2 pixelUv    = hit.textureCoord;
            pixelUv.x *= matMainTex.width;
            pixelUv.y *= matMainTex.height;

            var pixelColour = matMainTex.GetPixel((int)pixelUv.x, (int)pixelUv.y);
            material = FindMaterialStructFromColour(pixelColour);

            return(true);
        }
        else
        {
            // Debug.Log("Miss! " + APARaycast.intersectionErrorType);

            return(false);
        }
    }
    public void GameReaction(Vector3 hitWsPosition, Vector3 hitWsNormal, MaterialStruct mat)
    {
        Color  finalMaterialColour;
        string finalMaterialName = "";

        hitWsPosition = hitWsPosition + (hitWsNormal * 0.01f);

        if (mat != null)
        {
            // We know the material...so...
            finalMaterialName   = mat.m_name;
            finalMaterialColour = mat.m_colour;
        }
        else
        {
            finalMaterialName   = "Error";
            finalMaterialColour = m_errorColour;
        }

        m_uiMaterialColourOutput.color = finalMaterialColour;
        m_uiMaterialTextOutput.text    = finalMaterialName;

        int matIndex = mat == null ? 0 : mat.m_index;

        lastHitPos = hitWsPosition;

        // Grab Weapon Struct
        int weaponIndex  = 0;
        var weaponStruct = m_weaponDataCopy[weaponIndex];

        // we are in throwing mode
        if (!m_useShotgunWeapon)
        {
            // only do collision reaction for glass, as likely thing to break
            if (finalMaterialName != "glass")
            {
                return;
            }
        }

        // Spawn Particle Effects
        {
            // note: uses material index to go into array
            var newParticle = Instantiate(weaponStruct.m_hitParticlePrefabs[matIndex]) as GameObject;
            newParticle.transform.SetParent(particleParent, false);

            // Orientate to normal
            newParticle.transform.SetPositionAndRotation(hitWsPosition, Quaternion.LookRotation(hitWsNormal, Vector3.up));
        }

        // Spawn Decal Effects
        {
            // note: uses material index to go into array
            var newDecal = Instantiate(weaponStruct.m_hitDecalPrefabs[matIndex]) as GameObject;
            newDecal.transform.SetParent(decalParent, false);

            // Orientate to normal
            newDecal.transform.SetPositionAndRotation(hitWsPosition, Quaternion.LookRotation(-hitWsNormal, Vector3.up));
        }
    }
Пример #3
0
        public static string ToJson(Material material, Model parentModel = null)
        {
            MaterialStruct matConv = new MaterialStruct();

            matConv.Name           = material.Name;
            matConv.ShaderAssign   = ConvertShaderAssign(material.ShaderAssign);
            matConv.Visible        = material.Flags.HasFlag(MaterialFlags.Visible);
            matConv.PresetMetaInfo = new UserMetaInfo();
            if (material.RenderState != null)
            {
                matConv.RenderState = material.RenderState;
            }

            matConv.VolatileFlags = material.VolatileFlags;
            matConv.Textures      = new List <string>();
            foreach (var tex in material.TextureRefs)
            {
                matConv.Textures.Add(tex.Name);
            }
            matConv.Samplers = material.Samplers.Values.ToList();

            foreach (var param in material.ShaderParams.Values)
            {
                matConv.Parameters.Add($"{param.Type}|{param.Name}", param.DataValue);
            }

            foreach (var param in material.RenderInfos.Values)
            {
                matConv.RenderInfo.Add($"{param.Type}|{param.Name}", param.Data);
            }

            foreach (var param in material.UserData.Values)
            {
                matConv.UserData.Add($"{param.Type}|{param.Name}", param.GetData());
            }

            //It is important that we attach mesh information to the material
            //Shaders rely on both mesh and material data to match up nicely
            //This includes skin counts and vertex layouts
            if (parentModel != null)
            {
                foreach (var shape in parentModel.Shapes.Values)
                {
                    if (parentModel.Materials[shape.MaterialIndex] == material)
                    {
                        matConv.MeshInfo.Add(CreateMeshInfo(shape, shape.VertexBuffer));
                    }
                }
            }

            JsonConvert.DefaultSettings = () =>
            {
                var settings = new JsonSerializerSettings();
                return(settings);
            };

            return(JsonConvert.SerializeObject(matConv, Formatting.Indented));
        }
Пример #4
0
        public static string ToJson(Material material)
        {
            MaterialStruct matConv = new MaterialStruct();

            matConv.Name           = material.Name;
            matConv.ShaderAssign   = ConvertShaderAssign(material.ShaderAssign);
            matConv.Visible        = material.Flags.HasFlag(MaterialFlags.Visible);
            matConv.PresetMetaInfo = new UserMetaInfo();
            if (material.RenderState != null)
            {
                matConv.RenderState = material.RenderState;
            }

            matConv.VolatileFlags = material.VolatileFlags;
            matConv.Textures      = new List <string>();
            foreach (var tex in material.TextureRefs)
            {
                matConv.Textures.Add(tex.Name);
            }
            matConv.Samplers = material.Samplers.Values.ToList();

            foreach (var param in material.ShaderParams.Values)
            {
                matConv.Parameters.Add($"{param.Type}|{param.Name}", param.DataValue);
            }

            foreach (var param in material.RenderInfos.Values)
            {
                matConv.RenderInfo.Add($"{param.Type}|{param.Name}", param.Data);
            }

            foreach (var param in material.UserData.Values)
            {
                matConv.UserData.Add($"{param.Type}|{param.Name}", param.GetData());
            }

            JsonConvert.DefaultSettings = () =>
            {
                var settings = new JsonSerializerSettings();
                return(settings);
            };

            return(JsonConvert.SerializeObject(matConv, Formatting.Indented));
        }
Пример #5
0
        private Image GetThumbnail(MaterialStruct material)
        {
            Material mat       = MaterialsManager.LookupMaterialByHash(material.MaterialHash);
            Image    thumbnail = null;

            if (mat != null)
            {
                if (mat.Samplers.ContainsKey("S000"))
                {
                    thumbnail = LoadDDSSquish(Path.Combine(SceneData.ScenePath, mat.Samplers["S000"].File));
                }
                else
                {
                    thumbnail = LoadDDSSquish("Resources/texture.dds");
                }
            }
            else
            {
                thumbnail = LoadDDSSquish("Resources/MissingMaterial.dds");
            }
            return(thumbnail);
        }
Пример #6
0
    private void LoadMaterialData()
    {
        var materialDataParse = JSON.ParseFile("material_definitions");
        var materialDataArray = materialDataParse["MATERIAL_DEFINITIONS"].AsArray;
        var materialDataCount = materialDataArray.Count;

        m_materialData = new MaterialStruct[materialDataCount];

        for (int i = 0; i < materialDataCount; i++)
        {
            var thisMaterial = materialDataArray[i];

            string name          = thisMaterial["NAME"];
            string colHex        = thisMaterial["HEX_COL"];
            int    breakOnImpact = thisMaterial["BREAK_ON_IMPACT"].AsInt;

            Color  col = HexUtility.hexToColor(colHex);
            string hexColUnityFormat = HexUtility.colorToHex(col);

            //Debug.Log(name + hexColUnityFormat);

            m_materialData[i] = new MaterialStruct(name, hexColUnityFormat, breakOnImpact, col, i);
        }
    }
    // Has to be OnPostRender so we can grab render targets safely
    private void OnPostRender()
    {
        if (m_lastWidth != Screen.width || m_lastHeight != Screen.height)
        {
            OnResize();
        }

        if (m_rayCastTriggered)
        {
            m_rayCastTriggered = false;
            var zDepth = m_textureOverlay.depthXYZZed;

            // Store current RT
            RenderTexture currentRT = RenderTexture.active;

            // Create new render target to copy
            {
                RenderTexture.active = m_zedRT;

                Graphics.Blit(zDepth, m_zedRT);

                Texture2D zedReadable = new Texture2D(zDepth.width, zDepth.height, zDepth.format, false);
                zedReadable.ReadPixels(new Rect(0, 0, m_zedRT.width, m_zedRT.height), 0, 0);
                zedReadable.Apply();

                Vector2 relMousePos = new Vector2();

                relMousePos.x = m_mousePositionWhenTriggered.x / Screen.width;
                relMousePos.y = m_mousePositionWhenTriggered.y / Screen.height;

                Vector2 dPixUv = relMousePos;

                dPixUv.y = 1.0f - dPixUv.y;

                dPixUv.x *= zedReadable.width;
                dPixUv.y *= zedReadable.height;

                // this only works for starting camera position and rotation
                var            depthPixelData = zedReadable.GetPixel((int)dPixUv.x, (int)dPixUv.y);
                var            matPixelData   = new Color(0, 0, 0, 0);
                MaterialStruct matFound       = null;

                if (m_materialColourTexture != null)
                {
                    Vector2 mPixUv = relMousePos;
                    mPixUv.y = 1.0f - mPixUv.y;

                    mPixUv.x *= m_materialColourTexture.width;
                    mPixUv.y *= m_materialColourTexture.height;

                    matPixelData = m_materialColourTexture.GetPixel((int)mPixUv.x, (int)mPixUv.y);

                    matFound = MaterialRayCastSystem.FindMaterialStructFromColour(matPixelData);
                }

                // Need to guard against uninit areas of pixels
                // This can happen if camera hasn't been able to do depth properly in area

                if (
                    float.IsNaN(depthPixelData.r) ||
                    float.IsInfinity(depthPixelData.r) ||
                    float.IsNaN(depthPixelData.g) ||
                    float.IsInfinity(depthPixelData.g) ||
                    float.IsNaN(depthPixelData.b) ||
                    float.IsInfinity(depthPixelData.b)
                    )
                {
                    return;
                }

                // If changed process of getting this position, then remember to udpate for loop at bottom
                Vector3 cVsPos = new Vector3(depthPixelData.r, depthPixelData.g, -depthPixelData.b);

                // get back into object space
                Matrix4x4 inverseView = m_zedCamera.worldToCameraMatrix.inverse;

                Vector3 cWsPos = inverseView * new Vector4(cVsPos.x, cVsPos.y, cVsPos.z, 1.0f);

                // Now we need to find the normal....
                {
                    // https://stackoverflow.com/questions/37627254/how-to-reconstruct-normal-from-depth-without-artifacts-on-edge
                    //     [ ]
                    // [ ] [x] [ ]
                    //     [ ]

                    // 4 samples around edge
                    // find the closest sample top and bottom, left and right relative to center sample
                    // then normalise cross product on it? (x dir, y dir)

                    Vector2[] offsets = new Vector2[4]
                    {
                        new Vector2(0, 15),
                        new Vector2(0, -15),
                        new Vector2(15, 0),
                        new Vector2(-15, 0)
                    };

                    Vector3[] wsPositions  = new Vector3[4];
                    float[]   distToCenter = new float[4];

                    for (int i = 0; i < 4; i++)
                    {
                        Vector2 uvOffset = dPixUv + offsets[i];
                        Color   sample   = zedReadable.GetPixel((int)uvOffset.x, (int)uvOffset.y);
                        Vector4 vsPos    = new Vector4(sample.r, sample.g, -sample.b, 1.0f);

                        // Calculate WS POS
                        Vector3 sampleWsPos = inverseView * vsPos;

                        distToCenter[i] = Vector3.Distance(cWsPos, sampleWsPos);

                        wsPositions[i] = sampleWsPos;
                    }

                    int verticalSampleIndex   = 0;
                    int horizontalSampleIndex = 2;

                    // Find closest vertical sample
                    if (distToCenter[0] > distToCenter[1])
                    {
                        verticalSampleIndex = 1;
                    }

                    // Find closest horizontal sample
                    if (distToCenter[2] > distToCenter[3])
                    {
                        horizontalSampleIndex = 3;
                    }

                    Vector3 normalGen = Vector3.Cross(wsPositions[verticalSampleIndex] - cWsPos, wsPositions[horizontalSampleIndex] - cWsPos);
                    normalGen.Normalize();

                    // Update Game Reaction
                    m_gameController.GameReaction(cWsPos, normalGen, matFound);
                }
            }

            // Restore original active render texture
            RenderTexture.active = currentRT;
        }
    }