private void CreateShadowVolume(ABakingTask completeBakingTask) { Transform root = GetRoot(); Material debugMtrl = GetDebugMaterial(); ShadowVolumeObject svObj = FindShadowVolumeObject(completeBakingTask.Transform.gameObject); if (svObj == null) { GameObject newMeshGo = new GameObject("_$SV " + completeBakingTask.Transform.gameObject.name + "$_"); newMeshGo.transform.parent = root; newMeshGo.transform.localScale = completeBakingTask.Transform.lossyScale; newMeshGo.transform.localEulerAngles = completeBakingTask.Transform.eulerAngles; newMeshGo.transform.localPosition = completeBakingTask.Transform.position; MeshFilter mf = newMeshGo.AddComponent <MeshFilter>(); mf.sharedMesh = completeBakingTask.GetNewMesh(); MeshRenderer mr = newMeshGo.AddComponent <MeshRenderer>(); mr.sharedMaterial = debugMtrl; mr.enabled = false; svObj = newMeshGo.AddComponent <ShadowVolumeObject>(); svObj.source = completeBakingTask.Transform.gameObject; svObj.sourceMeshRenderer = completeBakingTask.Transform.GetComponent <MeshRenderer>(); svObj.sourceMeshFilter = completeBakingTask.Transform.GetComponent <MeshFilter>(); svObj.meshFilter = mf; svObj.l2w = mf.transform.localToWorldMatrix; svObj.wPos = mf.transform.position; } else { svObj.transform.parent = root; svObj.transform.localScale = completeBakingTask.Transform.lossyScale; svObj.transform.localEulerAngles = completeBakingTask.Transform.eulerAngles; svObj.transform.localPosition = completeBakingTask.Transform.position; svObj.l2w = svObj.meshFilter.transform.localToWorldMatrix; svObj.wPos = svObj.meshFilter.transform.position; MeshFilter mf = svObj.gameObject.GetComponent <MeshFilter>(); if (mf == null) { mf = svObj.gameObject.AddComponent <MeshFilter>(); } mf.sharedMesh = completeBakingTask.GetNewMesh(); MeshRenderer mr = svObj.gameObject.GetComponent <MeshRenderer>(); if (mr == null) { mr = svObj.gameObject.AddComponent <MeshRenderer>(); } mr.sharedMaterial = debugMtrl; mr.enabled = false; } }
private bool IsShadowVolulmeObjectVisible(ShadowVolumeObject svo, bool isShadowDistanceEnabled, ref Vector3 camWPos, ref Vector3 camWForward) { bool visible = svo.IsVisible(); if (isShadowDistanceEnabled) { float dist = Vector3.Dot(svo.wPos - camWPos, camWForward); visible = dist < shadowDistance; } return(visible); }
private void ExportShadowVolumeMesh() { if (Selection.activeGameObject == null) { ShowNotification("Please Select a GameObject"); } else { ShadowVolumeObject svo = FindShadowVolumeObject(Selection.activeGameObject); if (svo == null) { svo = Selection.activeGameObject.GetComponent <ShadowVolumeObject>(); } if (svo == null) { ShowNotification("Cannot find Shadow Volume Object"); return; } MeshFilter mf = svo.GetComponent <MeshFilter>(); if (mf == null || mf.sharedMesh == null) { ShowNotification("Cannot find Shadow Volume Mesh"); return; } if (!mf.sharedMesh.isReadable) { ShowNotification("Shadow Volume Mesh is not readable"); return; } string savePath = EditorUtility.SaveFilePanelInProject("Export Shadow Volume Mesh", mf.sharedMesh.name, "obj", string.Empty); if (string.IsNullOrEmpty(savePath)) { return; } File.WriteAllText(savePath, ShadowVolume_ObjExporter.DoExport(svo.gameObject, EXPORT_OBJ_COMMENT)); AssetDatabase.Refresh(); } }
private void BakeAGameObject(GameObject go) { ShadowVolumeObject svo = go.GetComponent <ShadowVolumeObject>(); if (svo != null) { go = svo.source; } PrefabType type = PrefabUtility.GetPrefabType(go); if (type == PrefabType.Prefab) { Debug.LogError("Skip a Shadow Volume Baking, because of it is a Prefab. " + go.name, go); return; } MeshFilter mf = go.GetComponent <MeshFilter>(); if (mf == null) { Debug.LogError("Skip a Shadow Volume Baking, becase of there is no MeshFilter. " + go.name, go); return; } if (mf.sharedMesh == null) { Debug.LogError("Skip a Shadow Volume Baking, becase of there is no Mesh. " + go.name, go); return; } if (!mf.sharedMesh.isReadable) { Debug.LogError("Skip a Shadow Volume Baking, becase of Mesh is not readable. " + go.name, go); return; } Transform transform = go.transform; ABakingTask task = new ABakingTask(); task.Init(transform, transform.localToWorldMatrix, transform.worldToLocalMatrix, dirLight.transform.forward, mf.sharedMesh, capsOffset, groundLayer, twoSubMeshes); bakingTaskManager.AddTask(task); }
private void UpdateBounds() { if (static_svos == null || !boundsNeedUpdate || !Application.isPlaying) { return; } boundsNeedUpdate = false; int numSVOs = static_svos.Length; for (int i = 0; i < numSVOs; ++i) { ShadowVolumeObject svo = static_svos[i]; if (svo.sourceMeshFilter != null && svo.sourceMeshFilter.sharedMesh != null && svo.meshFilter != null && svo.meshFilter.sharedMesh != null) { svo.sourceMeshFilter.sharedMesh.bounds = svo.meshFilter.sharedMesh.bounds; } } }
private void ClearSelected() { GameObject[] selectedGos = Selection.gameObjects; if (selectedGos == null || selectedGos.Length == 0) { ShowNotification("Select one or more GameObject in Scene"); } else { foreach (var selectedGo in selectedGos) { ShadowVolumeObject svObj = FindShadowVolumeObject(selectedGo); if (svObj == null) { svObj = selectedGo.GetComponent <ShadowVolumeObject>(); } if (svObj != null) { DestroyImmediate(svObj.gameObject); } } } }
private void GotoSVO() { if (Selection.activeGameObject == null) { ShowNotification("Please Select a GameObject"); } else { ShadowVolumeObject svo = FindShadowVolumeObject(Selection.activeGameObject); if (svo != null) { Selection.activeGameObject = svo.gameObject; } else { svo = Selection.activeGameObject.GetComponent <ShadowVolumeObject>(); if (svo != null) { Selection.activeGameObject = svo.source; } } } }