public bool AddBounds(int currentTime, ref idBounds bounds, bool removeOriginOffset) { if ((_endTime > 0) && (currentTime > _endTime)) { return(false); } idAnim anim = GetAnimation(); if (anim == null) { return(false); } float weight = GetWeight(currentTime); if (weight == 0) { return(false); } int time = GetAnimationTime(currentTime); int animCount = anim.AnimationCount; bool addOrigin = (_allowMove == false) || (removeOriginOffset == false); idBounds b; Vector3 pos; for (int i = 0; i < animCount; i++) { if (anim.GetBounds(out b, i, time, _cycle) == true) { if (addOrigin == true) { anim.GetOrigin(out pos, i, time, _cycle); b.Translate(pos); } bounds.AddBounds(b); } } return(true); }
public idBounds GetBounds(int time, int cycleCount) { FrameBlend frame = ConvertTimeToFrame(time, cycleCount); idBounds bounds = _bounds[frame.Frame1]; bounds.AddBounds(_bounds[frame.Frame2]); // origin position Vector3 offset = _baseFrame[0].Translation; if ((_jointInfo[0].AnimationBits & (AnimationBits.TranslationX | AnimationBits.TranslationY | AnimationBits.TranslationZ)) != 0) { int componentOffset1 = _animatedComponentCount * frame.Frame1 + _jointInfo[0].FirstComponent; int componentOffset2 = _animatedComponentCount * frame.Frame2 + _jointInfo[0].FirstComponent; if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationX) == AnimationBits.TranslationX) { offset.X = _componentFrames[componentOffset1] * frame.FrontLerp + _componentFrames[componentOffset2] * frame.BackLerp; componentOffset1++; componentOffset2++; } if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationY) == AnimationBits.TranslationY) { offset.Y = _componentFrames[componentOffset1] * frame.FrontLerp + _componentFrames[componentOffset2] * frame.BackLerp; componentOffset1++; componentOffset2++; } if ((_jointInfo[0].AnimationBits & AnimationBits.TranslationZ) == AnimationBits.TranslationZ) { offset.Z = _componentFrames[componentOffset1] * frame.FrontLerp + _componentFrames[componentOffset2] * frame.BackLerp; } } bounds.Min -= offset; bounds.Max -= offset; return(bounds); }
/// <summary> /// /// </summary> /// <remarks> /// The mergeShadows option allows surfaces with different textures to share /// silhouette edges for shadow calculation, instead of leaving shared edges /// hanging. /// <para/> /// If any of the original shaders have the noSelfShadow flag set, the surfaces /// can't be merged, because they will need to be drawn in different order. /// <para/> /// If there is only one surface, a separate merged surface won't be generated. /// <para/> /// A model with multiple surfaces can't later have a skinned shader change the /// state of the noSelfShadow flag. /// <para/> /// ----------------- /// <para/> /// Creates mirrored copies of two sided surfaces with normal maps, which would /// otherwise light funny. /// <para/> /// Extends the bounds of deformed surfaces so they don't cull incorrectly at screen edges. /// </remarks> public override void FinishSurfaces() { if (this.Disposed == true) { throw new ObjectDisposedException(this.GetType().Name); } _purged = false; // make sure we don't have a huge bounds even if we don't finish everything _bounds = idBounds.Zero; if (_surfaces.Count == 0) { return; } // renderBump doesn't care about most of this if (_fastLoad == true) { _bounds = idBounds.Zero; foreach (RenderModelSurface surf in _surfaces) { idHelper.BoundTriangleSurface(surf.Geometry); _bounds.AddBounds(surf.Geometry.Bounds); } return; } // cleanup all the final surfaces, but don't create sil edges int totalVerts = 0; int totalIndexes = 0; // decide if we are going to merge all the surfaces into one shadower int numOriginalSurfaces = _surfaces.Count; // make sure there aren't any NULL shaders or geometry for (int i = 0; i < numOriginalSurfaces; i++) { RenderModelSurface surf = _surfaces[i]; if ((surf.Geometry == null) || (surf.Material == null)) { MakeDefault(); idConsole.Error("Model {0}, surface {1} had NULL goemetry", this.Name, i); } if (surf.Material == null) { MakeDefault(); idConsole.Error("Model {0}, surface {1} had NULL material", this.Name, i); } } // duplicate and reverse triangles for two sided bump mapped surfaces // note that this won't catch surfaces that have their shaders dynamically // changed, and won't work with animated models. // It is better to create completely separate surfaces, rather than // add vertexes and indexes to the existing surface, because the // tangent generation wouldn't like the acute shared edges for (int i = 0; i < numOriginalSurfaces; i++) { RenderModelSurface surf = _surfaces[i]; if (surf.Material.ShouldCreateBackSides == true) { idConsole.Warning("TODO: should create back sides"); /*srfTriangles_t *newTri; * * newTri = R_CopyStaticTriSurf( surf->geometry ); * R_ReverseTriangles( newTri ); * * modelSurface_t newSurf; * * newSurf.shader = surf->shader; * newSurf.geometry = newTri; * * AddSurface( newSurf );*/ } } // clean the surfaces // TODO: clean surfaces /*for ( i = 0 ; i < surfaces.Num() ; i++ ) { * const modelSurface_t *surf = &surfaces[i]; * * R_CleanupTriangles( surf->geometry, surf->geometry->generateNormals, true, surf->shader->UseUnsmoothedTangents() ); * if ( surf->shader->SurfaceCastsShadow() ) { * totalVerts += surf->geometry->numVerts; * totalIndexes += surf->geometry->numIndexes; * } * }*/ // add up the total surface area for development information // TODO: surf dev info /*for ( i = 0 ; i < surfaces.Num() ; i++ ) { * const modelSurface_t *surf = &surfaces[i]; * srfTriangles_t *tri = surf->geometry; * * for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) { * float area = idWinding::TriangleArea( tri->verts[tri->indexes[j]].xyz, * tri->verts[tri->indexes[j+1]].xyz, tri->verts[tri->indexes[j+2]].xyz ); * const_cast<idMaterial *>(surf->shader)->AddToSurfaceArea( area ); * } * }*/ // calculate the bounds int surfaceCount = _surfaces.Count; if (surfaceCount == 0) { _bounds = idBounds.Zero; } else { _bounds.Clear(); for (int i = 0; i < surfaceCount; i++) { RenderModelSurface surf = _surfaces[i]; // if the surface has a deformation, increase the bounds // the amount here is somewhat arbitrary, designed to handle // autosprites and flares, but could be done better with exact // deformation information. // Note that this doesn't handle deformations that are skinned in // at run time... if (surf.Material.Deform != DeformType.None) { idConsole.Warning("TODO: deform"); /*srfTriangles_t *tri = surf->geometry; * idVec3 mid = ( tri->bounds[1] + tri->bounds[0] ) * 0.5f; * float radius = ( tri->bounds[0] - mid ).Length(); * radius += 20.0f; * * tri->bounds[0][0] = mid[0] - radius; * tri->bounds[0][1] = mid[1] - radius; * tri->bounds[0][2] = mid[2] - radius; * * tri->bounds[1][0] = mid[0] + radius; * tri->bounds[1][1] = mid[1] + radius; * tri->bounds[1][2] = mid[2] + radius;*/ } // add to the model bounds _bounds.AddBounds(surf.Geometry.Bounds); } } }
/// <summary> /// /// </summary> /// <remarks> /// The mergeShadows option allows surfaces with different textures to share /// silhouette edges for shadow calculation, instead of leaving shared edges /// hanging. /// <para/> /// If any of the original shaders have the noSelfShadow flag set, the surfaces /// can't be merged, because they will need to be drawn in different order. /// <para/> /// If there is only one surface, a separate merged surface won't be generated. /// <para/> /// A model with multiple surfaces can't later have a skinned shader change the /// state of the noSelfShadow flag. /// <para/> /// ----------------- /// <para/> /// Creates mirrored copies of two sided surfaces with normal maps, which would /// otherwise light funny. /// <para/> /// Extends the bounds of deformed surfaces so they don't cull incorrectly at screen edges. /// </remarks> public override void FinishSurfaces() { if(this.Disposed == true) { throw new ObjectDisposedException(this.GetType().Name); } _purged = false; // make sure we don't have a huge bounds even if we don't finish everything _bounds = idBounds.Zero; if(_surfaces.Count == 0) { return; } // renderBump doesn't care about most of this if(_fastLoad == true) { _bounds = idBounds.Zero; foreach(RenderModelSurface surf in _surfaces) { idHelper.BoundTriangleSurface(surf.Geometry); _bounds.AddBounds(surf.Geometry.Bounds); } return; } // cleanup all the final surfaces, but don't create sil edges int totalVerts = 0; int totalIndexes = 0; // decide if we are going to merge all the surfaces into one shadower int numOriginalSurfaces = _surfaces.Count; // make sure there aren't any NULL shaders or geometry for(int i = 0; i < numOriginalSurfaces; i++) { RenderModelSurface surf = _surfaces[i]; if((surf.Geometry == null) || (surf.Material == null)) { MakeDefault(); idConsole.Error("Model {0}, surface {1} had NULL goemetry", this.Name, i); } if(surf.Material == null) { MakeDefault(); idConsole.Error("Model {0}, surface {1} had NULL material", this.Name, i); } } // duplicate and reverse triangles for two sided bump mapped surfaces // note that this won't catch surfaces that have their shaders dynamically // changed, and won't work with animated models. // It is better to create completely separate surfaces, rather than // add vertexes and indexes to the existing surface, because the // tangent generation wouldn't like the acute shared edges for(int i = 0; i < numOriginalSurfaces; i++) { RenderModelSurface surf = _surfaces[i]; if(surf.Material.ShouldCreateBackSides == true) { idConsole.Warning("TODO: should create back sides"); /*srfTriangles_t *newTri; newTri = R_CopyStaticTriSurf( surf->geometry ); R_ReverseTriangles( newTri ); modelSurface_t newSurf; newSurf.shader = surf->shader; newSurf.geometry = newTri; AddSurface( newSurf );*/ } } // clean the surfaces // TODO: clean surfaces /*for ( i = 0 ; i < surfaces.Num() ; i++ ) { const modelSurface_t *surf = &surfaces[i]; R_CleanupTriangles( surf->geometry, surf->geometry->generateNormals, true, surf->shader->UseUnsmoothedTangents() ); if ( surf->shader->SurfaceCastsShadow() ) { totalVerts += surf->geometry->numVerts; totalIndexes += surf->geometry->numIndexes; } }*/ // add up the total surface area for development information // TODO: surf dev info /*for ( i = 0 ; i < surfaces.Num() ; i++ ) { const modelSurface_t *surf = &surfaces[i]; srfTriangles_t *tri = surf->geometry; for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) { float area = idWinding::TriangleArea( tri->verts[tri->indexes[j]].xyz, tri->verts[tri->indexes[j+1]].xyz, tri->verts[tri->indexes[j+2]].xyz ); const_cast<idMaterial *>(surf->shader)->AddToSurfaceArea( area ); } }*/ // calculate the bounds int surfaceCount = _surfaces.Count; if(surfaceCount == 0) { _bounds = idBounds.Zero; } else { _bounds.Clear(); for(int i = 0; i < surfaceCount; i++) { RenderModelSurface surf = _surfaces[i]; // if the surface has a deformation, increase the bounds // the amount here is somewhat arbitrary, designed to handle // autosprites and flares, but could be done better with exact // deformation information. // Note that this doesn't handle deformations that are skinned in // at run time... if(surf.Material.Deform != DeformType.None) { idConsole.Warning("TODO: deform"); /*srfTriangles_t *tri = surf->geometry; idVec3 mid = ( tri->bounds[1] + tri->bounds[0] ) * 0.5f; float radius = ( tri->bounds[0] - mid ).Length(); radius += 20.0f; tri->bounds[0][0] = mid[0] - radius; tri->bounds[0][1] = mid[1] - radius; tri->bounds[0][2] = mid[2] - radius; tri->bounds[1][0] = mid[0] + radius; tri->bounds[1][1] = mid[1] + radius; tri->bounds[1][2] = mid[2] + radius;*/ } // add to the model bounds _bounds.AddBounds(surf.Geometry.Bounds); } } }
public bool AddBounds(int currentTime, ref idBounds bounds, bool removeOriginOffset) { if((_endTime > 0) && (currentTime > _endTime)) { return false; } idAnim anim = GetAnimation(); if(anim == null) { return false; } float weight = GetWeight(currentTime); if(weight == 0) { return false; } int time = GetAnimationTime(currentTime); int animCount = anim.AnimationCount; bool addOrigin = (_allowMove == false) || (removeOriginOffset == false); idBounds b; Vector3 pos; for(int i = 0; i < animCount; i++) { if(anim.GetBounds(out b, i, time, _cycle) == true) { if(addOrigin == true) { anim.GetOrigin(out pos, i, time, _cycle); b.Translate(pos); } bounds.AddBounds(b); } } return true; }
private void ConstrainViewFrustum() { idBounds bounds = new idBounds(); // constrain the view frustum to the total bounds of all visible lights and visible entities // TODO: lights /*for(viewLight_t* vLight = tr.viewDef->viewLights; vLight; vLight = vLight->next) { bounds.AddBounds(vLight->lightDef->frustumTris->bounds); }*/ foreach(ViewEntity viewEntity in _viewDefinition.ViewEntities) { bounds.AddBounds(viewEntity.EntityDef.ReferenceBounds); } _viewDefinition.ViewFrustum.ConstrainToBounds(bounds); float farDistance = idE.CvarSystem.GetFloat("r_useFrustumFarDistance"); if(farDistance > 0.0f) { _viewDefinition.ViewFrustum.MoveFarDistance(farDistance); } }