public LensflareSceneNode(SceneNode parent, SceneManager mgr, int id, Vector3D position) : base(parent, mgr, id) { draw_flare = true; ign_geom = false; smgr = mgr; indices = new ushort[6]; indices[0] = 0; indices[1] = 2; indices[2] = 1; indices[3] = 0; indices[4] = 3; indices[5] = 2; vertices = new Vertex3D[4]; for (int i = 0; i < 4; i++) { vertices[i] = new Vertex3D(); } vertices[0].TCoords = Vector2D.From(0.0f, 1.0f); vertices[0].Color = Color.White; vertices[1].TCoords = Vector2D.From(0.0f, 0.0f); vertices[1].Color = Color.White; vertices[2].TCoords = Vector2D.From(1.0f, 0.0f); vertices[2].Color = Color.White; vertices[3].TCoords = Vector2D.From(1.0f, 1.0f); vertices[3].Color = Color.White; material = new Material(); material.Lighting = false; material.MaterialType = MaterialType.TransparentAddColor; material.ZBuffer = 0; material.ZWriteEnable = false; bbox = new Box3D(); bbox.MinEdge = Vector3D.From(-2, -2, -2); bbox.MaxEdge = Vector3D.From(2, 2, 2); }
public CustomSceneNode(SceneNode parent, SceneManager mgr, int id) : base(parent, mgr, id) { _mgr = mgr; _driver = _mgr.VideoDriver; Material.Wireframe = false; Material.Lighting = false; Vertices[0] = new Vertex3D(new Vector3D(0, 0, 10), new Vector3D(1, 1, 0), Color.From(255, 0, 255, 255), new Vector2D(0, 1)); Vertices[1] = new Vertex3D(new Vector3D(10, 0, -10), new Vector3D(1, 0, 0), Color.From(255, 255, 0, 255), new Vector2D(1, 1)); Vertices[2] = new Vertex3D(new Vector3D(0, 20, 0), new Vector3D(0, 1, 1), Color.From(255, 255, 255, 0), new Vector2D(1, 0)); Vertices[3] = new Vertex3D(new Vector3D(-10, 0, -10), new Vector3D(0, 0, 1), Color.From(255, 0, 255, 0), new Vector2D(0, 0)); Box = new Box3D(); for (int i = 0; i < Vertices.Length; i++) Box.AddInternalPoint(Vertices[i].Position); }
public static void CreateBox3DFromNode(SceneNode node, out Box3D box) { float minX = float.MaxValue; float minY = float.MaxValue; float minZ = float.MaxValue; float maxX = float.MinValue; float maxY = float.MinValue; float maxZ = float.MinValue; Vector3D[] edges; node.BoundingBox.GetEdges(out edges); Matrix4 m = new Matrix4(); m.RotationDegrees = node.Rotation; m.Translation = node.Position; for (int i = 0; i < edges.Length; i++) { Vector3D v = edges[i] * node.Scale; v = m.TransformVect(ref v); if (v.X < minX) minX = v.X; if (v.Y < minY) minY = v.Y; if (v.Z < minZ) minZ = v.Z; if (v.X > maxX) maxX = v.X; if (v.Y > maxY) maxY = v.Y; if (v.Z > maxZ) maxZ = v.Z; } box = new Box3D(minX, minY, minZ, maxX, maxY, maxZ); }
private void UpdateBoundingBox(MeshSceneNode node) { if (node == null) return; Mesh mesh = node.GetMesh(); if (mesh == null) return; Box3D box = new Box3D(0, 0, 0, 0, 0, 0); for (int i = 0; i < mesh.MeshBufferCount; i++) { mesh.GetMeshBuffer(i).RecalculateBoundingBox(); box.AddInternalBox(mesh.GetMeshBuffer(i).BoundingBox); } mesh.BoundingBox = box; }
public void Draw3DBox(Box3D box, Color color) { VideoDriver_Draw3DBox(_raw, box.ToUnmanaged(), color.ToUnmanaged()); }
public ParticleEmitter CreateBoxEmitter(Box3D box, Vector3D direction, uint minPPS, uint maxPPS, Color minSC, Color maxSC, uint minLT, uint maxLT, int maxAngleDegrees) { return (ParticleEmitter) NativeElement.GetObject(Particle_CreateBoxEmitter(_raw, box.ToUnmanaged(), direction.ToUnmanaged(), minPPS, maxPPS, minSC.ToUnmanaged(), maxSC.ToUnmanaged(), minLT, maxLT, maxAngleDegrees), typeof(ParticleEmitter)); }
public P3DSimplexNoiseTerrain(SceneNode parent, SceneManager mgr, int id, int vertsPerRow, int vertsPerCol, int cellSpacing, float heightScale) : base(parent, mgr, id) { _mgr = mgr; _driver = _mgr.VideoDriver; Material = new Material(); Material.Lighting = false; _numVertsPerRow = vertsPerRow; _numVertsPerCol = vertsPerCol; _cellSpacing = cellSpacing; _heightScale = heightScale; _numCellsPerRow = _numVertsPerRow - 1; _numCellsPerCol = _numVertsPerCol - 1; _width = _numCellsPerRow * _cellSpacing; _depth = _numCellsPerCol * _cellSpacing; NumVertices = _numVertsPerRow * _numVertsPerCol; _numIndices = (_numCellsPerRow * _numCellsPerCol) * 6; _numTriangles = (_numCellsPerRow * _numCellsPerCol) * 2; _indices = new ushort[_numIndices]; int startX = -_width / 2; int startZ = _depth / 2; int endX = _width / 2; int endZ = -_depth / 2; Box3D = new Box3D(new Vector3D(startX, -_heightScale, startZ), new Vector3D(endX, _heightScale, endZ)); float uCoordIncrementSize = 1.0f; float vCoordIncrementSize = 1.0f; _heights = new float[NumVertices]; int i = 0; for (int z = startZ; z >= endZ; z -= _cellSpacing) { int j = 0; for (int x = startX; x <= endX; x += _cellSpacing) { int index = i * _numVertsPerRow + j; float height;// = noise.PerlinNoise1F(x, 100*heightScale, 0.001f); // large noise. height = PerlinSimplexNoise.noise(x * 0.0001f, z * 0.0001f) * _heightScale; // detail noise. height += PerlinSimplexNoise.noise(x * 0.001f, z * 0.001f) * _heightScale / 10; Vertex3D v = new Vertex3D( new Vector3D(x, height, z), new Vector3D(0, 1, 0), Color.Black, new Vector2D(j * uCoordIncrementSize, i * vCoordIncrementSize) ); _buffer.SetVertex((uint)index, v); j++; } i++; } uint baseIndex = 0; for (uint k = 0; k < _numCellsPerRow; k++) { for (uint j = 0; j < _numCellsPerCol; j++) { _buffer.SetIndex(baseIndex + 0, (ushort)(k * _numVertsPerRow + j)); _buffer.SetIndex(baseIndex + 1, (ushort)(k * _numVertsPerRow + j + 1)); _buffer.SetIndex(baseIndex + 2, (ushort)((k + 1) * _numVertsPerRow + j)); _buffer.SetIndex(baseIndex + 3, (ushort)((k + 1) * _numVertsPerRow + j)); _buffer.SetIndex(baseIndex + 4, (ushort)(k * _numVertsPerRow + j + 1)); _buffer.SetIndex(baseIndex + 5, (ushort)((k + 1) * _numVertsPerRow + j + 1)); baseIndex += 6; } } }
public override void Render() { VideoDriver driver = _mgr.VideoDriver; CameraSceneNode camera = _mgr.ActiveCamera; if (camera == null || driver == null) return; if (!redrawnextloop) { driver.SetTransform(TransformationState.World, AbsoluteTransformation); driver.SetMaterial(_material); driver.DrawIndexedTriangleList(Vertices, lastdrawcount * 4, Indices, lastdrawcount * 4); } else { ReallocateBuffers(); Vector3D campos = camera.AbsolutePosition; Box3D cbox = camera.ViewFrustum.BoundingBox; Vector3D pos = Position; int drawcount = 0; int max = (Particles.Length < MaxDensity) ? Particles.Length : MaxDensity; double d = pos.DistanceFrom(campos) / GRASS_PATCH_SIZE; if (d > 1.0) max = (int)(((double)max) / d); //Matrix4 m = new Matrix4(); for (int i = 0; i < max; i++) { int idx = drawcount * 4; GrassParticle particle = Particles[i]; Vector3D gpos = particle.pos + pos; double dist = campos.DistanceFromSQ(gpos); if (dist > NewMath.Sqr(DrawDistance)) continue; if (!cbox.IsPointInside(gpos)) continue; if (dist > NewMath.Sqr(DrawDistance * 0.5)) { if (particle.sprite.Height == 0) { float i1 = ((float)i) / ((float)max); float i2 = ((float)(dist / DrawDistance)) / 2f; if (i1 < i2) continue; } } int igridsize = GRASS_PATCH_SIZE / (int)WindRes; int ihalfres = (int)WindRes / 2; int xgrid = (int)(particle.pos.X / (igridsize) + ihalfres); int zgrid = (int)(particle.pos.Z / (igridsize) + ihalfres); float xnext = particle.pos.X / (GRASS_PATCH_SIZE / WindRes) + (WindRes / 2f) - xgrid; float znext = particle.pos.Z / (GRASS_PATCH_SIZE / WindRes) + (WindRes / 2f) - zgrid; Vector2D wind1 = WindGrid[xgrid * WindRes + zgrid]; Vector2D wind2 = WindGrid[(xgrid + 1) * WindRes + zgrid]; Vector2D wind3 = WindGrid[xgrid * (WindRes + 1) + zgrid]; Vector2D wind4 = WindGrid[(xgrid + 1) * (WindRes + 1) + zgrid]; Vector2D wind2d = wind1 * (1.0f - xnext) * (1.0f - znext) + wind2 * xnext * (1.0f - znext) + wind3 * (1.0f - xnext) * znext + wind4 * xnext * znext; wind2d *= particle.flex; Vector3D wind = new Vector3D(wind2d.X, 0f, wind2d.Y); Color gcol = new Color(particle.color.A, (int)(particle.color.R * 0.8f), (int)(particle.color.G * 0.8f), (int)(particle.color.B * 0.8f)); Vertices[0 + idx].Position = particle.points[0]; Vertices[0 + idx].Color = gcol; Vertices[1 + idx].Position = particle.points[1] + wind; Vertices[1 + idx].Color = particle.color; Vertices[2 + idx].Position = particle.points[2] + wind; Vertices[2 + idx].Color = particle.color; Vertices[3 + idx].Position = particle.points[3]; Vertices[3 + idx].Color = gcol; int arrpos = (_imagecount.Width * particle.sprite.Height) + particle.sprite.Width; Vertices[0 + idx].TCoords = new Vector2D(v1[arrpos], v2[arrpos]); Vertices[1 + idx].TCoords = new Vector2D(v1[arrpos], v3[arrpos]); Vertices[2 + idx].TCoords = new Vector2D(v4[arrpos], v3[arrpos]); Vertices[3 + idx].TCoords = new Vector2D(v4[arrpos], v2[arrpos]); drawcount++; } driver.SetTransform(TransformationState.World, AbsoluteTransformation); driver.SetMaterial(_material); driver.DrawIndexedTriangleList(Vertices, drawcount * 4, Indices, drawcount * 4); lastdrawcount = drawcount; } if (DebugDataVisible == DebugSceneType.BoundingBox) { driver.SetTransform(TransformationState.World, AbsoluteTransformation); Material m = new Material(); m.Lighting = false; driver.SetMaterial(m); driver.Draw3DBox(BoundingBox, Color.From(0, 255, 255, 255)); Box3D b2 = new Box3D(); b2.AddInternalPoint(BoundingBox.MaxEdge * 0.01f); driver.Draw3DBox(b2, Color.From(0, 255, 255, 255)); } }
bool Create(bool save) { Random rand = new Random((int)((100 * gridpos.X) + gridpos.Z)); int count = rand.Next(3000, 3200); _bbox = new Box3D(); Particles = new GrassParticle[count]; /*Matrix4 m = new Matrix4(); m.RotationDegrees = Terrain.Rotation; m.Translation = Terrain.AbsolutePosition; m.MakeInverse();*/ Color[,] TGMRetrieve = TerrainGrassMap.Retrieve(); Color[,] TCMRetrieve = TerrainColourMap.Retrieve(); Color[,] THMRetrieve = TerrainHeightMap.Retrieve(); System.Collections.ArrayList tosave = new System.Collections.ArrayList(); for (int i = 0; i < count; i++) { Particles[i].points = new Vector3D[4]; float x = rand.Next(0, GRASS_PATCH_SIZE * 10) / 10f; float z = rand.Next(0, GRASS_PATCH_SIZE * 10) / 10f; x -= GRASS_PATCH_SIZE / 2f; z -= GRASS_PATCH_SIZE / 2f; Particles[i].pos.X = x; Particles[i].pos.Z = z; Particles[i].flex = rand.Next(0, 100) / 100f; Particles[i].sprite.Width = rand.Next(0, _imagecount.Width); if (i < 30) Particles[i].sprite.Height = rand.Next(0, _imagecount.Height); else Particles[i].sprite.Height = 0; Vector3D p = Position + Particles[i].pos; Dimension2Df size; Vector3D xz = new Vector3D(p.X / Terrain.Scale.X, 0f, p.Z / Terrain.Scale.Z); int x1 = (int)Math.Floor(xz.X); int z1 = (int)Math.Floor(xz.Z); float height; if (x1 < 1 || z1 < 1 || x1 > TerrainHeightMap.OriginalSize.Width - 1 || z1 > TerrainHeightMap.OriginalSize.Height - 1) continue; Color cDensity = TGMRetrieve[x1, z1]; if (rand.Next(0, 255) > cDensity.A || cDensity.A < 1) continue; float ay = THMRetrieve[x1, z1].B * Terrain.Scale.Y; float by = THMRetrieve[x1 + 1, z1].B * Terrain.Scale.Y; float cy = THMRetrieve[x1, z1 + 1].B * Terrain.Scale.Y; float dy = THMRetrieve[x1 + 1, z1 + 1].B * Terrain.Scale.Y; float u1 = xz.X - x1; float v1 = xz.Z - z1; height = ay * (1.0f - u1) * (1.0f - v1) + by * u1 * (1.0f - v1) + cy * (1.0f - u1) * v1 + dy * u1 * v1; size = new Dimension2Df(rand.Next(40, 70), 100); size.Height *= (float)cDensity.B / 200f; Particles[i].pos.Y = height + (size.Height * 0.5f); Particles[i].color = TCMRetrieve[x1, z1]; Particles[i].startColor = TCMRetrieve[x1, z1]; _bbox.AddInternalPoint(Particles[i].pos); Vector3D dimensions = new Vector3D(0.5f * size.Width, -0.5f * size.Height, 0); /*float rotation = rand.Next(0, 3600) / 10f; Matrix4 m2 = new Matrix4(); m2.RotationDegrees = new Vector3D(0, rotation, 0); m2.RotateVect(dimensions);*/ //Vector3D h = new Vector3D(dimensions.X,0.0f,dimensions.Z); //Vector3D v = new Vector3D(0.0f,dimensions.Y,0.0f); Particles[i].points[0] = Particles[i].pos + new Vector3D(dimensions.X, dimensions.Y, dimensions.Z); Particles[i].points[1] = Particles[i].pos + new Vector3D(dimensions.X, -dimensions.Y, dimensions.Z); Particles[i].points[2] = Particles[i].pos - new Vector3D(dimensions.X, dimensions.Y, dimensions.Z); Particles[i].points[3] = Particles[i].pos - new Vector3D(dimensions.X, -dimensions.Y, dimensions.Z); tosave.Add(Particles[i]); } Particles = (GrassParticle[])tosave.ToArray(typeof(GrassParticle)); tosave.Clear(); if (save) return Save(); return true; }
/// <summary> /// Adds an other bounding box to the bounding box, causing it to grow bigger, /// if the box is outside of the box /// </summary> /// <param name="b"> Other bounding box to add into this box.</param> public void AddInternalBox(Box3D b) { AddInternalPoint(b.MaxEdge); AddInternalPoint(b.MinEdge); }
/// <summary> /// Determinates if the box intersects with an other box. /// </summary> /// <param name="other">Other box to check a intersection with.</param> /// <returns> Returns true if there is a intersection with the other box, /// otherwise false.</returns> public bool IntersectsWithBox(Box3D other) { return (MinEdge.X <= other.MaxEdge.X && MinEdge.Y <= other.MaxEdge.Y && MinEdge.Z <= other.MaxEdge.Z && MaxEdge.X >= other.MinEdge.X && MaxEdge.Y >= other.MinEdge.Y && MaxEdge.Z >= other.MinEdge.Z); }
/// <summary> /// Bread and butter of the texture system. /// This is the start point for the texture-> graphics pipeline /// </summary> /// <param name="tex"></param> /// <param name="vObj"></param> /// <param name="AssetID"></param> public void applyTexture(TextureExtended tex, VObject vObj, UUID AssetID) { try { // works if (vObj.Mesh == null) return; // Check if we have a sculptie and its sculpting texture // If yes, don't apply the texture if (vObj.Prim.Sculpt != null && vObj.Prim.Sculpt.SculptTexture == AssetID) { m_log.Debug("[TEXTURE]: Skipping applyTexture for sculpt " + AssetID); return; } bool alphaimage = IsAlphaImage(tex); // MeshPrim if (vObj._3DiIrrfileUUID != UUID.Zero && vObj.IrrData != null) { for (int iTex = 0; iTex < vObj.IrrData.Materials.Count; iTex++) { if (Path.GetFileNameWithoutExtension(vObj.IrrData.Materials[iTex].Texture1) == AssetID.ToString()) { Texture loadedTex = Reference.VideoDriver.GetTexture(AssetID.ToString() + tex.extension); if (vObj.Node.Children.Length > 0) { vObj.Node.Children[0].GetMaterial(iTex).Texture1 = loadedTex; } break; } } if (alphaimage) { vObj.Node.Children[0].SetMaterialType(MaterialType.TransparentAlphaChannel); Reference.SceneManager.RegisterNodeForRendering(vObj.Node.Children[0], SceneNodeRenderPass.Transparent); } } // Normal prim else { // Apply the Texture based on the TextureEntry if (vObj.Prim.Textures != null) { Reference.SceneManager.MeshCache.RemoveMesh(vObj.Mesh); // TODO: Apply texture per face (including DefaultTexture if a FaceTexture was not specified) for (int i = 0; i < vObj.Mesh.MeshBufferCount; i++) { float shinyval = 0; // Check if there is a facetexture for this MB Primitive.TextureEntryFace applyTexture = null; if (i < vObj.Prim.Textures.FaceTextures.Length && vObj.Prim.Textures.FaceTextures[i] != null) { // Apply FaceTexture applyTexture = vObj.Prim.Textures.FaceTextures[i]; } else if (vObj.Prim.Textures.DefaultTexture != null) { // Apply DefaultTexture applyTexture = vObj.Prim.Textures.DefaultTexture; } if (applyTexture != null) { Color4 coldata = applyTexture.RGBA; switch (applyTexture.Shiny) { case Shininess.Low: shinyval = 0.8f; coldata.R *= 0.8f; coldata.B *= 0.8f; coldata.G *= 0.8f; break; case Shininess.Medium: shinyval = 0.7f; coldata.R *= 0.6f; coldata.B *= 0.6f; coldata.G *= 0.6f; break; case Shininess.High: shinyval = 0.6f; coldata.R *= 0.3f; coldata.B *= 0.3f; coldata.G *= 0.3f; break; } if (applyTexture.TextureID == AssetID) { ApplyFaceSettings(vObj, alphaimage, applyTexture, tex, i, shinyval, coldata); } else { // Apply color settings ApplyFaceSettings(vObj, alphaimage, applyTexture, null, i, shinyval, coldata); } vObj.Mesh.GetMeshBuffer(i).Material.NormalizeNormals = true; vObj.Mesh.GetMeshBuffer(i).Material.GouraudShading = true; vObj.Mesh.GetMeshBuffer(i).Material.BackfaceCulling = (texDownloadStyle == TextureDownloadStyle.TEX_DOWNLOAD_ASSETSERVER); } } if (vObj.Node is MeshSceneNode) { MeshSceneNode msn = (MeshSceneNode) vObj.Node; msn.SetMesh(vObj.Mesh); /* if (vObj.Prim.Textures != null) { // Check the default texture to ensure that it's not null (why would it be null?) if (vObj.Prim.Textures.DefaultTexture != null) { Color4 coldata = vObj.Prim.Textures.DefaultTexture.RGBA; IrrlichtNETCP.Color objColor = new Color( Util.Clamp<int>((int) (coldata.A*255), 0, 255), Util.Clamp<int>((int) (coldata.R*255), 0, 255), Util.Clamp<int>((int) (coldata.G*255), 0, 255), Util.Clamp<int>((int) (coldata.B*255), 0, 255) ); // Set material color. for (int i = 0; i < msn.MaterialCount; i++) { msn.GetMaterial(i).AmbientColor = objColor; msn.GetMaterial(i).DiffuseColor = objColor; msn.GetMaterial(i).SpecularColor = Color.Black; msn.GetMaterial(i).EmissiveColor = Color.Black; msn.GetMaterial(i).Shininess = 0; } } } */ Box3D box = new Box3D(0, 0, 0, 0, 0, 0); for (int i = 0; i < msn.GetMesh().MeshBufferCount; i++) { msn.GetMesh().GetMeshBuffer(i).RecalculateBoundingBox(); box.AddInternalBox(msn.GetMesh().GetMeshBuffer(i).BoundingBox); } msn.GetMesh().BoundingBox = box; } else { // Swap out the visible untextured object with a textured one. // SceneNode sn = device.SceneManager.AddMeshSceneNode(vObj.Mesh, ParentNode, -1); // ZAKI: Change TextureManager Parent to actual parent node SceneNode sn = Reference.SceneManager.AddMeshSceneNode(vObj.Mesh, vObj.Node.Parent, -1); sn.Position = vObj.Node.Position; sn.Rotation = vObj.Node.Rotation; sn.Scale = vObj.Node.Scale; sn.DebugDataVisible = DebugSceneType.Off; // If it's translucent, register it for the Transparent phase of rendering if (vObj.Prim.Textures.DefaultTexture != null) { if (vObj.Prim.Textures.DefaultTexture.RGBA.A != 1) { Reference.SceneManager.RegisterNodeForRendering(sn, SceneNodeRenderPass.Transparent); } } // Add the new triangle selector sn.TriangleSelector = Reference.SceneManager.CreateTriangleSelector(vObj.Mesh, sn); sn.TriangleSelector.Drop(); Reference.Viewer.EntityManager.AddTriangleSelector(sn.TriangleSelector, sn); // Delete the old node. SceneNode oldnode = vObj.Node; Reference.Viewer.EntityManager.DeleteNode(oldnode); // Assign new node vObj.Node = sn; } } } // prim texture is not null } catch (AccessViolationException) { VUtil.LogConsole(this.ToString() + "[ACCESSVIOLATION]", " TextureManager::ApplyTexture"); m_log.Error("[TEXTURE]: Failed to load texture."); } catch (NullReferenceException) { m_log.Error("unable to update texture"); } }
private static Mesh FacesToIrrMesh(List<ViewerFace> viewerFaces, int numPrimFaces) { Color color = new Color(255, 255, 255, 255); Mesh mesh; try { mesh = new Mesh(); } catch (IndexOutOfRangeException) { return null; } int numViewerFaces = viewerFaces.Count; MeshBuffer[] mb = new MeshBuffer[numPrimFaces]; for (int i = 0; i < mb.Length; i++) mb[i] = new MeshBuffer(VertexType.Standard); try { uint[] index = new uint[mb.Length]; for (int i = 0; i < index.Length; i++) index[i] = 0; for (uint i = 0; i < numViewerFaces; i++) { ViewerFace vf = viewerFaces[(int)i]; try { mb[vf.primFaceNumber].SetVertex(index[vf.primFaceNumber], new Vertex3D(convVect3d(vf.v1), convNormal(vf.n1), color, convVect2d(vf.uv1))); mb[vf.primFaceNumber].SetVertex(index[vf.primFaceNumber] + 1, new Vertex3D(convVect3d(vf.v2), convNormal(vf.n2), color, convVect2d(vf.uv2))); mb[vf.primFaceNumber].SetVertex(index[vf.primFaceNumber] + 2, new Vertex3D(convVect3d(vf.v3), convNormal(vf.n3), color, convVect2d(vf.uv3))); } catch (OutOfMemoryException) { return null; } catch (IndexOutOfRangeException) { return null; } mb[vf.primFaceNumber].SetIndex(index[vf.primFaceNumber], (ushort)index[vf.primFaceNumber]); mb[vf.primFaceNumber].SetIndex(index[vf.primFaceNumber] + 1, (ushort)(index[vf.primFaceNumber] + 2)); mb[vf.primFaceNumber].SetIndex(index[vf.primFaceNumber] + 2, (ushort)(index[vf.primFaceNumber] + 1)); index[vf.primFaceNumber] += 3; } for (int i = 0; i < mb.Length; i++) { mesh.AddMeshBuffer(mb[i]); } Box3D box = new Box3D(0, 0, 0, 0, 0, 0); for (int i = 0; i < mesh.MeshBufferCount; i++) { mesh.GetMeshBuffer(i).RecalculateBoundingBox(); box.AddInternalBox(mesh.GetMeshBuffer(i).BoundingBox); } mesh.BoundingBox = box; // don't dispose here //mb.Dispose(); } catch (AccessViolationException) { VUtil.LogConsole("[ACCESSVIOLATION]", "PrimMesherG::FacesToIrrMesh"); mesh = null; } return mesh; }
/// <summary> /// Bread and butter of the texture system. /// This is the start point for the texture-> graphics pipeline /// </summary> /// <param name="tex"></param> /// <param name="vObj"></param> /// <param name="AssetID"></param> public void applyTexture(TextureExtended tex, VObject vObj, UUID AssetID) { //return; try { // works if (vObj.Mesh == null) return; // Check if we have a sculptie and its sculpting texture // If yes, don't apply the texture if (vObj.Prim.Sculpt != null && vObj.Prim.Sculpt.SculptTexture == AssetID) { m_log.Debug("[TEXTURE]: Skipping applyTexture for sculpt " + AssetID); return; } bool alphaimage = false; #if YK_ADD_DEFAULT_TEXTURE if (tex == null) tex = defaultTexture; #endif // Check if we've already run this through our image alpha checker if (tex.Userdata == null) { // Check if this image has an alpha channel in use // All textures are 32 Bit and alpha capable, so we have to scan it for an // alpha pixel Color[,] imgcolors; //tex.Lock(); try { imgcolors = tex.Retrieve(); //tex.Unlock(); for (int i = 0; i < imgcolors.GetUpperBound(0); i++) { for (int j = 0; j < imgcolors.GetUpperBound(1); j++) { if (imgcolors[i, j].A != 255) { alphaimage = true; break; } } if (alphaimage) break; } } catch (OutOfMemoryException) { alphaimage = false; } // Save result tex.Userdata = (object)alphaimage; } else { // Use cached result alphaimage = (bool)tex.Userdata; } //#if NOTYET if (vObj._3DiIrrfileUUID != UUID.Zero && vObj.IrrData != null) { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: 3Di mesh applyTexture for tex " + AssetID + " for irrfile " + vObj._3DiIrrfileUUID); #endif for (int iTex = 0; iTex < vObj.IrrData.Materials.Count; iTex++) { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: This mesh references a texture num " + iTex + ": " + vObj.IrrData.Materials[iTex].Texture1); #endif if (System.IO.Path.GetFileNameWithoutExtension(vObj.IrrData.Materials[iTex].Texture1) == AssetID.ToString()) { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Found the texture reference inside the mesh; loading texture and re-assigning the reference."); #endif Texture loadedTex = device.VideoDriver.GetTexture(AssetID.ToString() + tex.extension); if (vObj.Node.Children.Length > 0) { vObj.Node.Children[0].GetMaterial(iTex).Texture1 = loadedTex; } else { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Could not assign texture; mesh child not found"); #endif } } } #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Finished all materials in this mesh."); #endif if (alphaimage) { vObj.Node.Children[0].SetMaterialType(MaterialType.TransparentAlphaChannel); device.SceneManager.RegisterNodeForRendering(vObj.Node.Children[0], SceneNodeRenderPass.Transparent); } } else //#endif // Apply the Texture based on the TextureEntry if(vObj.Prim.Textures != null) { device.SceneManager.MeshCache.RemoveMesh(vObj.Mesh); // Check the default texture to ensure that it's not null (why would it be null?) if (vObj.Prim.Textures.DefaultTexture != null) { Color4 coldata = vObj.Prim.Textures.DefaultTexture.RGBA; float shinyval = 0; switch (vObj.Prim.Textures.DefaultTexture.Shiny) { case Shininess.Low: shinyval = 0.8f; coldata.R *= 0.8f; coldata.B *= 0.8f; coldata.G *= 0.8f; break; case Shininess.Medium: shinyval = 0.7f; coldata.R *= 0.6f; coldata.B *= 0.6f; coldata.G *= 0.6f; break; case Shininess.High: shinyval = 0.6f; coldata.R *= 0.3f; coldata.B *= 0.3f; coldata.G *= 0.3f; break; } // The mesh buffers correspond to the faces defined in the textureentry int mbcount = vObj.Mesh.MeshBufferCount; for (int j = 0; j < mbcount; j++) { // Only apply default texture if there isn't one already! // we don't want to overwrite a face specific texture with the default if (vObj.Prim.Textures.DefaultTexture.TextureID == AssetID) { ApplyFaceSettings(vObj, alphaimage, vObj.Prim.Textures.DefaultTexture, tex, j, shinyval, coldata); } else { // Apply color settings ApplyFaceSettings(vObj, alphaimage, vObj.Prim.Textures.DefaultTexture, null, j, shinyval, coldata); } vObj.Mesh.GetMeshBuffer(j).Material.NormalizeNormals = true; vObj.Mesh.GetMeshBuffer(j).Material.GouraudShading = true; vObj.Mesh.GetMeshBuffer(j).Material.BackfaceCulling = (this.texDownloadStyle == TextureDownloadStyle.TEX_DOWNLOAD_ASSETSERVER); } } // default taken care of.. now on to the individual face settings. for (int i = 0; i < vObj.Prim.Textures.FaceTextures.Length; i++) { if (vObj.Prim.Textures.FaceTextures[i] != null) { Primitive.TextureEntryFace teface = vObj.Prim.Textures.FaceTextures[i]; if (vObj.Mesh.MeshBufferCount > i) { //if (tex. Color4 coldata = teface.RGBA; float shinyval = 0; switch (teface.Shiny) { case Shininess.Low: shinyval = 0.8f; coldata.R *= 0.8f; coldata.B *= 0.8f; coldata.G *= 0.8f; break; case Shininess.Medium: shinyval = 0.7f; coldata.R *= 0.6f; coldata.B *= 0.6f; coldata.G *= 0.6f; break; case Shininess.High: shinyval = 0.6f; coldata.R *= 0.3f; coldata.B *= 0.3f; coldata.G *= 0.3f; break; } // Apply texture only if this face has it linked if (teface.TextureID == AssetID) { ApplyFaceSettings(vObj, alphaimage, teface, tex, i, shinyval, coldata); } else { // Only apply the color settings.. ApplyFaceSettings(vObj, alphaimage, teface, null, i, shinyval, coldata); } vObj.Mesh.GetMeshBuffer(i).Material.NormalizeNormals = true; vObj.Mesh.GetMeshBuffer(i).Material.GouraudShading = true; vObj.Mesh.GetMeshBuffer(i).Material.BackfaceCulling = (this.texDownloadStyle == TextureDownloadStyle.TEX_DOWNLOAD_ASSETSERVER); } else { m_log.Warn("[TEXTUREDEF]: Unable to apply Texture to face because mesh buffer doesn't have definition for face"); } }// end check if textureentry face is null } // end loop over textureentry faces array if (vObj.Node is MeshSceneNode) { MeshSceneNode msn = (MeshSceneNode)vObj.Node; msn.SetMesh(vObj.Mesh); if (vObj.Prim.Textures != null) { // Check the default texture to ensure that it's not null (why would it be null?) if (vObj.Prim.Textures.DefaultTexture != null) { Color4 coldata = vObj.Prim.Textures.DefaultTexture.RGBA; IrrlichtNETCP.Color objColor = new Color( Util.Clamp<int>((int)(coldata.A * 255), 0, 255), Util.Clamp<int>((int)(coldata.R * 255), 0, 255), Util.Clamp<int>((int)(coldata.G * 255), 0, 255), Util.Clamp<int>((int)(coldata.B * 255), 0, 255) ); // Set material color. for (int i = 0; i < msn.MaterialCount; i++) { #if MATERIAL_DEBUG lock(NativeElement.Elements) {System.Diagnostics.Debug.WriteLine("Element count before get:" + NativeElement.Elements.Count);} #endif msn.GetMaterial(i).AmbientColor = objColor; #if MATERIAL_DEBUG lock (NativeElement.Elements) { System.Diagnostics.Debug.WriteLine("Element count after get:" + NativeElement.Elements.Count); } #endif msn.GetMaterial(i).DiffuseColor = objColor; msn.GetMaterial(i).SpecularColor = Color.Black; msn.GetMaterial(i).EmissiveColor = Color.Black; msn.GetMaterial(i).Shininess = 0; } } } #if RECALC_BOUNDINGBOX Box3D box = new Box3D(0, 0, 0, 0, 0, 0); for (int i = 0; i < msn.GetMesh().MeshBufferCount; i++) { msn.GetMesh().GetMeshBuffer(i).RecalculateBoundingBox(); box.AddInternalBox(msn.GetMesh().GetMeshBuffer(i).BoundingBox); } msn.GetMesh().BoundingBox = box; #endif } else { // Swap out the visible untextured object with a textured one. // SceneNode sn = device.SceneManager.AddMeshSceneNode(vObj.Mesh, ParentNode, -1); // ZAKI: Change TextureManager Parent to actual parent node SceneNode sn = device.SceneManager.AddMeshSceneNode(vObj.Mesh, vObj.Node.Parent, -1); sn.Position = vObj.Node.Position; sn.Rotation = vObj.Node.Rotation; sn.Scale = vObj.Node.Scale; sn.DebugDataVisible = DebugSceneType.Off; // If it's translucent, register it for the Transparent phase of rendering if (vObj.Prim.Textures.DefaultTexture.RGBA.A != 1) { device.SceneManager.RegisterNodeForRendering(sn, SceneNodeRenderPass.Transparent); } // Add the new triangle selector sn.TriangleSelector = device.SceneManager.CreateTriangleSelector(vObj.Mesh, sn); sn.TriangleSelector.Drop(); Reference.Viewer.EntityManager.AddTriangleSelector(sn.TriangleSelector, sn); // Delete the old node. SceneNode oldnode = vObj.Node; Reference.Viewer.EntityManager.DeleteNode(oldnode); // Assign new node vObj.Node = sn; } } // prim texture is not null } catch (AccessViolationException) { VUtil.LogConsole(this.ToString() + "[ACCESSVIOLATION]", " TextureManager::ApplyTexture"); m_log.Error("[TEXTURE]: Failed to load texture."); } catch (NullReferenceException) { m_log.Error("unable to update texture"); } }