/// <summary> /// Reads the vertex buffers for a model from a stream and passes them to an IModelProcessor. /// </summary> /// <param name="reader">The stream to read the vertex buffers from.</param> /// <param name="model">The model's metadata.</param> /// <param name="sectionsToRead"> /// A BitArray controlling which sections to read. Indices which are set to to true will be /// read. /// </param> /// <param name="buildInfo">Information about the cache file's target engine.</param> /// <param name="processor">The IModelProcessor to pass the read model data to.</param> private static void ReadVertexBuffers(IReader reader, IRenderModel model, BitArray sectionsToRead, EngineDescription buildInfo, IModelProcessor processor) { for (int i = 0; i < model.Sections.Length; i++) ReadSectionVertices(reader, model.Sections[i], model.BoundingBoxes[0], buildInfo, sectionsToRead[i] ? processor : null); }
private ActionResult RenderArticleListByCategory(IRenderModel model, string tag, int?p) { var tagPage = model.Content as TravelBlog.Models.VirtualPage; if (tagPage == null) { throw new InvalidOperationException("The RenderModel.Content instance must be of type " + typeof(VirtualPage)); } //create a master model var masterModel = new MasterModel(model.Content); var contentByTag = Umbraco.GetContentByTag(masterModel, tagPage.Name, p ?? 1, masterModel.PageSize); //this is a special case in the event that a tag contains a '.', when this happens we change it to a '-' // when generating the URL. So if the above doesn't return any tags and the tag contains a '-', then we // will replace them with '.' and do the lookup again if ((contentByTag == null || contentByTag.PostCount == 0) && tagPage.Name.Contains("-")) { contentByTag = Umbraco.GetContentByTag( masterModel, tagPage.Name.Replace('-', '.'), p ?? 1, masterModel.PageSize); } if (contentByTag == null) { return(new HttpNotFoundResult()); } return(GetPagedListView(masterModel, tagPage, contentByTag.Posts, contentByTag.PostCount, p)); }
/// <summary> /// Reads the vertex buffers for a model from a stream and passes them to an IModelProcessor. /// </summary> /// <param name="reader">The stream to read the vertex buffers from.</param> /// <param name="model">The model's metadata.</param> /// <param name="sectionsToRead"> /// A BitArray controlling which sections to read. Indices which are set to to true will be /// read. /// </param> /// <param name="buildInfo">Information about the cache file's target engine.</param> /// <param name="processor">The IModelProcessor to pass the read model data to.</param> private static void ReadVertexBuffers(IReader reader, IRenderModel model, BitArray sectionsToRead, EngineDescription buildInfo, IModelProcessor processor) { for (int i = 0; i < model.Sections.Length; i++) { ReadSectionVertices(reader, model.Sections[i], model.BoundingBoxes[0], buildInfo, sectionsToRead[i] ? processor : null); } }
/// <summary> /// Reads the resource data for a model from a stream and passes it to an IModelProcessor. /// </summary> /// <param name="reader">The stream to read the model data from.</param> /// <param name="model">The model's metadata.</param> /// <param name="sectionsToRead">A BitArray controlling which sections to read. Indices which are set to to true will be read.</param> /// <param name="buildInfo">Information about the cache file's target engine.</param> /// <param name="processor">The IModelProcessor to pass the read model data to.</param> public static void ReadModelData(IReader reader, IRenderModel model, BitArray sectionsToRead, BuildInformation buildInfo, IModelProcessor processor) { processor.BeginModel(model); ReadVertexBuffers(reader, model, sectionsToRead, buildInfo, processor); ReadIndexBuffers(reader, model, sectionsToRead, buildInfo, processor); processor.EndModel(model); }
/// <summary> /// Reads the resource data for a model from a stream and passes it to an IModelProcessor. /// </summary> /// <param name="reader">The stream to read the model data from.</param> /// <param name="model">The model's metadata.</param> /// <param name="sectionsToRead"> /// A BitArray controlling which sections to read. Indices which are set to to true will be /// read. /// </param> /// <param name="buildInfo">Information about the cache file's target engine.</param> /// <param name="processor">The IModelProcessor to pass the read model data to.</param> public static void ReadModelData(IReader reader, IRenderModel model, BitArray sectionsToRead, EngineDescription buildInfo, IModelProcessor processor) { processor.BeginModel(model); ReadVertexBuffers(reader, model, sectionsToRead, buildInfo, processor); ReadIndexBuffers(reader, model, sectionsToRead, buildInfo, processor); processor.EndModel(model); }
private ActionResult RenderView(IRenderModel model, int?p = null) { var listNode = model.Content.Children .FirstOrDefault(x => x.DocumentTypeAlias.InvariantEquals("ArticulateArchive")); if (listNode == null) { throw new InvalidOperationException("An ArticulateArchive document must exist under the root Articulate document"); } if (p == null || p.Value <= 0) { p = 1; } var rootPageModel = new ListModel(model.Content); //TODO: I wonder about the performance of this - when we end up with thousands of blog posts, // this will probably not be so efficient. I wonder if using an XPath lookup for batches of children // would work? The children count could be cached. I'd rather not put blog posts under 'month' nodes // just for the sake of performance. Hrm.... Examine possibly too. var totalPosts = listNode.Children.Count(); var pageSize = rootPageModel.PageSize; var totalPages = Convert.ToInt32(Math.Ceiling((double)totalPosts / pageSize)); //Invalid page, redirect without pages if (totalPages > 0 && totalPages < p) { return(new RedirectToUmbracoPageResult(model.Content, UmbracoContext)); } // Testing //UrlRewritingNet.Web.RegExRewriteRule rule = new UrlRewritingNet.Web.RegExRewriteRule(); //rule.VirtualUrl = "^~/blog/page/(.*)"; //rule.RewriteUrlParameter = UrlRewritingNet.Web.RewriteUrlParameterOption.ExcludeFromClientQueryString; //rule.DestinationUrl = "~/blog?p=$1"; //rule.IgnoreCase = true; //UrlRewritingNet.Web.UrlRewriting.AddRewriteRule("Articulate_Paging", rule); var pager = new PagerModel( pageSize, p.Value - 1, totalPages, totalPages > p ? model.Content.Url.EnsureEndsWith('/') + "page/" + (p + 1) : null, p > 1 ? model.Content.Url.EnsureEndsWith('/') + "page/" + (p - 1) : null); var listModel = new ListModel(listNode, pager); return(View(PathHelper.GetThemeViewPath(listModel, "List"), listModel)); }
/// <summary> /// Reads the index buffers for a model from a stream and passes them to an IModelProcessor. /// </summary> /// <param name="reader">The stream to read the index buffers from.</param> /// <param name="model">The model's metadata.</param> /// <param name="sectionsToRead">A BitArray controlling which sections to read. Indices which are set to to true will be read.</param> /// <param name="buildInfo">Information about the cache file's target engine.</param> /// <param name="processor">The IModelProcessor to pass the read model data to.</param> private static void ReadIndexBuffers(IReader reader, IRenderModel model, BitArray sectionsToRead, BuildInformation buildInfo, IModelProcessor processor) { int baseIndex = 0; for (int i = 0; i < model.Sections.Length; i++) { IModelSection section = model.Sections[i]; ReadSectionIndices(reader, section, baseIndex, buildInfo, sectionsToRead[i] ? processor : null); if (sectionsToRead[i]) baseIndex += CountVertices(section); } }
private ActionResult RenderView(IRenderModel model, int?p = null) { var listNode = model.Content.Children .FirstOrDefault(x => x.DocumentTypeAlias.InvariantEquals("ArticulateArchive")); if (listNode == null) { throw new InvalidOperationException("An ArticulateArchive document must exist under the root Articulate document"); } if (p != null && p.Value == 1) { return(new RedirectToUmbracoPageResult(model.Content, UmbracoContext)); } if (p == null || p.Value <= 0) { p = 1; } var rootPageModel = new ListModel(model.Content); //TODO: I wonder about the performance of this - when we end up with thousands of blog posts, // this will probably not be so efficient. I wonder if using an XPath lookup for batches of children // would work? The children count could be cached. I'd rather not put blog posts under 'month' nodes // just for the sake of performance. Hrm.... Examine possibly too. var totalPosts = listNode.Children.Count(); var pageSize = rootPageModel.PageSize; var totalPages = Convert.ToInt32(Math.Ceiling((double)totalPosts / pageSize)); //Invalid page, redirect without pages if (totalPages > 0 && totalPages < p) { return(new RedirectToUmbracoPageResult(model.Content, UmbracoContext)); } var pager = new PagerModel( pageSize, p.Value - 1, totalPages, totalPages > p ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p + 1) : null, p > 2 ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p - 1) : p > 1 ? model.Content.Url : null); var listModel = new ListModel(listNode, pager); return(View(PathHelper.GetThemeViewPath(listModel, "List"), listModel)); }
private ActionResult RenderView(IRenderModel model, int?p = null) { var listNodes = model.Content.Children("ArticulateArchive").ToArray(); if (listNodes.Length == 0) { throw new InvalidOperationException("An ArticulateArchive document must exist under the root Articulate document"); } var master = new MasterModel(model.Content); //Get post count by xpath is much faster than iterating all children to get a count var count = Umbraco.GetPostCount(listNodes.Select(x => x.Id).ToArray()); return(GetPagedListView(master, listNodes[0], listNodes[0].Children, count, p)); }
/// <summary> /// Reads the index buffers for a model from a stream and passes them to an IModelProcessor. /// </summary> /// <param name="reader">The stream to read the index buffers from.</param> /// <param name="model">The model's metadata.</param> /// <param name="sectionsToRead"> /// A BitArray controlling which sections to read. Indices which are set to to true will be /// read. /// </param> /// <param name="buildInfo">Information about the cache file's target engine.</param> /// <param name="processor">The IModelProcessor to pass the read model data to.</param> private static void ReadIndexBuffers(IReader reader, IRenderModel model, BitArray sectionsToRead, EngineDescription buildInfo, IModelProcessor processor) { int baseIndex = 0; for (int i = 0; i < model.Sections.Length; i++) { IModelSection section = model.Sections[i]; ReadSectionIndices(reader, section, baseIndex, buildInfo, sectionsToRead[i] ? processor : null); if (sectionsToRead[i]) { baseIndex += CountVertices(section); } } }
private ActionResult RenderView(IRenderModel model, int?p = null) { var listNode = model.Content.Children .FirstOrDefault(x => x.DocumentTypeAlias.InvariantEquals("ArticulateArchive")); if (listNode == null) { throw new InvalidOperationException("An ArticulateArchive document must exist under the root Articulate document"); } if (p != null && p.Value == 1) { return(new RedirectToUmbracoPageResult(model.Content, UmbracoContext)); } if (p == null || p.Value <= 0) { p = 1; } var rootPageModel = new MasterModel(model.Content); //get the count with XPath, this will be the fastest var totalPosts = Umbraco.GetPostCount(listNode.Id); var pageSize = rootPageModel.PageSize; var totalPages = Convert.ToInt32(Math.Ceiling((double)totalPosts / pageSize)); //Invalid page, redirect without pages if (totalPages > 0 && totalPages < p) { return(new RedirectToUmbracoPageResult(model.Content, UmbracoContext)); } var pager = new PagerModel( pageSize, p.Value - 1, totalPages, totalPages > p ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p + 1) : null, p > 2 ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p - 1) : p > 1 ? model.Content.Url : null); var listItems = Umbraco.GetPostsSortedByPublishedDate(listNode.Id, pager); var listModel = new ListModel(listNode, listItems, pager); return(View(PathHelper.GetThemeViewPath(listModel, "List"), listModel)); }
private ActionResult RenderView(IRenderModel model, int? p = null) { var listNode = model.Content.Children .FirstOrDefault(x => x.DocumentTypeAlias.InvariantEquals("ArticulateArchive")); if (listNode == null) { throw new InvalidOperationException("An ArticulateArchive document must exist under the root Articulate document"); } if (p != null && p.Value == 1) { return new RedirectToUmbracoPageResult(model.Content, UmbracoContext); } if (p == null || p.Value <= 0) { p = 1; } var rootPageModel = new ListModel(model.Content); //TODO: I wonder about the performance of this - when we end up with thousands of blog posts, // this will probably not be so efficient. I wonder if using an XPath lookup for batches of children // would work? The children count could be cached. I'd rather not put blog posts under 'month' nodes // just for the sake of performance. Hrm.... Examine possibly too. var totalPosts = listNode.Children.Count(); var pageSize = rootPageModel.PageSize; var totalPages = Convert.ToInt32(Math.Ceiling((double)totalPosts/pageSize)); //Invalid page, redirect without pages if (totalPages > 0 && totalPages < p) { return new RedirectToUmbracoPageResult(model.Content, UmbracoContext); } var pager = new PagerModel( pageSize, p.Value - 1, totalPages, totalPages > p ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p + 1) : null, p > 2 ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p - 1) : p > 1 ? model.Content.Url : null); var listModel = new ListModel(listNode, pager); return View(PathHelper.GetThemeViewPath(listModel, "List"), listModel); }
private ActionResult RenderView(IRenderModel model, int? p = null) { var listNode = model.Content.Children .FirstOrDefault(x => x.DocumentTypeAlias.InvariantEquals("ArticulateArchive")); if (listNode == null) { throw new InvalidOperationException("An ArticulateArchive document must exist under the root Articulate document"); } if (p != null && p.Value == 1) { return new RedirectToUmbracoPageResult(model.Content, UmbracoContext); } if (p == null || p.Value <= 0) { p = 1; } var rootPageModel = new MasterModel(model.Content); //get the count with XPath, this will be the fastest var totalPosts = Umbraco.GetPostCount(listNode.Id); var pageSize = rootPageModel.PageSize; var totalPages = Convert.ToInt32(Math.Ceiling((double)totalPosts/pageSize)); //Invalid page, redirect without pages if (totalPages > 0 && totalPages < p) { return new RedirectToUmbracoPageResult(model.Content, UmbracoContext); } var pager = new PagerModel( pageSize, p.Value - 1, totalPages, totalPages > p ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p + 1) : null, p > 2 ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p - 1) : p > 1 ? model.Content.Url : null); var listItems = Umbraco.GetPostsSortedByPublishedDate(listNode.Id, pager); var listModel = new ListModel(listNode, listItems, pager); return View(PathHelper.GetThemeViewPath(listModel, "List"), listModel); }
private ActionResult RenderView(IRenderModel model, int?p = null) { var archive = new MasterModel(model.Content); // redirect to root node when "redirectArchive" is configured if (archive.RootBlogNode.GetPropertyValue <bool>("redirectArchive")) { return(RedirectPermanent(archive.RootBlogNode.Url)); } //Get post count by xpath is much faster than iterating all children to get a count var count = Umbraco.GetPostCount(archive.Id); int pageSize; if (!Int32.TryParse(archive.RootBlogNode.GetPropertyValue <string>("pageSize"), out pageSize)) { pageSize = 10; } var posts = Umbraco.GetRecentPostsByArchive(archive, 1, pageSize); return(GetPagedListView(archive, archive, posts, count, null)); }
public override IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel) { int i, surfaceNum; MD5Mesh mesh; RenderModelStatic staticModel; if (cachedModel != null && !r_useCachedDynamicModels.Bool) { cachedModel.Dispose(); cachedModel = null; } if (purged) { common.DWarning($"model {Name} instantiated while purged"); LoadModel(); } if (ent.joints == null) { common.Printf($"RenderModelMD5::InstantiateDynamicModel: null joints on renderEntity for '{Name}'\n"); cachedModel.Dispose(); return(null); } else if (ent.numJoints != joints.Length) { common.Printf($"RenderModelMD5::InstantiateDynamicModel: renderEntity has different number of joints than model for '{Name}'\n"); cachedModel.Dispose(); return(null); } tr.pc.c_generateMd5++; if (cachedModel != null) { Debug.Assert(cachedModel is RenderModelStatic); Debug.Assert(string.Equals(cachedModel.Name, MD5_SnapshotName, StringComparison.OrdinalIgnoreCase)); staticModel = (RenderModelStatic)cachedModel; } else { staticModel = new RenderModelStatic(); staticModel.InitEmpty(MD5_SnapshotName); } staticModel.bounds.Clear(); if (r_showSkel.Integer != 0) { if (view != null && (!r_skipSuppress.Bool || ent.suppressSurfaceInViewID == 0 || ent.suppressSurfaceInViewID != view.renderView.viewID)) { DrawJoints(ent, view); // only draw the skeleton } if (r_showSkel.Integer > 1) { staticModel.InitEmpty(MD5_SnapshotName); return(staticModel); } // turn off the model when showing the skeleton } // create all the surfaces for (i = 0; i < meshes.Length; i++) { mesh = meshes[i]; // avoid deforming the surface if it will be a nodraw due to a skin remapping. FIXME: may have to still deform clipping hulls var shader = mesh.shader; shader = R_RemapShaderBySkin(shader, ent.customSkin, ent.customShader); if (shader == null || (!shader.IsDrawn && !shader.SurfaceCastsShadow)) { staticModel.DeleteSurfaceWithId(i); mesh.surfaceNum = -1; continue; } ModelSurface surf; if (staticModel.FindSurfaceWithId(i, out surfaceNum)) { mesh.surfaceNum = surfaceNum; surf = staticModel.surfaces[surfaceNum]; } else { // Remove Overlays before adding new surfaces RenderModelOverlay.RemoveOverlaySurfacesFromModel(staticModel); mesh.surfaceNum = staticModel.NumSurfaces; surf = staticModel.surfaces.Alloc(); surf.geometry = null; surf.shader = null; surf.id = i; } mesh.UpdateSurface(ent, ent.joints, surf); staticModel.bounds.AddPoint(surf.geometry.bounds[0]); staticModel.bounds.AddPoint(surf.geometry.bounds[1]); } return(staticModel); }
private ActionResult RenderByTagOrCategory(IRenderModel model, int? p, string tagGroup, string baseUrl) { var tagPage = model.Content as ArticulateVirtualPage; if (tagPage == null) { throw new InvalidOperationException("The RenderModel.Content instance must be of type " + typeof(ArticulateVirtualPage)); } //create a blog model of the main page var rootPageModel = new MasterModel(model.Content.Parent); var contentByTag = Umbraco.GetContentByTag(rootPageModel, tagPage.Name, tagGroup, baseUrl); //this is a special case in the event that a tag contains a '.', when this happens we change it to a '-' // when generating the URL. So if the above doesn't return any tags and the tag contains a '-', then we // will replace them with '.' and do the lookup again if (contentByTag == null && tagPage.Name.Contains("-")) { contentByTag = Umbraco.GetContentByTag( rootPageModel, tagPage.Name.Replace('-', '.'), tagGroup, baseUrl); } if (contentByTag == null) { return new HttpNotFoundResult(); } if (p != null && p.Value == 1) { return new RedirectToUmbracoPageResult(model.Content, UmbracoContext); } if (p == null || p.Value <= 0) { p = 1; } //TODO: I wonder about the performance of this - when we end up with thousands of blog posts, // this will probably not be so efficient. I wonder if using an XPath lookup for batches of children // would work? The children count could be cached. I'd rather not put blog posts under 'month' nodes // just for the sake of performance. Hrm.... Examine possibly too. var totalPosts = contentByTag.PostCount; var pageSize = rootPageModel.PageSize; var totalPages = totalPosts == 0 ? 1 : Convert.ToInt32(Math.Ceiling((double)totalPosts / pageSize)); //Invalid page, redirect without pages if (totalPages < p) { return new RedirectToUmbracoPageResult(model.Content.Parent, UmbracoContext); } var pager = new PagerModel( pageSize, p.Value - 1, totalPages, totalPages > p ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p + 1) : null, p > 2 ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p - 1) : p > 1 ? model.Content.Url : null); var listModel = new ListModel(tagPage, contentByTag.Posts, pager); return View(PathHelper.GetThemeViewPath(listModel, "List"), listModel); }
public virtual IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel);
public override IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel) { RenderModelStatic staticModel; SrfTriangles tri; ModelSurface surf; if (cachedModel != null && !r_useCachedDynamicModels.Bool) { cachedModel.Dispose(); cachedModel = null; } if (ent == null || view == null) { cachedModel.Dispose(); cachedModel = null; } if (cachedModel != null) { Debug.Assert(cachedModel is RenderModelStatic); Debug.Assert(string.Equals(cachedModel.Name, sprite_SnapshotName, StringComparison.OrdinalIgnoreCase)); staticModel = (RenderModelStatic)cachedModel; surf = staticModel.Surface(0); tri = surf.geometry; } else { staticModel = new RenderModelStatic(); staticModel.InitEmpty(sprite_SnapshotName); tri = R_AllocStaticTriSurf(); R_AllocStaticTriSurfVerts(tri, 4); R_AllocStaticTriSurfIndexes(tri, 6); tri.verts[0].Clear(); tri.verts[0].normal.Set(1f, 0f, 0f); tri.verts[0].tangents0.Set(0f, 1f, 0f); tri.verts[0].tangents1.Set(0f, 0f, 1f); tri.verts[0].st.x = 0f; tri.verts[0].st.y = 0f; tri.verts[1].Clear(); tri.verts[1].normal.Set(1f, 0f, 0f); tri.verts[1].tangents0.Set(0f, 1f, 0f); tri.verts[1].tangents1.Set(0f, 0f, 1f); tri.verts[1].st.x = 1f; tri.verts[1].st.y = 0f; tri.verts[2].Clear(); tri.verts[2].normal.Set(1f, 0f, 0f); tri.verts[2].tangents0.Set(0f, 1f, 0f); tri.verts[2].tangents1.Set(0f, 0f, 1f); tri.verts[2].st.x = 1f; tri.verts[2].st.y = 1f; tri.verts[3].Clear(); tri.verts[3].normal.Set(1f, 0f, 0f); tri.verts[3].tangents0.Set(0f, 1f, 0f); tri.verts[3].tangents1.Set(0f, 0f, 1f); tri.verts[3].st.x = 0f; tri.verts[3].st.y = 1f; tri.indexes[0] = 0; tri.indexes[1] = 1; tri.indexes[2] = 3; tri.indexes[3] = 1; tri.indexes[4] = 2; tri.indexes[5] = 3; tri.numVerts = 4; tri.numIndexes = 6; surf = new(); surf.geometry = tri; surf.id = 0; surf.shader = tr.defaultMaterial; staticModel.AddSurface(surf); } var red = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_RED] * 255f); var green = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_GREEN] * 255f); var blue = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_BLUE] * 255f); var alpha = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_ALPHA] * 255f); var right = new Vector3(0f, ent.shaderParms[IRenderWorld.SHADERPARM_SPRITE_WIDTH] * 0.5f, 0f); var up = new Vector3(0f, 0f, ent.shaderParms[IRenderWorld.SHADERPARM_SPRITE_HEIGHT] * 0.5f); tri.verts[0].xyz = up + right; tri.verts[0].color0 = red; tri.verts[0].color1 = green; tri.verts[0].color2 = blue; tri.verts[0].color3 = alpha; tri.verts[1].xyz = up - right; tri.verts[1].color0 = red; tri.verts[1].color1 = green; tri.verts[1].color2 = blue; tri.verts[1].color3 = alpha; tri.verts[2].xyz = -right - up; tri.verts[2].color0 = red; tri.verts[2].color1 = green; tri.verts[2].color2 = blue; tri.verts[2].color3 = alpha; tri.verts[3].xyz = right - up; tri.verts[3].color0 = red; tri.verts[3].color1 = green; tri.verts[3].color2 = blue; tri.verts[3].color3 = alpha; R_BoundTriSurf(tri); staticModel.bounds = tri.bounds; return(staticModel); }
=> true; // don't ever need to load public override IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel) { RenderModelStatic staticModel; SrfTriangles tri; ModelSurface surf; if (cachedModel != null) { cachedModel = null; } if (ent == null || view == null) { return(null); } if (cachedModel != null) { Debug.Assert(cachedModel is RenderModelStatic); Debug.Assert(string.Equals(cachedModel.Name, beam_SnapshotName, StringComparison.OrdinalIgnoreCase)); staticModel = (RenderModelStatic)cachedModel; surf = staticModel.Surface(0); tri = surf.geometry; } else { staticModel = new RenderModelStatic(); staticModel.InitEmpty(beam_SnapshotName); tri = R_AllocStaticTriSurf(); R_AllocStaticTriSurfVerts(tri, 4); R_AllocStaticTriSurfIndexes(tri, 6); tri.verts[0].Clear(); tri.verts[0].st.x = 0; tri.verts[0].st.y = 0; tri.verts[1].Clear(); tri.verts[1].st.x = 0; tri.verts[1].st.y = 1; tri.verts[2].Clear(); tri.verts[2].st.x = 1; tri.verts[2].st.y = 0; tri.verts[3].Clear(); tri.verts[3].st.x = 1; tri.verts[3].st.y = 1; tri.indexes[0] = 0; tri.indexes[1] = 2; tri.indexes[2] = 1; tri.indexes[3] = 2; tri.indexes[4] = 3; tri.indexes[5] = 1; tri.numVerts = 4; tri.numIndexes = 6; surf = new(); surf.geometry = tri; surf.id = 0; surf.shader = tr.defaultMaterial; staticModel.AddSurface(surf); } Vector3 target = reinterpret.cast_vec3(ent.shaderParms, IRenderWorld.SHADERPARM_BEAM_END_X); // we need the view direction to project the minor axis of the tube as the view changes var modelMatrix = stackalloc float[16]; R_AxisToModelMatrix(ent.axis, ent.origin, modelMatrix); R_GlobalPointToLocal(modelMatrix, view.renderView.vieworg, out var localView); R_GlobalPointToLocal(modelMatrix, target, out var localTarget); Vector3 major = localTarget; Vector3 minor = default; Vector3 mid = 0.5f * localTarget; Vector3 dir = mid - localView; minor.Cross(major, dir); minor.Normalize(); if (ent.shaderParms[IRenderWorld.SHADERPARM_BEAM_WIDTH] != 0f) { minor *= ent.shaderParms[IRenderWorld.SHADERPARM_BEAM_WIDTH] * 0.5f; } var red = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_RED] * 255f); var green = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_GREEN] * 255f); var blue = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_BLUE] * 255f); var alpha = (byte)MathX.FtoiFast(ent.shaderParms[IRenderWorld.SHADERPARM_ALPHA] * 255f); tri.verts[0].xyz = minor; tri.verts[0].color0 = red; tri.verts[0].color1 = green; tri.verts[0].color2 = blue; tri.verts[0].color3 = alpha; tri.verts[1].xyz = -minor; tri.verts[1].color0 = red; tri.verts[1].color1 = green; tri.verts[1].color2 = blue; tri.verts[1].color3 = alpha; tri.verts[2].xyz = localTarget + minor; tri.verts[2].color0 = red; tri.verts[2].color1 = green; tri.verts[2].color2 = blue; tri.verts[2].color3 = alpha; tri.verts[3].xyz = localTarget - minor; tri.verts[3].color0 = red; tri.verts[3].color1 = green; tri.verts[3].color2 = blue; tri.verts[3].color3 = alpha; R_BoundTriSurf(tri); staticModel.bounds = tri.bounds; return(staticModel); }
public override IRenderModel InstantiateDynamicModel(RenderEntity ent, ViewDef view, IRenderModel cachedModel) { idRenderModelStatic *staticModel; if (cachedModel && !r_useCachedDynamicModels.GetBool()) { delete cachedModel; cachedModel = NULL; } // this may be triggered by a model trace or other non-view related source, to which we should look like an empty model if (renderEntity == NULL || viewDef == NULL) { delete cachedModel; return(NULL); } if (r_skipParticles.GetBool()) { delete cachedModel; return(NULL); } /* * // if the entire system has faded out * if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && viewDef->renderView.time * 0.001f >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] ) { * delete cachedModel; * return NULL; * } */ if (cachedModel != NULL) { assert(dynamic_cast <idRenderModelStatic *>(cachedModel) != NULL); assert(idStr::Icmp(cachedModel->Name(), parametricParticle_SnapshotName) == 0); staticModel = static_cast <idRenderModelStatic *>(cachedModel); } else { staticModel = new idRenderModelStatic; staticModel->InitEmpty(parametricParticle_SnapshotName); } particleGen_t g; g.renderEnt = renderEntity; g.renderView = &viewDef->renderView; g.origin.Zero(); g.axis.Identity(); for (int stageNum = 0; stageNum < particleSystem->stages.Num(); stageNum++) { idParticleStage *stage = particleSystem->stages[stageNum]; if (!stage->material) { continue; } if (!stage->cycleMsec) { continue; } if (stage->hidden) { // just for gui particle editor use staticModel->DeleteSurfaceWithId(stageNum); continue; } idRandom steppingRandom, steppingRandom2; int stageAge = g.renderView->time + renderEntity->shaderParms[SHADERPARM_TIMEOFFSET] * 1000 - stage->timeOffset * 1000; int stageCycle = stageAge / stage->cycleMsec; // some particles will be in this cycle, some will be in the previous cycle steppingRandom.SetSeed(((stageCycle << 10) & idRandom::MAX_RAND) ^ (int)(renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND)); steppingRandom2.SetSeed((((stageCycle - 1) << 10) & idRandom::MAX_RAND) ^ (int)(renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND)); int count = stage->totalParticles * stage->NumQuadsPerParticle(); int surfaceNum; modelSurface_t *surf; if (staticModel->FindSurfaceWithId(stageNum, surfaceNum)) { surf = &staticModel->surfaces[surfaceNum]; R_FreeStaticTriSurfVertexCaches(surf->geometry); } else { surf = &staticModel->surfaces.Alloc(); surf->id = stageNum; surf->shader = stage->material; surf->geometry = R_AllocStaticTriSurf(); R_AllocStaticTriSurfVerts(surf->geometry, 4 * count); R_AllocStaticTriSurfIndexes(surf->geometry, 6 * count); R_AllocStaticTriSurfPlanes(surf->geometry, 6 * count); } int numVerts = 0; idDrawVert *verts = surf->geometry->verts; for (int index = 0; index < stage->totalParticles; index++) { g.index = index; // bump the random steppingRandom.RandomInt(); steppingRandom2.RandomInt(); // calculate local age for this index int bunchOffset = stage->particleLife * 1000 * stage->spawnBunching * index / stage->totalParticles; int particleAge = stageAge - bunchOffset; int particleCycle = particleAge / stage->cycleMsec; if (particleCycle < 0) { // before the particleSystem spawned continue; } if (stage->cycles && particleCycle >= stage->cycles) { // cycled systems will only run cycle times continue; } if (particleCycle == stageCycle) { g.random = steppingRandom; } else { g.random = steppingRandom2; } int inCycleTime = particleAge - particleCycle * stage->cycleMsec; if (renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && g.renderView->time - inCycleTime >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] * 1000) { // don't fire any more particles continue; } // supress particles before or after the age clamp g.frac = (float)inCycleTime / (stage->particleLife * 1000); if (g.frac < 0.0f) { // yet to be spawned continue; } if (g.frac > 1.0f) { // this particle is in the deadTime band continue; } // this is needed so aimed particles can calculate origins at different times g.originalRandom = g.random; g.age = g.frac * stage->particleLife; // if the particle doesn't get drawn because it is faded out or beyond a kill region, don't increment the verts numVerts += stage->CreateParticle(&g, verts + numVerts); } // numVerts must be a multiple of 4 assert((numVerts & 3) == 0 && numVerts <= 4 * count); // build the indexes int numIndexes = 0; glIndex_t *indexes = surf->geometry->indexes; for (int i = 0; i < numVerts; i += 4) { indexes[numIndexes + 0] = i; indexes[numIndexes + 1] = i + 2; indexes[numIndexes + 2] = i + 3; indexes[numIndexes + 3] = i; indexes[numIndexes + 4] = i + 3; indexes[numIndexes + 5] = i + 1; numIndexes += 6; } surf->geometry->tangentsCalculated = false; surf->geometry->facePlanesCalculated = false; surf->geometry->numVerts = numVerts; surf->geometry->numIndexes = numIndexes; surf->geometry->bounds = stage->bounds; // just always draw the particles } return(staticModel); }
private ActionResult RenderByTagOrCategory(IRenderModel model, int?p, string tagGroup, string baseUrl) { var tagPage = model.Content as ArticulateVirtualPage; if (tagPage == null) { throw new InvalidOperationException("The RenderModel.Content instance must be of type " + typeof(ArticulateVirtualPage)); } //create a blog model of the main page var rootPageModel = new MasterModel(model.Content.Parent); var contentByTag = Umbraco.GetContentByTag(rootPageModel, tagPage.Name, tagGroup, baseUrl); //this is a special case in the event that a tag contains a '.', when this happens we change it to a '-' // when generating the URL. So if the above doesn't return any tags and the tag contains a '-', then we // will replace them with '.' and do the lookup again if (contentByTag == null && tagPage.Name.Contains("-")) { contentByTag = Umbraco.GetContentByTag( rootPageModel, tagPage.Name.Replace('-', '.'), tagGroup, baseUrl); } if (contentByTag == null) { return(new HttpNotFoundResult()); } if (p != null && p.Value == 1) { return(new RedirectToUmbracoPageResult(model.Content, UmbracoContext)); } if (p == null || p.Value <= 0) { p = 1; } //TODO: I wonder about the performance of this - when we end up with thousands of blog posts, // this will probably not be so efficient. I wonder if using an XPath lookup for batches of children // would work? The children count could be cached. I'd rather not put blog posts under 'month' nodes // just for the sake of performance. Hrm.... Examine possibly too. var totalPosts = contentByTag.PostCount; var pageSize = rootPageModel.PageSize; var totalPages = totalPosts == 0 ? 1 : Convert.ToInt32(Math.Ceiling((double)totalPosts / pageSize)); //Invalid page, redirect without pages if (totalPages < p) { return(new RedirectToUmbracoPageResult(model.Content.Parent, UmbracoContext)); } var pager = new PagerModel( pageSize, p.Value - 1, totalPages, totalPages > p ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p + 1) : null, p > 2 ? model.Content.Url.EnsureEndsWith('?') + "p=" + (p - 1) : p > 1 ? model.Content.Url : null); var listModel = new ListModel(tagPage, contentByTag.Posts, pager); return(View(PathHelper.GetThemeViewPath(listModel, "List"), listModel)); }