public bool Create(ref RenderableInfo ri, ref bool m_hasMesh, float priority, int retries) { // collect mesh info // collect morph data // Ogr.CreateAvatarBF() string entitySceneNodeName; string parentSceneNodeName; EntityName entMeshName; if (RendererOgre.GetSceneNodeName(m_ent) == null) { entitySceneNodeName = EntityNameOgre.ConvertToOgreSceneNodeName(m_ent.Name); parentSceneNodeName = EntityNameOgre.ConvertToOgreSceneNodeName(m_ent.RegionContext.Name); IWorldRenderConv wrc; if (m_ent.TryGet<IWorldRenderConv>(out wrc)) { entMeshName = EntityNameOgre.ConvertToOgreMeshName(m_ent.Name); if (!wrc.CreateAvatarMeshResource(0f, m_ent, entMeshName.Name, m_ent.Name)) { // something about this avatar can't be created yet. Try again later. return false; } } else { entMeshName = EntityNameOgre.ConvertToOgreMeshName(new EntityName(m_defaultAvatarMesh)); } IEntityAvatar av; if (m_ent.TryGet<IEntityAvatar>(out av)) { // Create the scene node for this entity // and add the definition for the object on to the scene node // This will cause the load function to be called and create all // the callbacks that will actually create the object m_renderer.m_log.Log(LogLevel.DRENDERDETAIL, "RenderAvatar.Create: mesh={0}, prio={1}", entMeshName.Name, priority); if (!m_renderer.m_sceneMgr.CreateMeshSceneNodeBF(priority, parentSceneNodeName, m_ent, entMeshName.Name, false, true, av.RegionPosition.X, av.RegionPosition.Y, av.RegionPosition.Z, 1f, 1f, 1f, av.Heading.W, av.Heading.X, av.Heading.Y, av.Heading.Z)) { // m_log.Log(LogLevel.DRENDERDETAIL, "Delaying avatar rendering. {0} waiting for parent {1}", // m_ent.Name.Name, (parentSceneNodeName == null ? "NULL" : parentSceneNodeName)); return false; // if I must have parent, requeue if no parent } m_ent.SetAddition(RendererOgre.AddSceneNodeName, entitySceneNodeName); } else { // shouldn't be creating an avatar with no avatar info } } return true; }
public bool Create(ref RenderableInfo ri, ref bool m_hasMesh, float priority, int retries) { lock (m_ent) { if (RendererOgre.GetSceneNodeName(m_ent) == null) { IAttachment atch; if (m_ent.TryGet<IAttachment>(out atch)) { // an attachment is almost a prim, use prim code to get details if (ri == null) { IWorldRenderConv conver; if (m_ent.TryGet<IWorldRenderConv>(out conver)) { ri = conver.RenderingInfo(priority, m_renderer.m_sceneMgr, m_ent, retries); if (ri == null) { // The rendering info couldn't be built now. This is usually because // the parent of this object is not available so we don't know where to put it // m_renderer.m_log.Log(LogLevel.DRENDERDETAIL, // "Delaying rendering. RenderingInfo not built for {0}", m_ent.Name.Name); return false; } } else { m_renderer.m_log.Log(LogLevel.DBADERROR, "DoRenderLater: NO WORLDRENDERCONV FOR PRIM {0}", m_ent.Name.Name); // this probably creates infinite retries but other things are clearly broken return false; } } string entitySceneNodeName = EntityNameOgre.ConvertToOgreSceneNodeName(m_ent.Name); EntityName entMeshName = (EntityName)ri.basicObject; // resolve the name of the parent scene node string parentSceneNodeName = null; if (ri.parentEntity != null) { // this entity has a parent entity. create scene node off his IEntity parentEnt = ri.parentEntity; parentSceneNodeName = EntityNameOgre.ConvertToOgreSceneNodeName(parentEnt.Name); } else { // if no parent, add it at the top level of the region parentSceneNodeName = EntityNameOgre.ConvertToOgreSceneNodeName(m_ent.RegionContext.Name); } if (!m_renderer.m_sceneMgr.CreateMeshSceneNodeBF(priority, parentSceneNodeName, m_ent, entMeshName.Name, false, true, ri.position.X, ri.position.Y, ri.position.Z, ri.scale.X, ri.scale.Y, ri.scale.Z, ri.rotation.W, ri.rotation.X, ri.rotation.Y, ri.rotation.Z)) { // m_log.Log(LogLevel.DRENDERDETAIL, "Delaying rendering. {0} waiting for parent {1}", // m_ent.Name.Name, (parentSceneNodeName == null ? "NULL" : parentSceneNodeName)); return false; // if I must have parent, requeue if no parent } // Add the name of the created scene node name so we know it's created and // we can find it later. m_ent.SetAddition(RendererOgre.AddSceneNodeName, entitySceneNodeName); } } } return true; }
public bool Create(ref RenderableInfo ri, ref bool m_hasMesh, float priority, int retries) { m_renderer.m_log.Log(LogLevel.DRENDERDETAIL, "RenderFoliage: Create"); return true; }
/// <summary> /// Collect rendering info. The information collected for rendering has a pre /// phase (this call), a doit phase and then a post phase (usually on demand /// requests). /// If we can't collect all the information return null. For LLLP, the one thing /// we might not have is the parent entity since child prims are rendered relative /// to the parent. /// This will be called multiple times trying to get the information for the /// renderable. The callCount is the number of times we have asked. The caller /// can pass zero and know nothing will happen. Values more than zero can cause /// this routine to try and do some implementation specific thing to fix the /// problem. For LLLP, this is usually asking for the parent to be loaded. /// </summary> /// <param name="sceneMgr"></param> /// <param name="ent"></param> /// <param name="callCount">zero if do nothing, otherwise the number of times that /// this RenderingInfo has been asked for</param> /// <returns>rendering info or null if we cannot collect all data</returns> public RenderableInfo RenderingInfo(float priority, Object sceneMgr, IEntity ent, int callCount) { LLEntityBase llent; LLRegionContext rcontext; OMV.Primitive prim; // true if we should do the scaling with the rendering parameters bool shouldHaveRendererScale = m_useRendererMeshScaling; try { llent = (LLEntityBase)ent; rcontext = (LLRegionContext)llent.RegionContext; prim = llent.Prim; } catch (Exception e) { m_log.Log(LogLevel.DRENDERDETAIL, "RenderingInfoLL: conversion of pointers failed: " + e.ToString()); throw e; } RenderableInfo ri = new RenderableInfo(); if (prim == null) throw new LookingGlassException("ASSERT: RenderOgreLL: prim is null"); EntityName newMeshName = EntityNameOgre.ConvertToOgreMeshName(ent.Name); ri.basicObject = newMeshName; // pass the name of the mesh that should be created // if a standard type (done by Ogre), let the rendering system do the scaling int meshType = 0; int meshFaces = 0; if (CheckStandardMeshType(prim, out meshType, out meshFaces)) { // if a standard mesh type, use Ogre scaling so we can reuse base shapes shouldHaveRendererScale = true; } // if the prim has a parent, we must hang this scene node off the parent's scene node if (prim.ParentID != 0) { if (ent.ContainingEntity == null) { // NOTE: in theory, the parent container has been resolved before we get here // but it is a legacy feature that the comm system does not hold entities // that don't have their parent so it's possible to get here and find the // parent entity does not exist. If this is the case, we return 'null' saying // we cannot yet build this entity. IEntity parentEntity = null; rcontext.TryGetEntityLocalID(prim.ParentID, out parentEntity); if (parentEntity != null) { ent.ContainingEntity = parentEntity; parentEntity.AddEntityToContainer(ent); } else { // we can't find the parent. Can't build render info. // if we've been waiting for that parent, ask for same if ((callCount != 0) && ((callCount % 3) == 0)) { rcontext.RequestLocalID(prim.ParentID); } return null; } } ri.parentEntity = ent.ContainingEntity; } ri.rotation = prim.Rotation; ri.position = prim.Position; // If the mesh was scaled just pass the renderer a scale of one // otherwise, if the mesh was not scaled, have the renderer do the scaling // This specifies what we want the renderer to do if (shouldHaveRendererScale) { ri.scale = prim.Scale * m_sceneMagnification; } else { ri.scale = new OMV.Vector3(m_sceneMagnification, m_sceneMagnification, m_sceneMagnification); } // Compute a unique hash code for this shape. ri.shapeHash = GetMeshKey(prim, prim.Scale, 0); // while we're in the neighborhood, we can create the materials if (m_buildMaterialsAtRenderInfoTime) { CreateMaterialResource7X(priority, ent, prim, 7); } return ri; }
public bool Create(ref RenderableInfo ri, ref bool m_hasMesh, float priority, int retries) { string entitySceneNodeName = EntityNameOgre.ConvertToOgreSceneNodeName(m_ent.Name); lock (m_ent) { // create the rendering info if not created yet if (ri == null) { IWorldRenderConv conver; if (m_ent.TryGet<IWorldRenderConv>(out conver)) { ri = conver.RenderingInfo(priority, m_renderer.m_sceneMgr, m_ent, retries); if (ri == null) { // The rendering info couldn't be built now. This is usually because // the parent of this object is not available so we don't know where to put it // m_renderer.m_log.Log(LogLevel.DRENDERDETAIL, // "Delaying rendering. RenderingInfo not built for {0}", m_ent.Name.Name); return false; } } else { m_renderer.m_log.Log(LogLevel.DBADERROR, "DoRenderLater: NO WORLDRENDERCONV FOR PRIM {0}", m_ent.Name.Name); // this probably creates infinite retries but other things are clearly broken return false; } } // Check to see if something of this mesh shape already exists. Use it if so. EntityName entMeshName = (EntityName)ri.basicObject; if (m_shouldShareMeshes && (ri.shapeHash != RenderableInfo.NO_HASH_SHARE)) { lock (prebuiltMeshes) { if (prebuiltMeshes.TryGetValue(ri.shapeHash, out entMeshName)) { m_hasMesh = true; // presume someone else created it // m_log.Log(LogLevel.DRENDERDETAIL, "DorRenderLater: using prebuilt {0}", entMeshName); // m_statShareInstances.Event(); } else { // re-get mesh name since TryGet defaults it if not found entMeshName = (EntityName)ri.basicObject; // this is a new mesh. Remember that it has been built prebuiltMeshes.Add(ri.shapeHash, entMeshName); } } } // see if this scene node has already been created if (RendererOgre.GetSceneNodeName(m_ent) == null) { try { // m_log.Log(LogLevel.DRENDERDETAIL, "Adding SceneNode to new entity " + m_ent.Name); // Find a handle to the parent for this node string parentSceneNodeName = null; if (ri.parentEntity != null) { // this entity has a parent entity. create scene node off his IEntity parentEnt = ri.parentEntity; parentSceneNodeName = EntityNameOgre.ConvertToOgreSceneNodeName(parentEnt.Name); } else { // if no parent, add it at the top level of the region parentSceneNodeName = EntityNameOgre.ConvertToOgreSceneNodeName(m_ent.RegionContext.Name); } // Create the mesh if prebilding. The mesh can be either built later on demand or now if // we're forcing the build. if ((m_shouldPrebuildMesh || m_shouldForceMeshRebuild) && !m_hasMesh) { // way kludgy... but we see if the cached mesh file exists and, if so, we don't need to rebuild if (!m_shouldForceMeshRebuild && m_ent.AssetContext.CheckIfCached(entMeshName)) { // if we just want the mesh built, if the file exists that's enough prebuilding m_renderer.m_log.Log(LogLevel.DRENDERDETAIL, "RendererOgre.DorRenderLater: mesh file exists: {0}", m_ent.Name.CacheFilename); m_hasMesh = true; } if (!m_hasMesh) { // TODO: figure out how to do this without queuing -- do it now //2 RequestMesh(m_ent.Name, entMeshName.Name); //1 Object[] meshLaterParams = { entMeshName.Name, entMeshName }; //1 bool worked = RequestMeshLater(qInstance, meshLaterParams); //1 // if we can't get the mesh now, we'll have to wait until all the pieces are here //1 if (!worked) return false; IWorldRenderConv conver; m_ent.TryGet<IWorldRenderConv>(out conver); if (!conver.CreateMeshResource(priority, m_ent, entMeshName.Name, entMeshName)) { // we need to wait until some resource exists before we can complete this creation return false; // note that m_hasMesh is still false so we'll do this routine again } m_renderer.m_log.Log(LogLevel.DRENDERDETAIL, "RendererOgre.DorRenderLater: prebuild/forced mesh build for {0}", entMeshName.Name); // The mesh was crreated into the queued item so if a 'false' is returned // later, we don't create the mesh again. m_hasMesh = true; } } // Create the scene node for this entity // and add the definition for the object on to the scene node // This will cause the load function to be called and create all // the callbacks that will actually create the object m_renderer.m_log.Log(LogLevel.DRENDERDETAIL, "RenderPrim: ent={0}, mesh={1}", m_ent.Name, entMeshName.Name); if (!m_renderer.m_sceneMgr.CreateMeshSceneNodeBF(priority, parentSceneNodeName, m_ent, entMeshName.Name, false, true, ri.position.X, ri.position.Y, ri.position.Z, ri.scale.X, ri.scale.Y, ri.scale.Z, ri.rotation.W, ri.rotation.X, ri.rotation.Y, ri.rotation.Z)) { // m_log.Log(LogLevel.DRENDERDETAIL, "Delaying rendering. {0} waiting for parent {1}", // m_ent.Name.Name, (parentSceneNodeName == null ? "NULL" : parentSceneNodeName)); return false; // if I must have parent, requeue if no parent } // Add the name of the created scene node name so we know it's created and // we can find it later. m_ent.SetAddition(RendererOgre.AddSceneNodeName, entitySceneNodeName); } catch (Exception e) { m_renderer.m_log.Log(LogLevel.DBADERROR, "Render: Failed conversion of {0}: {1}", m_ent.Name.Name, e.ToString()); } } else { // the entity already has a scene node. We're just forcing the rebuild of the prim m_renderer.m_log.Log(LogLevel.DRENDERDETAIL, "DoRenderLater: entity has scenenode. Rebuilding mesh: {0}", entMeshName); m_renderer.RequestMesh(m_ent.Name, entMeshName.Name); } return true; } }