/// <summary> /// Explodes each object in the instance definition into a list of display objects /// </summary> public new void ExplodeIntoArray(RMModel model, List<DisplayObject> array, Transform xform) { RMModel currentModel = model; int instanceCount = InstanceDefinition.GetObjectIds ().GetLength (0); for (int i = 0; i < instanceCount; i++) { Guid guid = InstanceDefinition.GetObjectIds () [i]; ModelObject modelObject = currentModel.ModelObjectWithGUID (guid); if (modelObject != null) { try { modelObject.LayerIndex = LayerIndex; var modelMesh = modelObject as ModelMesh; if (modelMesh != null) { modelMesh.ExplodeIntoArray (model, array, xform); } else { var modelInstanceRef = modelObject as ModelInstanceRef; if (modelInstanceRef != null) { modelInstanceRef.ExplodeIntoArray (model, array, xform); } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine ("Caught Exception: " + ex.Message); System.Diagnostics.Debug.WriteLine ("This is caused by a null Mesh on an InstanceRef"); Rhino.Runtime.HostUtils.ExceptionReport (ex); } } } }
/// <summary> /// Calls into this reference's ModelInstanceDef ExplodeIntoArray method /// </summary> public new void ExplodeIntoArray(RMModel model, List<DisplayObject> array, Transform initialXform) { Transform newXform = initialXform * m_xform; RMModel currentModel = model; ModelObject modelObject = currentModel.ModelObjectWithGUID (m_definitionGUID); (modelObject as ModelInstanceDef).LayerIndex = this.LayerIndex; (modelObject as ModelInstanceDef).ExplodeIntoArray (model, array, newXform); }
/// <summary> /// Explodes a list of DisplayObjects into DisplayMeshes /// </summary> public new void ExplodeIntoArray(RMModel model, List<DisplayObject> array, Transform xform) { bool isIdentityXform = xform.Equals (Transform.Identity); if (DisplayMeshes == null) return; foreach (DisplayMesh mesh in DisplayMeshes) { if (isIdentityXform) { mesh.IsVisible = Visible; mesh.LayerIndex = LayerIndex; array.Add (mesh); } else { DisplayInstanceMesh instanceMesh = new DisplayInstanceMesh (mesh, xform); instanceMesh.IsVisible = Visible; instanceMesh.LayerIndex = LayerIndex; array.Add (instanceMesh); } } }
/// <summary> /// Creates a default light and enables the active shader /// </summary> private void SetupShader(RhGLShaderProgram shader, RMModel model, ViewportInfo viewport) { // Check to make sure we actually have an active shader... if (shader != null) { // Enable... shader.Enable (); // Now setup and initialize frustum and lighting... int near, far; viewport.GetScreenPort (out near, out far); viewport.SetScreenPort ((int)Frame.Left, (int)Frame.Right, (int)Frame.Bottom, (int)Frame.Top, near, far); shader.SetupViewport (viewport); Rhino.Geometry.Light light = CreateDefaultLight (); shader.SetupLight (light); light.Dispose (); } }
/// <summary> /// Draws all transparent meshes /// </summary> private void RenderTransparentObjects(RMModel model) { // Drawing transparent meshes is a 3 pass process... // // Pass #1: With depth buffer writing OFF // i. Draw all objects' backfaces // ii. Draw all "open" objects' front faces. // // Pass #2: With depth buffer writing ON // i. Draw all objects' front faces // // Pass #3: With depth buffer writing ON // i. Draw all "open" objects' back faces // // Provided we actually have a model to render... if (model != null) { CurrentMaterial = new DisplayMaterial (); //reset to the default (unset) material // ... render all transparent meshes... if (model.TransparentObjects.Count > 0) { //Pass #1 GL.DepthMask (false); GL.Enable (EnableCap.CullFace); // i. Draw all objects' backfaces GL.CullFace (CullFaceMode.Front); foreach (DisplayMesh mesh in model.TransparentObjects) { if (mesh != null) { RenderObject (mesh, Viewport, false); // ii. Draw all "open" objects' front faces. if (!mesh.IsClosed) { GL.CullFace (CullFaceMode.Back); RenderObject (mesh, Viewport, false); } } } // Pass #2: Draw all objects' front faces GL.DepthMask (true); GL.CullFace (CullFaceMode.Back); foreach (DisplayMesh mesh in model.TransparentObjects) RenderObject (mesh, Viewport, false); // Pass #3: Draw all "open" objects' back faces GL.CullFace (CullFaceMode.Front); foreach (DisplayMesh mesh in model.TransparentObjects) { if ((mesh != null) && (!mesh.IsClosed)) RenderObject (mesh, Viewport, false); } GL.Disable (EnableCap.CullFace); } // ...then render all transparent instance meshes... if (model.TransparentInstanceObjects.Count > 0) { //Pass #1 GL.DepthMask (false); GL.Enable (EnableCap.CullFace); // i. Draw all objects' backfaces GL.CullFace (CullFaceMode.Front); foreach (DisplayInstanceMesh instance in model.TransparentInstanceObjects) { if (instance.Mesh != null) { RenderObject (instance, Viewport, true); // ii. Draw all "open" objects' front faces. if (!instance.Mesh.IsClosed) { GL.CullFace (CullFaceMode.Back); RenderObject (instance, Viewport, true); } } } // Pass #2: Draw all objects' front faces GL.DepthMask (true); GL.CullFace (CullFaceMode.Back); foreach (DisplayInstanceMesh instance in model.TransparentInstanceObjects) RenderObject (instance, Viewport, true); // Pass #3: Draw all "open" objects' back faces GL.CullFace (CullFaceMode.Front); foreach (DisplayInstanceMesh instance in model.TransparentInstanceObjects) { if ((instance.Mesh != null) && (!instance.Mesh.IsClosed)) RenderObject (instance, Viewport, true); } GL.Disable (EnableCap.CullFace); } } }
/// <summary> /// IRenderer interface method /// Renders a model in a viewport /// </summary> public bool RenderModel(RMModel model, Rhino.DocObjects.ViewportInfo viewport) { if (null == model || null == viewport || !model.IsReadyForRendering) return false; Model = model; CheckGLError ("intro call"); //HACK: necessary on some Android GPUs (don't delete this check) viewport.SetFrustumNearFar (model.BBox); // Disable Blending and set the depth function GL.DepthFunc (DepthFunction.Gequal); GL.Disable (EnableCap.Blend); // Get the shader... ActiveShader = FastDrawing ? GetShader ("PerVertexLighting") : GetShader ("PerPixelLighting"); // Render calls... if (model != null) { // First, render all opaque objects that are not instances foreach (var obj in model.DisplayMeshes) { if (obj != null) RenderObject (obj, viewport, false); } // Second, render all opaque objects that are instances foreach (var obj in model.DisplayInstanceMeshes) { if (obj != null) RenderObject (obj, viewport, true); } // Third, we're done drawing our instances, so set the ModelViewMatrix's XForm back to the identity matrix. ActiveShader.SetModelViewMatrix (Rhino.Geometry.Transform.Identity); // Fourth, render all transparent meshes... RenderTransparentObjects (model); } // Disable the shader ActiveShader.Disable (); return true; }
/// <remarks> /// For Debugging purposes only. If this method is being called, then some object /// has not been properly cast into a ModelMesh, a ModelInstanceDef, or a ModelInstanceRef. /// </remarks> public void ExplodeIntoArray(RMModel model, List<DisplayObject> array, Transform xForm) { Debug.WriteLine("Missing implementation or implementation should happen in derived class"); }