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)); } }
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)); }
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)); }
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); }
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; } }