void DrawMesh(Camera cam, MeshRenderer obj, Exporter exporter) { if (obj.gameObject.tag == "EditorOnly") { return; } if (obj.gameObject.GetComponent <TextFx>() != null) { return; } //-------------------change shader command { commandlist.Add(new ChangeShaderCommand(cam, obj.gameObject, exporter)); } //-------------------set image slot command { var imageslots = obj.GetComponents <FxImageSlot>(); foreach (var slot in imageslots) { commandlist.Add(new ImageSlotCommand(slot)); } } //-------------------set canvas slot command { //var canvasSlot = obj.GetComponent<FxCanvasSlot>(); var canvasSlots = obj.GetComponents <FxCanvasSlot>(); foreach (var slot in canvasSlots) { if (slot.canvas == null) { Debug.LogError("有CanvasSlot使用了空的canvas:" + obj.name); continue; } commandlist.Add(new CanvasSlotCommand(slot, exporter)); } } //-------------------draw mesh command { //commandlist.Add(new DrawMeshCommand(Camera.main, obj.gameObject, exporter)); commandlist.Add(new DrawMeshCommand(SceneConfig.currentCamera, obj.gameObject, exporter)); } }
private void DrawLimitToGameObjects(Camera cam) { if (_materialLimitToGameObjects == null) { _materialLimitToGameObjects = new Material(Shader.Find("Hidden/Decalicious Game Object ID")); } var limitToId = Shader.PropertyToID("_DecaliciousLimitToGameObject"); _bufferLimitTo.GetTemporaryRT(limitToId, -1, -1, 0, FilterMode.Point, RenderTextureFormat.RInt); _bufferLimitTo.SetRenderTarget(limitToId, BuiltinRenderTextureType.CameraTarget); _bufferLimitTo.ClearRenderTarget(false, true, Color.black); if (temporaryMesh == null) { temporaryMesh = new Mesh(); } // Loop over all game objects used for limiting decals Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(cam); foreach (GameObject go in GameObject.FindObjectsOfType <GameObject>()) { _bufferLimitTo.SetGlobalFloat("_ID", go.layer); // Draw all mesh renderers... _limitToMeshRenderers.Clear(); MeshRenderer mr = go.GetComponent <MeshRenderer>(); if (null != mr) { // ...if they are not decals themselves... // NOTE: We're using this trick because GetComponent() does some GC allocs // when the component is null (for some warning string or whatever). _decalComponent.Clear(); mr.GetComponents(_decalComponent); if (_decalComponent.Count == 0) { // Cull meshes that are outside the camera's frustum if (!GeometryUtility.TestPlanesAABB(frustumPlanes, mr.bounds)) { continue; } // ...and have a mesh filter _meshFilterComponent.Clear(); mr.GetComponents(_meshFilterComponent); if (_meshFilterComponent.Count == 1) { MeshFilter mf = _meshFilterComponent[0]; _bufferLimitTo.DrawMesh(mf.sharedMesh, mr.transform.localToWorldMatrix, _materialLimitToGameObjects); } } } //_limitToSkinnedMeshRenderers.Clear(); SkinnedMeshRenderer smr = go.GetComponent <SkinnedMeshRenderer>(); // TODO: Allow limiting to skinned meshes if (null != smr) { smr.BakeMesh(temporaryMesh); _bufferLimitTo.DrawMesh(temporaryMesh, smr.transform.localToWorldMatrix, _materialLimitToGameObjects); } } }
void RefreshRenderer(object tag) { List <int> triangles = new List <int>(capacity: all_triangles.Length); List <int> stems = new List <int>(capacity: all_stems.Length); List <int> alt_triangles = new List <int>(); List <int> alt_stems = new List <int>(); lock (sketch.geometries_lock) { var geometries = sketch.geometries; for (int i = geom_ids.Count - 1; i >= 0; --i) { int geom_id = geom_ids[i]; Geom geom = geometries[geom_id]; /* Concurrent writes to 'geom' could occur, but only the 'gindex' field, and * only to add/remove the GINDEX_HIDDEN flag or to change it to GINDEX_DESTROYED. * If that occurs, this MeshGameObject will be scheduled for another update * at the next Flush() anyway. */ List <int> triangles1, stems1; uint gmask = geom.gindex & GINDEX_MASK; if (gmask == GINDEX_REG) { /* Geometry is visible */ triangles1 = triangles; stems1 = stems; } else if (gmask == GINDEX_ALT) { triangles1 = alt_triangles; stems1 = alt_stems; } else { if (geom.gindex == GINDEX_DESTROYED) { /* Geom was destroyed */ int last = geom_ids.Count - 1; geom_ids[i] = geom_ids[last]; geom_ids.RemoveAt(last); geometries[geom_id].gindex = (((uint)sketch.geom_free_head_mainthread) << GINDEX_SHIFT) | GINDEX_FREE; sketch.geom_free_head_mainthread = geom_id; } continue; } int start, stop; start = geom.triangle_start * 3; stop = geom.triangle_stop * 3; if (stop == 0xFFFF * 3) { stop = all_triangles.Length; } for (int j = start; j < stop; j++) { triangles1.Add(all_triangles[j]); } start = geom.stem_start * 2; stop = geom.stem_stop * 2; if (stop == 0xFFFF * 2) { stop = all_stems.Length; } for (int j = start; j < stop; j++) { stems1.Add(all_stems[j]); } } } geom_ids.TrimExcess(); bool any_triangle_1 = triangles.Count > 0; bool any_triangle_2 = alt_triangles.Count > 0; bool any_stem_1 = (stems.Count > 0 && sketch.stemMaterial != null); bool any_stem_2 = (alt_stems.Count > 0 && sketch.stemAlternateMaterial != null); stem_mat = sketch.stemMaterial; stem_alt_mat = sketch.stemAlternateMaterial; face_mat = null; face_alt_mat = null; if (any_triangle_1 || any_stem_1 || any_triangle_2 || any_stem_2) { mesh.subMeshCount = (any_triangle_1 ? 1 : 0) + (any_stem_1 ? 1 : 0) + (any_triangle_2 ? 1 : 0) + (any_stem_2 ? 1 : 0); Material[] mats = new Material[mesh.subMeshCount]; int submesh = 0; if (any_triangle_1) { mesh.SetTriangles(triangles, submesh, calculateBounds: false); face_mat = face_mat_builder.GetMaterial(); mats[submesh] = face_mat; submesh++; } if (any_stem_1) { mesh.SetIndices(stems.ToArray(), MeshTopology.Lines, submesh, calculateBounds: false); mats[submesh] = stem_mat; submesh++; } if (any_triangle_2) { mesh.SetTriangles(alt_triangles, submesh, calculateBounds: false); face_alt_mat = face_mat_builder.GetAlternateMaterial(); mats[submesh] = face_alt_mat; submesh++; } if (any_stem_2) { mesh.SetIndices(alt_stems.ToArray(), MeshTopology.Lines, submesh, calculateBounds: false); mats[submesh] = stem_alt_mat; submesh++; } mesh.RecalculateBounds(); if (renderer == null) { var go = Instantiate(sketch.largeSketchMeshPrefab, sketch.transform); go.GetComponent <MeshFilter>().sharedMesh = mesh; renderer = go.GetComponent <MeshRenderer>(); } renderer.sharedMaterials = mats; foreach (var script in renderer.GetComponents <IMeshModified>()) { script.Modified(); } } else { if (renderer != null) { Destroy(renderer.gameObject); renderer = null; } } current_tag = tag; }