public override void OnInspectorGUI() { base.OnInspectorGUI(); _lod = target as LOD; float newPerc = EditorGUILayout.Slider( "Size Percentage", _lod.percentageSizeOnScreen, 1.0f, 0.0f, GUILayout.ExpandWidth(true)); if ( newPerc != _lod.percentageSizeOnScreen ) { if ( newPerc < _lod.percentageSizeOnScreen ) { } //moveBack = true; } else { //moveBack = false; } _lod.percentageSizeOnScreen = newPerc; for( int i = 0; i < _lod.renderers.Length; i++ ) { _lod.renderers[i] = EditorGUILayout.ObjectField(((LODLevel)i).ToString(), _lod.renderers[i], typeof(Renderer), true, GUILayout.ExpandWidth(true)) as Renderer; } if ( GUILayout.Button( "Recalculate Bounds", GUILayout.ExpandWidth(true) ) ) { _lod.RecalcBounds(); } }
public void CreateLODGroup() { var lodGroup = gameObject.GetComponent<LODGroup>(); if ( lodGroup == null ) lodGroup = gameObject.AddComponent<LODGroup>(); // // Kill all old LODGroups // { var emptyLOD = new LOD[1]; foreach ( var lod in GetComponentsInChildren<LODGroup>() ) { if ( lodGroup == lod ) continue; lod.SetLODS( emptyLOD ); GameObject.Destroy( lod ); } } var renderers = GetComponentsInChildren<Renderer>(); var lods = new LOD[4]; for ( int i=0; i < 4; i++ ) { lods[i].renderers = renderers.Where( x => x.name.EndsWith( "_LOD" + i ) || x.name.EndsWith( "_LOD0" + i ) ).ToArray(); } lods[0].screenRelativeTransitionHeight = 0.50f; lods[1].screenRelativeTransitionHeight = 0.25f; lods[2].screenRelativeTransitionHeight = 0.10f; lods[3].screenRelativeTransitionHeight = 0.02f; lodGroup.SetLODS( lods ); }
//**************************************************************************************************** // //**************************************************************************************************** public FSFilter(FSFilter o) { m_selectionLevel = o.m_selectionLevel; m_displayLevel = o.m_displayLevel; m_pattern = o.m_pattern; }
//**************************************************************************************************** // //**************************************************************************************************** public FSFilter(LOD paramSelectionLevel, string paramPattern = "*") { selectionLevel = paramSelectionLevel; displayLevel = LOD.FILE; pattern = paramPattern; }
void ChangeLOD() { if (Selection.objects == null) { return; } foreach (GameObject g in Selection.objects) { var LODGroups = g.GetComponentsInChildren <LODGroup>(); foreach (var r in LODGroups) { if (r != null) { Debug.Log("Current LODGourps is on:" + g.name + " LOD1 Percents:" + LOD1Per); LOD[] LG = r.GetLODs(); LOD[] lods = new LOD[2]; if (LG != null) { for (int i = 0; i < 2; i++) { Renderer[] rens; if (LG[i].renderers.Length == 1) { rens = new Renderer[1]; rens[0] = LG[i].renderers[0]; } else { rens = new Renderer[2]; rens[0] = LG[i].renderers[0]; rens[1] = LG[i].renderers[1]; } float relHei = 1.0f; switch (i) { case 0: relHei = LOD1Per; break; case 1: relHei = CulledPer; break; } lods[i] = new LOD(relHei, rens); Debug.Log("Change LOD percents!" + LG[i].renderers[0].name + " " + LG[i].screenRelativeTransitionHeight); } r.SetLODs(lods); r.RecalculateBounds(); //LG[1].screenRelativeTransitionHeight = LOD1Per; Debug.Log("Finish LOD Construct!:"); } } } } }
//Install LOD information void InstallLods() { if (this.transform == null || this.transform.childCount == 0) { return; } Transform baseTurrel = this.transform.GetChild(0); if (baseTurrel != null) { LODGroup oldLod = baseTurrel.gameObject.GetComponent <LODGroup>(); if (oldLod == null) { LODGroup lod = baseTurrel.gameObject.AddComponent <LODGroup>(); Renderer[] rends = baseTurrel.gameObject.GetComponentsInChildren <Renderer>(); List <List <Renderer> > renderers = new List <List <Renderer> >(); for (int i = 0; i < rends.Length; i++) { string curName = rends[i].gameObject.name; if (curName[curName.Length - 1] == ')') { string cuting = "(Clone)"; curName = curName.Replace(cuting, ""); } int lodGroup = -1; if (int.TryParse(curName[curName.Length - 1].ToString(), out lodGroup)) { if (renderers.Count <= lodGroup + 1) { for (int j = 0; j < lodGroup + 1 - renderers.Count; j++) { renderers.Add(new List <Renderer>()); } } renderers[lodGroup].Add(rends[i]); } } LOD[] lods = new LOD[renderers.Count]; for (int i = 0; i < lods.Length; i++) { lods[i].renderers = renderers[i].ToArray(); float x = 10f / lods.Length * (i + 1); if (i < lods.Length * 0.5f) { lods[i].screenRelativeTransitionHeight = (-1.5f * x + 10f) / 10f + 0.02f; } else { lods[i].screenRelativeTransitionHeight = (-0.5f * x + 5f) / 10f + 0.02f; } } lod.SetLODs(lods); lod.RecalculateBounds(); } } }
public void ConvertMTKToRenderModel(M2TStructure structure) { List <Vertex[]> vertices = new List <Vertex[]>(); LODs = new LOD[structure.Lods.Length]; for (int i = 0; i != structure.Lods.Length; i++) { M2TStructure.Lod lod = structure.Lods[i]; vertices.Add(lod.Vertices); LOD lod2 = new LOD(); lod2.Indices = lod.Indices; lod2.ModelParts = new ModelPart[lod.Parts.Length]; for (int y = 0; y != lod.Parts.Length; y++) { ModelPart part = new ModelPart(); part.NumFaces = lod.Parts[y].NumFaces; part.StartIndex = lod.Parts[y].StartIndex; part.MaterialHash = lod.Parts[y].Hash; switch (part.MaterialHash) { case 1337: part.Material = RenderStorageSingleton.Instance.Prefabs.GizmoRed; break; case 1338: part.Material = RenderStorageSingleton.Instance.Prefabs.GizmoBlue; break; case 1339: part.Material = RenderStorageSingleton.Instance.Prefabs.GizmoGreen; break; default: part.Material = MaterialsManager.LookupMaterialByHash(part.MaterialHash); break; } lod2.ModelParts[y] = part; } lod2.Vertices = new VertexLayouts.NormalLayout.Vertex[lod.Vertices.Length]; for (int y = 0; y != lod.Vertices.Length; y++) { var vertice = new VertexLayouts.NormalLayout.Vertex(); vertice.Position = lod.Vertices[y].Position; vertice.Normal = lod.Vertices[y].Normal; vertice.Tangent = lod.Vertices[y].Tangent; vertice.TexCoord0 = lod.Vertices[y].UVs[0]; vertice.TexCoord7 = lod.Vertices[y].UVs[3]; lod2.Vertices[y] = vertice; } LODs[i] = lod2; } BoundingBox = BoundingBoxExtenders.CalculateBounds(vertices); SetupShaders(); }
/// <summary> /// Obtiene una lista de nodos dibujados en el último frame /// </summary> /// <returns>Devuelve la lista de nodos dibujados en el último frame, o null si no se ha inicializado</returns> internal SceneryInfoNodeDrawn[] GetNodesDrawn(LOD lod) { if (this.Root != null) { return(this.Root.GetNodesDrawn(lod)); } return(new SceneryInfoNodeDrawn[] { }); }
// Token: 0x060024A7 RID: 9383 RVA: 0x000B3548 File Offset: 0x000B1748 private void GetSetup() { LOD[] array = new LOD[this.lodGroupParentIndex + 1]; for (int i = 0; i < array.Length; i++) { array[i] = default(LOD); array[i].screenRelativeTransitionHeight = this.meshCombiner.lodGroupsSettings[this.lodGroupParentIndex].lodSettings[i].screenRelativeTransitionHeight; } this.lodGroup.SetLODs(array); }
public void CreateLodGroupColliders(LODGroup lodGroup, Transform parentT) { var lodGroupGO = new GameObject("L_" + lodGroup.name); Transform lodGroupT = lodGroupGO.transform; lodGroupT.parent = parentT; LOD[] lods = lodGroup.GetLODs(); bool meshColliderCreated = false; for (int i = 0; i < lods.Length; i++) { LOD lod = lods[i]; LodLevel lodLevel = new LodLevel(); Renderer[] rs = lod.renderers; for (int j = 0; j < rs.Length; j++) { Renderer r = rs[j]; GameObject go = r.gameObject; if (r.enabled && go.activeInHierarchy) { MeshFilter mf = go.GetComponent <MeshFilter>(); if (mf == null) { continue; } Mesh mesh = mf.sharedMesh; if (mesh == null) { continue; } meshColliderCreated = true; MeshCollider mc = CreateMeshCollider(mf, lodGroupT, "L" + i + "_"); lodLevel.colliders.Add(mc); lodLevel.gos.Add(mc.gameObject); lodInfoLookup.Add(mc, this); lodGroupMeshes.Add(mesh); } } lodLevels.Add(lodLevel); } if (meshColliderCreated) { lodInfos.Add(this); } }
private void ApplyLodSettings() { lodGroup = FindObjectsOfType <LODGroup>(); for (int a = 0; a < lodGroup.Length; a++) { var lod = lodGroup[a].GetLODs(); lod[0] = new LOD(0.15f, lod[0].renderers); lodGroup[a].SetLODs(lod); lodGroup[a].RecalculateBounds(); } }
public static void GenerateEvent(EventType type) { if (!ServerManager.Instance.StartedEvents.Contains(type)) { Task.Factory.StartNew(() => { ServerManager.Instance.StartedEvents.Add(type); switch (type) { case EventType.RANKINGREFRESH: ServerManager.Instance.RefreshRanking(); ServerManager.Instance.StartedEvents.Remove(EventType.RANKINGREFRESH); break; case EventType.LOD: LOD.GenerateLod(); break; case EventType.MINILANDREFRESHEVENT: MinilandRefresh.GenerateMinilandEvent(); break; case EventType.INSTANTBATTLE: InstantBattle.GenerateInstantBattle(); break; case EventType.LODDH: LOD.GenerateLod(35); break; case EventType.METEORITEGAME: MeteoriteGame.GenerateMeteoriteGame(); break; case EventType.ACT4SHIP: ACT4SHIP.GenerateAct4Ship(1); ACT4SHIP.GenerateAct4Ship(2); break; case EventType.TALENTARENA: TalentArena.Run(); break; case EventType.CALIGOR: CaligorRaid.Run(); break; case EventType.TOXIC: LevelRaid.GenerateLevelRaid(); break; } }); } }
public override int GetSize() { var Size = base.GetSize(); Size += sizeof(byte); //Number of LODs foreach (var LOD in LODs) { Size += LOD.GetSize(); } return(Size); }
void GetSetup() { LOD[] lods = new LOD[lodGroupParentIndex + 1]; for (int i = 0; i < lods.Length; i++) { lods[i] = new LOD(); lods[i].screenRelativeTransitionHeight = meshCombiner.lodGroupsSettings[lodGroupParentIndex].lodSettings[i].screenRelativeTransitionHeight; } lodGroup.SetLODs(lods); }
public void setLOD(GameObject obj, float screenRelativeTransitionHeight) { LODGroup lodGroup = obj.AddComponent <LODGroup>(); List <Renderer> renderers = new List <Renderer>(obj.GetComponents <Renderer>()); foreach (Transform t in obj.GetComponentsInChildren <Transform>()) { renderers.AddRange(t.GetComponents <Renderer>()); } LOD[] lods = new LOD[] { new LOD(screenRelativeTransitionHeight, renderers.ToArray()) }; lodGroup.SetLODs(lods); }
public override void OnBuildChunk(ChunkDataContext context) { if (_mesh == null) { return; } foreach (VoxelPrimitive it in context.model.GetEnumerator(this.material.GetInstanceID())) { Vector3 pos, scale; it.GetTranslateScale(out pos, out scale); var actors = new GameObject(this.name); actors.isStatic = gameObject.isStatic; actors.tag = gameObject.tag; actors.layer = gameObject.layer; actors.transform.parent = context.parent.transform; actors.transform.localPosition = transform.position + pos; actors.transform.localRotation = transform.rotation; actors.transform.localScale = Vector3.Scale(transform.localScale, scale); actors.AddComponent <MeshFilter>().sharedMesh = _mesh; if (_meshMaterial) { var clone = actors.AddComponent <MeshRenderer>(); clone.material = _meshMaterial; if (_lods != null) { LOD[] lods = new LOD[_lods.Length]; for (int i = 0; i < _lods.Length; i++) { if (lods[i].renderers.Length > 0) { lods[i].renderers[0] = clone; } } actors.AddComponent <LODGroup>().SetLODs(_lods); } } if (_physicMaterial != null) { var meshCollider = actors.AddComponent <MeshCollider>(); meshCollider.sharedMesh = _mesh; meshCollider.material = _physicMaterial; } } }
static void AddMRLG() { GameObject[] gobs = Selection.gameObjects; foreach (GameObject gob in gobs) { LODGroup g = gob.AddComponent <LODGroup> (); LOD[] lods = new LOD[1]; lods [0].screenRelativeTransitionHeight = 0.11f; lods [0].renderers = gob.GetComponentsInChildren <Renderer> (); g.SetLODs(lods); g.RecalculateBounds(); } }
public void AddIt() { LODGroup lODGroup = this.gameObject.GetComponent <LODGroup>(); LOD[] Lods = new LOD[1]; // Fill up Renderer[] arrays. This is the list of drawables per LOD level Lods[0].renderers = this.GetComponentsInChildren <Renderer>(); // Make it live! lODGroup.SetLODS(Lods); lODGroup.RecalculateBounds(); }
public void Initialize(BuildingInstance buildingInput) { DFHack.DFCoord pos = new DFHack.DFCoord( (buildingInput.pos_x_min + buildingInput.pos_x_max) / 2, (buildingInput.pos_y_min + buildingInput.pos_y_max) / 2, buildingInput.pos_z_max); //always update building rotation because that depends on outside stuff if (MapDataStore.Main[pos] != null && rotationType != RotationType.BuildingDirection) { transform.localRotation = MeshContent.TranslateRotation(rotationType, MapDataStore.Main[pos]); } if (originalBuilding != null && originalBuilding.active == buildingInput.active && originalBuilding.items.Count == buildingInput.items.Count && originalBuilding.pos_x_min == buildingInput.pos_x_min && originalBuilding.pos_y_min == buildingInput.pos_y_min) { return; //There's nothing changed. } originalBuilding = buildingInput; foreach (var part in parts) { part.UpdatePart(buildingInput); } var group = GetComponent <LODGroup>(); if (group == null) { group = gameObject.AddComponent <LODGroup>(); var lods = new LOD[1]; lods[0] = new LOD(0.05f, GetComponentsInChildren <MeshRenderer>()); group.SetLODs(lods); group.RecalculateBounds(); } UpdateTilePositions(buildingInput); foreach (var item in GetComponentsInChildren <Collider>()) { if (item.GetComponent <BuildingSelect>() == null) { item.gameObject.AddComponent <BuildingSelect>().root = this; } } }
void AddLODs() { if (GetComponent <LODGroup>()) { LOD[] lods = new LOD[1]; Renderer[] renderers = new Renderer[1]; renderers[0] = mergedMesh.GetComponent <Renderer>(); lods[0] = new LOD(0.0045f, renderers); GetComponent <LODGroup>().SetLODs(lods); GetComponent <LODGroup>().RecalculateBounds(); } }
// Token: 0x06000032 RID: 50 RVA: 0x000029DC File Offset: 0x00000BDC private static void ConvertPoints(ODOL odol, MLOD_LOD dstLod, LOD srcLod) { Vector3P boundingCenter = odol.modelInfo.boundingCenter; Vector3P bboxMinVisual = odol.modelInfo.bboxMinVisual; Vector3P bboxMaxVisual = odol.modelInfo.bboxMaxVisual; int num = srcLod.Vertices.Length; dstLod.points = new Point[num]; for (int i = 0; i < num; i++) { Vector3P pos = srcLod.Vertices[i] + boundingCenter; dstLod.points[i] = new Point(pos, Conversion.clipFlagsToPointFlags(srcLod.ClipFlags[i])); } }
void Start() { // Programmatically create a LOD group and add LOD levels. // Create a GUI that allows for forcing a specific LOD level. group = gameObject.GetComponent <LODGroup>(); // Add 4 LOD levels LOD[] lods = new LOD[3]; for (int i = 0; i < group.lodCount; i++) { PrimitiveType primType = PrimitiveType.Cube; switch (i) { case 1: primType = PrimitiveType.Capsule; break; case 2: primType = PrimitiveType.Sphere; break; case 3: primType = PrimitiveType.Cylinder; break; } GameObject go = GameObject.CreatePrimitive(primType); go.transform.parent = gameObject.transform; Renderer[] renderers = new Renderer[1]; renderers[0] = go.GetComponent <Renderer>(); float screenRelativeTransitionHeight = 1f; switch (i) { case 1: screenRelativeTransitionHeight = 0.25f; break; case 2: screenRelativeTransitionHeight = 0.05f; break; case 3: screenRelativeTransitionHeight = 0.02f; break; } lods[i] = new LOD(screenRelativeTransitionHeight, renderers); } group.SetLODs(lods); group.RecalculateBounds(); }
/// <summary> /// Obtiene la lista de nodos dibujados /// </summary> /// <returns>Lista de nodos dibujados</returns> public virtual SceneryInfoNodeDrawn[] GetNodesDrawn(LOD lod) { List <SceneryInfoNodeDrawn> nodesDrawn = new List <SceneryInfoNodeDrawn>(); if (ToDraw) { foreach (SceneryNode node in Childs.Values) { nodesDrawn.AddRange(node.GetNodesDrawn(lod)); } } return(nodesDrawn.ToArray()); }
public override int FromBytes(byte[] _FromBytes, int _Head) { int Head = _Head; Head += base.FromBytes(_FromBytes, Head); Convert.BytesToValue(out byte LODsCount, _FromBytes, ref Head); for (byte i = 0; i < LODsCount; ++i) { LODs.Add(LOD.FromBytes(_FromBytes, ref Head)); } return(Head - _Head); }
public override int ToBytes(byte[] _WriteToBytes, int _Head) { int Head = _Head; Head += base.ToBytes(_WriteToBytes, Head); Convert.ValueToBytes((byte)LODs.Count, _WriteToBytes, ref Head); foreach (var LOD in LODs) { LOD.ToBytes(_WriteToBytes, ref Head); } return(Head - _Head); }
void AddObjectInternal(Transform t, Vector3 position, bool addToSingle, int lodLevel) { if (level == maxLevels) { MaxCell thisCell = (MaxCell)this; if (thisCell.lods == null) { thisCell.lods = new LOD[lodCount]; } if (thisCell.lods[lodLevel] == null) { thisCell.lods[lodLevel] = new LOD(); } LOD lod = thisCell.lods[lodLevel]; if (lod.transforms == null) { lod.transforms = new List <Transform>(); } if (addToSingle) { lod.singleTransforms.Add(t); } else { lod.transforms.Add(t); } lod.objectCount++; MeshFilter mf = t.GetComponent <MeshFilter>(); Mesh m = mf.sharedMesh; lod.vertCount += m.vertexCount; return; } else { bool maxCellCreated; int index = AddCell <Cell, MaxCell>(ref cells, position, out maxCellCreated); if (maxCellCreated) { MaxCell.maxCellCount++; } cells[index].AddObjectInternal(t, position, addToSingle, lodLevel); } }
// Token: 0x06000030 RID: 48 RVA: 0x00002774 File Offset: 0x00000974 private static MLOD_LOD OdolLod2MLOD(ODOL odol, LOD src) { MLOD_LOD mlod_LOD = new MLOD_LOD(src.Resolution); int vertexCount = src.VertexCount; Conversion.ConvertPoints(odol, mlod_LOD, src); mlod_LOD.normals = src.Normals; Conversion.ConvertFaces(odol, mlod_LOD, src); float mass = odol.modelInfo.mass; Skeleton skeleton = odol.Skeleton; mlod_LOD.taggs = new List <Tagg>(); if (src.Resolution == 1E+13f) { MassTagg item = Conversion.createMassTagg(vertexCount, mass); mlod_LOD.taggs.Add(item); } IEnumerable <UVSetTagg> collection = Conversion.createUVSetTaggs(src); mlod_LOD.taggs.AddRange(collection); IEnumerable <PropertyTagg> collection2 = Conversion.createPropertyTaggs(src); mlod_LOD.taggs.AddRange(collection2); IEnumerable <NamedSelectionTagg> collection3 = Conversion.createNamedSelectionTaggs(src); mlod_LOD.taggs.AddRange(collection3); IEnumerable <AnimationTagg> collection4 = Conversion.createAnimTaggs(src); mlod_LOD.taggs.AddRange(collection4); if (Resolution.KeepsNamedSelections(src.Resolution)) { return(mlod_LOD); } Dictionary <string, List <Conversion.PointWeight> > nsPoints = new Dictionary <string, List <Conversion.PointWeight> >(); Dictionary <string, List <int> > nsFaces = new Dictionary <string, List <int> >(); Conversion.ReconstructNamedSelectionBySections(src, out nsPoints, out nsFaces); Dictionary <string, List <Conversion.PointWeight> > nsPoints2 = new Dictionary <string, List <Conversion.PointWeight> >(); Dictionary <string, List <int> > nsFaces2 = new Dictionary <string, List <int> >(); Conversion.ReconstructProxies(src, out nsPoints2, out nsFaces2); Dictionary <string, List <Conversion.PointWeight> > nsPoints3 = new Dictionary <string, List <Conversion.PointWeight> >(); Conversion.ReconstructNamedSelectionsByBones(src, odol.Skeleton, out nsPoints3); Conversion.ApplySelectedPointsAndFaces(mlod_LOD, nsPoints, nsFaces); Conversion.ApplySelectedPointsAndFaces(mlod_LOD, nsPoints2, nsFaces2); Conversion.ApplySelectedPointsAndFaces(mlod_LOD, nsPoints3, null); return(mlod_LOD); }
private void SavePrefabs(Mesh[,,] generatedMeshes, GrassBakeSettings grassBakeSettings, string path) { GameObject topParentObject = new GameObject(); Vector2 tileSize = grassBakeSettings.extents / grassBakeSettings.numTiles; for (int x = 0; x < generatedMeshes.GetLength(0); ++x) { for (int y = 0; y < generatedMeshes.GetLength(1); ++y) { GameObject tileParentObject = new GameObject(); tileParentObject.transform.parent = topParentObject.transform; tileParentObject.name = "Tile" + x + y; LODGroup lodGroup = tileParentObject.AddComponent <LODGroup>(); LOD[] lods = new LOD[generatedMeshes.GetLength(2)]; for (int i = 0; i < generatedMeshes.GetLength(2); ++i) { GameObject generatedGrass = new GameObject(); generatedGrass.name = "" + x + y + "_LOD" + i; generatedGrass.transform.position = new Vector3( x * tileSize.x - generatedMeshes.GetLength(0) * tileSize.x / 2f, 0f, y * tileSize.y - generatedMeshes.GetLength(1) * tileSize.y / 2f); MeshFilter meshFilter = generatedGrass.AddComponent <MeshFilter>(); meshFilter.sharedMesh = generatedMeshes[x, y, i]; MeshRenderer meshRenderer = generatedGrass.AddComponent <MeshRenderer>(); meshRenderer.sharedMaterial = grassBakeSettings.grassLODLevelSettings[i].grassMaterial; generatedGrass.transform.parent = tileParentObject.transform; Renderer[] renderers = new Renderer[1]; renderers[0] = meshRenderer; lods[i] = new LOD(grassBakeSettings.grassLODLevelSettings[i].lodPercent, renderers); } lodGroup.SetLODs(lods); lodGroup.RecalculateBounds(); } } PrefabUtility.SaveAsPrefabAsset(topParentObject, path); DestroyImmediate(topParentObject); AssetDatabase.SaveAssets(); }
private void UpdateLODDataDistances(TreeSystemPrototypeData data) { float lodMultiplier = 1; LOD[] lods = data.m_TreePrototype.GetComponent <LODGroup>().GetLODs(); TreeSystemLODData[] lodData = data.m_LODData; for (int i = 0; i < lodData.Length; i++) { // If it's the billboard move on if (i == lods.Length - 1) { continue; } TreeSystemLODData d = lodData[i]; LOD lodCrt = new LOD(); LOD lodPrv = new LOD(); lodCrt = lods[i]; lodCrt.screenRelativeTransitionHeight *= lodMultiplier; if (i > 0) { lodPrv = lods[i - 1]; lodPrv.screenRelativeTransitionHeight *= lodMultiplier; } if (i == 0) { // If it's first 3D LOD d.m_StartDistance = 0; d.m_EndDistance = ((1.0f - lodCrt.screenRelativeTransitionHeight) * m_Settings.m_MaxTreeDistance); } else if (i == lodData.Length - 2) { // If it's last 3D LOD d.m_StartDistance = ((1.0f - lodPrv.screenRelativeTransitionHeight) * m_Settings.m_MaxTreeDistance); d.m_EndDistance = m_Settings.m_MaxTreeDistance; } else { // If it's a LOD in between d.m_StartDistance = ((1.0f - lodPrv.screenRelativeTransitionHeight) * m_Settings.m_MaxTreeDistance); d.m_EndDistance = ((1.0f - lodCrt.screenRelativeTransitionHeight) * m_Settings.m_MaxTreeDistance); } } }
public void AssignLODGroup(MeshCombiner meshCombiner) { LOD[] lods = new LOD[lodLevels.Length]; int lodGroupParentIndex = lods.Length - 1; for (int i = 0; i < lodLevels.Length; i++) { LODLevel lodLevel = lodLevels[i]; // Debug.Log(i + " " + lodLevel.newMeshRenderers.Count); lods[i] = new LOD(meshCombiner.lodGroupsSettings[lodGroupParentIndex].lodSettings[i].screenRelativeTransitionHeight, lodLevel.newMeshRenderers.ToArray()); } lodGroup.SetLODs(lods); lodGroup.size = meshCombiner.cellSize; }
void MakeTile(int xLoc, int yLoc) { string Name = xLoc + "_" + yLoc; GameObject Empty = new GameObject(Name); Empty.transform.SetParent(this.transform); Empty.transform.position = new Vector3(xLoc * TileSize, 0f, yLoc * TileSize); Empty.transform.localScale = new Vector3(TileSize, 1f, TileSize); LODGroup LOD = Empty.AddComponent(typeof(LODGroup)) as LODGroup; LOD[] meshLODS = new LOD[5]; meshLODS[0] = MakeLOD(1, Empty, .8f); //LOD[] quickLODS = new LOD[1]; //quickLODS[0] = meshLODS[0]; //LOD.SetLODs(quickLODS); //LOD.RecalculateBounds(); meshLODS[1] = MakeLOD(2, Empty, 0.5f); meshLODS[2] = MakeLOD(4, Empty, 0.25f); meshLODS[3] = MakeLOD(8, Empty, 0.1f); meshLODS[4] = MakeLOD(16, Empty, 0f); LOD.SetLODs(meshLODS); LOD.fadeMode = LODFadeMode.CrossFade; //LOD.RecalculateBounds(); for (int i = 0; i < NumberPerTile; i++) { GameObject Obj = Instantiate(Tree, Vector3.zero, Quaternion.identity); Obj.transform.SetParent(Empty.transform); Obj.transform.localPosition = Vector3.zero; Obj.transform.position += new Vector3(Random.Range(0f, TileSize), 0f, Random.Range(0f, TileSize)); //Obj.transform.position += new Vector3(0f, GetNoiseSample(Obj.transform.localPosition.x + xLoc * TileSize, Obj.transform.localPosition.z + yLoc * TileSize), 0f); //Obj.transform.position += new Vector3(-Size/2f, YOffset, -Size/2f); Obj.transform.position += new Vector3(0f, GetNoiseSample((Obj.transform.localPosition.x / TileVertices * TileSize) + Empty.transform.position.x, (Obj.transform.localPosition.z / TileVertices * TileSize) + Empty.transform.position.z) / 2f, 0f); } }
public static LODNode CreateLOD(LODGroup group, LOD lod) { Transform root = group.transform; LODNode lodNode = new LODNode(); Renderer[] renderers = lod.renderers; List <Transform[]> rendererTransformPaths = new List <Transform[]>(); // filter the renderers into gameobjects with unique roots in the group (i.e. if two renderers share a parent just add the parent gameobject) for (int i = 0; i < renderers.Length; i++) { rendererTransformPaths.Add(TransformConverter.CreateTransformPath(renderers[i].transform, root)); } return(lodNode); }
void Start() { group = gameObject.AddComponent<LODGroup>(); LOD[] lods = new LOD[4]; int i = 0; while (i < 4) { PrimitiveType primType = PrimitiveType.Cube; if (i == 1) primType = PrimitiveType.Capsule; if (i == 2) primType = PrimitiveType.Sphere; if (i == 3) primType = PrimitiveType.Cylinder; GameObject go = GameObject.CreatePrimitive(primType); go.transform.parent = gameObject.transform; Renderer[] renderers = new Renderer[1]; renderers[0] = go.renderer; lods[i] = new LOD(1.0F / (i + 1), renderers); i++; } group.SetLODS(lods); group.RecalculateBounds(); }
//bool moveBack = false; void OnSceneGUI() { _lod = target as LOD; if ( _lod != null ) { if ( !Application.isPlaying ) { //_lod.RecalcBounds(); _lod.RecalcLOD(Camera.current); /* //if ( moveBack ) //{ Camera cam = SceneView.lastActiveSceneView.camera; Vector3 pos = cam.transform.localPosition; pos.z = -10.1f; cam.transform.localPosition = pos; cam. Vector3 moveDir = cam.transform.InverseTransformDirection( Vector3.forward ); Vector3 position = SceneView.lastActiveSceneView.pivot; position.z += 1;//moveDir; SceneView.lastActiveSceneView.pivot = position; SceneView.lastActiveSceneView.Repaint(); //} */ } DrawBoundingBox(); } }
private void SetupTerrainIndices(LOD detailLevel) { int width = size; int detail = (int)detailLevel; int widthMinusOne = (width - 1); // If detail level is smaller than the quad patch, then move up to // the next highest detail level. if (detail >= widthMinusOne) { detail /= 2; } int widthMinusOneDivDetail = widthMinusOne / detail; int[] indices = new int[widthMinusOne * widthMinusOne * 6 / (detail * detail)]; for (int x = 0; x < widthMinusOneDivDetail; ++x) for (int y = 0; y < widthMinusOneDivDetail; ++y) { int triStartIndex = (x + y * widthMinusOneDivDetail) * 6; int xPlusOne = x + 1; int yTimesWidth = y * width; int yPlusOneTimesWidth = (y + 1) * width; indices[triStartIndex] = (xPlusOne + yPlusOneTimesWidth) * detail; indices[triStartIndex + 1] = (xPlusOne + yTimesWidth) * detail; indices[triStartIndex + 2] = (x + yTimesWidth) * detail; indices[triStartIndex + 3] = indices[triStartIndex]; indices[triStartIndex + 4] = indices[triStartIndex + 2]; indices[triStartIndex + 5] = (x + yPlusOneTimesWidth) * detail; } int widthMinusDetail = (width - detail); indexBuffers[detail] = new IndexBuffer(MapViewer.graphics.GraphicsDevice, typeof(int), indices.Length, BufferUsage.WriteOnly); indexBuffers[detail].SetData(indices); numTris[detail] = indices.Length / 3; }
public void Draw(Matrix view, Matrix projection, LOD detailLevel) { int detail = (int)detailLevel; int vertexCount = size * size; MapViewer.graphics.GraphicsDevice.Indices = indexBuffers[detail]; MapViewer.graphics.GraphicsDevice.VertexDeclaration = vertDeclaration; MapViewer.graphics.GraphicsDevice.Vertices[0].SetSource(vertexBuffer, 0, vertDeclaration.GetVertexStrideSize(0)); Matrix world = Matrix.CreateWorld(position, Vector3.Forward, Vector3.Up); Matrix worldView = world * view; Matrix worldViewProjection = worldView * projection; terrainEffect.Parameters["View"].SetValue(view); terrainEffect.Parameters["Projection"].SetValue(projection); terrainEffect.Parameters["World"].SetValue(world); terrainEffect.Parameters["WorldViewProj"].SetValue(worldViewProjection); terrainEffect.Parameters["CameraPos"].SetValue(new Vector4(MapViewer.camera.Position, 0f)); terrainEffect.Parameters["CameraForward"].SetValue(new Vector4(view.Forward, 0f)); terrainEffect.Begin(); for (int i = 0; i < terrainEffect.CurrentTechnique.Passes.Count; ++i) { terrainEffect.CurrentTechnique.Passes[i].Begin(); MapViewer.graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertexCount, 0, numTris[detail]); terrainEffect.CurrentTechnique.Passes[i].End(); } terrainEffect.End(); MapViewer.graphics.GraphicsDevice.RenderState.FillMode = FillMode.Solid; MapViewer.graphics.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace; }
public void SetLODS(LOD[] scriptingLODs){}
private void GenerateLODs(Renderer[] renderers) { LOD[] existingLODs = lod.GetLODs(); if (existingLODs.Length != 2) { Debug.LogError("Unexpected LOD count: " + existingLODs.Length + ", " + name); } List<Renderer> lod0s = new List<Renderer>(); List<Renderer> lod1s = new List<Renderer>(); for (int i = 0; i < renderers.Length; i++) { if (renderers[i].name.Equals("LOD0")) { lod0s.Add(renderers[i]); } else if (renderers[i].name.Equals("LOD1")) { lod1s.Add(renderers[i]); } else { Debug.LogError("Unexpected LOD name: " + renderers[i].name); } } LOD lod0 = new LOD(existingLODs[0].screenRelativeTransitionHeight, lod0s.ToArray()); lod0.fadeTransitionWidth = existingLODs[0].fadeTransitionWidth; LOD lod1 = new LOD(existingLODs[1].screenRelativeTransitionHeight, lod1s.ToArray()); lod1.fadeTransitionWidth = existingLODs[1].fadeTransitionWidth; lod.SetLODs(new LOD[] { lod0, lod1 }); lod.RecalculateBounds(); }
public void ApplyTangents(LOD l, int edge, Vector4 tan, Vector4 bitan) { byte[] buff = new byte[4]; Edge e = l.Edges[edge]; buff[0] = Convert.ToByte((tan.X * 0.5f + 0.5f) * 0xFF); buff[1] = Convert.ToByte((tan.Y * 0.5f + 0.5f) * 0xFF); buff[2] = Convert.ToByte((tan.Z * 0.5f + 0.5f) * 0xFF); buff[3] = Convert.ToByte((tan.W * 0.5f + 0.5f) * 0xFF); e.Unk1 = BitConverter.ToInt32(buff, 0); buff[0] = Convert.ToByte((bitan.X * 0.5f + 0.5f) * 0xFF); buff[1] = Convert.ToByte((bitan.Y * 0.5f + 0.5f) * 0xFF); buff[2] = Convert.ToByte((bitan.Z * 0.5f + 0.5f) * 0xFF); buff[3] = Convert.ToByte((bitan.W * 0.5f + 0.5f) * 0xFF); e.Unk2 = BitConverter.ToInt32(buff, 0); l.Edges[edge] = e; }
private TreeNode ToTreeSection(TreeNode t, LOD sec) { TreeNode t1 = new TreeNode("Headers"); for (int i = 0; i < sec.Headers.Count(); i++) { LODHeader h = sec.Headers[i]; TreeNode t2 = new TreeNode(i.ToString()); t2.Nodes.Add(new TreeNode("Index: " + h.index)); t2.Nodes.Add(new TreeNode("MatIndex: " + h.matindex)); t2.Nodes.Add(new TreeNode("Offset: " + h.offset)); t2.Nodes.Add(new TreeNode("Count: " + h.count)); t2.Nodes.Add(new TreeNode("Unknown: " + h.unk1)); t1.Nodes.Add(t2); } t.Nodes.Add(t1); t1 = new TreeNode("Indexbuffer"); for(int i=0;i<sec.Indexes.Count;i++) t1.Nodes.Add(new TreeNode(i.ToString("d4") + " : " + sec.Indexes[i])); t.Nodes.Add(t1); t1 = new TreeNode("Unknown Buffer 1"); for (int i = 0; i < sec.UnkIndexes1.Count; i++) t1.Nodes.Add(new TreeNode(i.ToString("d4") + " : " + sec.UnkIndexes1[i])); t.Nodes.Add(t1); t1 = new TreeNode("Unknown Buffer 2"); for (int i = 0; i < sec.UnkIndexes2.Count; i++) t1.Nodes.Add(new TreeNode(i.ToString("d4") + " : " + sec.UnkIndexes2[i])); t.Nodes.Add(t1); t1 = new TreeNode("Unknown Buffer 3"); for (int i = 0; i < sec.UnkSec2.Length / 4; i++) t1.Nodes.Add(new TreeNode(i.ToString("d4") + " : " + BitConverter.ToInt32(sec.UnkSec2, i * 4).ToString("X8") + " " + BitConverter.ToSingle(sec.UnkSec2, i * 4))); t.Nodes.Add(t1); t1 = new TreeNode("Unknown Sections"); for (int i = 0; i < sec.UnkSec1.Count; i++) { TreeNode t2 = new TreeNode("Unknown Section " + i); t2 = ToTreeUnkSection(t2, sec.UnkSec1[i]); t1.Nodes.Add(t2); } t.Nodes.Add(t1); t1 = new TreeNode("Active Bones"); for (int i = 0; i < sec.ActiveBones.Count; i++) t1.Nodes.Add(new TreeNode(i + " : " + sec.ActiveBones[i])); t.Nodes.Add(t1); t1 = new TreeNode("Edges"); t1 = ToTreeEdges(t1, sec.Edges); t.Nodes.Add(t1); t1 = new TreeNode("UnknownValue = " + sec.unk2); t.Nodes.Add(t1); return t; }
public void ReadLODs() { int count = BitConverter.ToInt32(memory, readerpos); readerpos += 4; Mesh.LODs = new List<LOD>(); for (int i = 0; i < count; i++) { LOD lod = new LOD(); lod._offset = readerpos; lod.Headers = new List<LODHeader>(); int sectioncount = BitConverter.ToInt32(memory, readerpos); readerpos += 4; for (int j = 0; j < sectioncount; j++) { LODHeader lodsec = new LODHeader(); lodsec.matindex = BitConverter.ToUInt16(memory, readerpos); lodsec.index = BitConverter.ToUInt16(memory, readerpos + 2); lodsec.offset = BitConverter.ToUInt32(memory, readerpos + 4); lodsec.count = BitConverter.ToUInt16(memory, readerpos + 8); lodsec.unk1 = BitConverter.ToUInt16(memory, readerpos + 10); readerpos += 12; lod.Headers.Add(lodsec); } int indexsize = BitConverter.ToInt32(memory, readerpos); int indexcount = BitConverter.ToInt32(memory, readerpos + 4); readerpos += 8; lod.Indexes = new List<ushort>(); for (int j = 0; j < sectioncount; j++) { for (int k = 0; k < lod.Headers[j].count * 3; k++) { lod.Indexes.Add(BitConverter.ToUInt16(memory, readerpos)); readerpos += 2; } } indexcount = BitConverter.ToInt32(memory, readerpos); // ?? SoftVertices ?? readerpos += 4; if (indexcount != 0) { MessageBox.Show("Not implemented!"); return; } indexcount = BitConverter.ToInt32(memory, readerpos); // ?? RigidVertices ?? readerpos += 4; lod.UnkIndexes1 = new List<ushort>(); for (int k = 0; k < indexcount; k++) { lod.UnkIndexes1.Add(BitConverter.ToUInt16(memory, readerpos)); readerpos += 2; } indexcount = BitConverter.ToInt32(memory, readerpos); // ?? ShadowIndices ?? readerpos += 4; if (indexcount != 0) { MessageBox.Show("Not implemented!"); return; } lod.UnkCount1 = BitConverter.ToInt32(memory, readerpos); // ?? Sections ?? readerpos += 4; lod.UnkIndexes2 = new List<UInt32>(); for (int k = 0; k < 3; k++) // ?? Rot/Loc ?? { lod.UnkIndexes2.Add(BitConverter.ToUInt32(memory, readerpos)); readerpos += 4; } lod.UnkSec1 = new List<UnknownSection>(); for (int k = 0; k < lod.UnkCount1; k++) // ?? Sections ?? Materials ?? { UnknownSection unk = new UnknownSection(); indexcount = BitConverter.ToInt32(memory, readerpos); readerpos += 4; unk.Indexes = new List<ushort>(); for (int l = 0; l < indexcount; l++) // ?? active bones ?? { unk.Indexes.Add(BitConverter.ToUInt16(memory, readerpos)); readerpos += 2; } unk.Unkn = new byte[24]; for (int l = 0; l < 24; l++) unk.Unkn[l] = memory[readerpos + l]; readerpos += 24; lod.UnkSec1.Add(unk); } indexcount = BitConverter.ToInt32(memory, readerpos); readerpos += 4; lod.ActiveBones = new List<byte>(); for (int k = 0; k < indexcount; k++) lod.ActiveBones.Add(memory[readerpos + k]); readerpos += indexcount; lod.UnkSec2 = new byte[48]; for (int k = 0; k < 48; k++) lod.UnkSec2[k] = memory[readerpos + k]; readerpos += 48; indexsize = BitConverter.ToInt32(memory, readerpos); indexcount = BitConverter.ToInt32(memory, readerpos + 4); readerpos += 8; lod.Edges = new List<Edge>(); for (int k = 0; k < indexcount; k++) { Edge e = new Edge(); e._offset = readerpos; e.Unk1 = BitConverter.ToInt32(memory, readerpos); e.Unk2 = BitConverter.ToInt32(memory, readerpos + 4); e.Influences = new List<Influence>(); for (int l = 0; l < 4; l++) { Influence inf = new Influence(); inf.bone = memory[readerpos + 8 + l]; inf.weight = memory[readerpos + 12 + l]; e.Influences.Add(inf); } e.Position = ReadVector(readerpos + 16); UInt16 u = BitConverter.ToUInt16(memory, readerpos + 28); UInt16 v = BitConverter.ToUInt16(memory, readerpos + 30); e.UV = new Vector2(HalfToFloat(u), HalfToFloat(v)); e._imported = false; lod.Edges.Add(e); readerpos += 32; } lod.unk2 = BitConverter.ToUInt32(memory, readerpos); readerpos += 4; Mesh.LODs.Add(lod); } }
public void CalcTangentSpace2(LOD l) { int vertexCount = l.Edges.Count(); Vector3[] vertices = ToVec3(l.Edges); Vector3[] normals = new Vector3[vertexCount]; Vector2[] texcoords = new Vector2[vertexCount]; Vector4[] tangents = new Vector4[vertexCount]; Vector4[] bitangents = new Vector4[vertexCount]; Vector3[] tan1 = new Vector3[vertexCount]; Vector3[] tan2 = new Vector3[vertexCount]; for (int i = 0; i < l.Indexes.Count() / 3; i++) { int i0, i1, i2; i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 1]; i2 = l.Indexes[i * 3 + 2]; Vector3 v1 = l.Edges[i0].Position; Vector3 v2 = l.Edges[i1].Position; Vector3 v3 = l.Edges[i2].Position; Vector3 edge1 = v2 - v1; Vector3 edge2 = v3 - v1; Vector3 normal = Vector3.Cross(edge1, edge2); normal *= InvSqrt(VecSqr(normal)); normals[i0] += normal; normals[i1] += normal; normals[i2] += normal; texcoords[i0] = l.Edges[i0].UV; texcoords[i1] = l.Edges[i1].UV; texcoords[i2] = l.Edges[i2].UV; Vector2 w1 = texcoords[i0]; Vector2 w2 = texcoords[i1]; Vector2 w3 = texcoords[i2]; float x1 = v2.X - v1.X; float x2 = v3.X - v1.X; float y1 = v2.Y - v1.Y; float y2 = v3.Y - v1.Y; float z1 = v2.Z - v1.Z; float z2 = v3.Z - v1.Z; float s1 = w2.X - w1.X; float s2 = w3.X - w1.X; float t1 = w2.Y - w1.Y; float t2 = w3.Y - w1.Y; float r = (s1 * t2 - s2 * t1); if (r != 0) { r = 1 / r; Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); tan1[i0] += sdir; tan1[i1] += sdir; tan1[i2] += sdir; tan2[i0] += tdir; tan2[i1] += tdir; tan2[i2] += tdir; } } for (int i = 0; i < vertexCount; i++) { normals[i] *= InvSqrt(VecSqr(normals[i])); Vector3 n = normals[i]; Vector3 t = tan1[i]; Vector3 t2 = tan2[i]; t -= n * Vector3.Dot(n, t); t *= InvSqrt(VecSqr(t)); Vector3 nxt = Vector3.Cross(n, t); float sign =(Vector3.Dot(t2, nxt) < 0.0f) ? -1.0f : 1.0f; t2 = nxt * sign; bitangents[i] = new Vector4(t.X, t.Y, t.Z, sign); tangents[i] = new Vector4(t2.X, t2.Y, t2.Z, -0.004f); } for (int i = 0; i < l.Indexes.Count() / 3; i++) { int i0, i1, i2; i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 1]; i2 = l.Indexes[i * 3 + 2]; Vector4 bi0 = bitangents[i0]; Vector4 bi1 = bitangents[i1]; Vector4 bi2 = bitangents[i2]; Vector4 tn0 = tangents[i0]; Vector4 tn1 = tangents[i1]; Vector4 tn2 = tangents[i2]; ApplyTangents(l, i0, tn0, bi0); ApplyTangents(l, i1, tn1, bi1); ApplyTangents(l, i2, tn2, bi2); } }
public void CalcTangentSpace(LOD l) { int vertexCount = l.Edges.Count(); Vector3[] vertices = ToVec3(l.Edges); Vector3[] normals = new Vector3[vertexCount]; Vector2[] texcoords = new Vector2[vertexCount]; for (int i = 0; i < l.Indexes.Count() / 3; i++) { int i0, i1, i2; if (MPOpt.SKM_cullfaces) { i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 2]; i2 = l.Indexes[i * 3 + 1]; } else { i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 1]; i2 = l.Indexes[i * 3 + 2]; } Vector3 v1 = l.Edges[i0].Position; Vector3 v2 = l.Edges[i1].Position; Vector3 v3 = l.Edges[i2].Position; Vector3 edge1 = v2 - v1; Vector3 edge2 = v3 - v1; normals[i0] += Vector3.Cross(edge1, edge2); edge1 = v3 - v2; edge2 = v1 - v2; normals[i1] += Vector3.Cross(edge1, edge2); edge1 = v1 - v3; edge2 = v2 - v3; normals[i2] += Vector3.Cross(edge1, edge2); texcoords[i0] = l.Edges[i0].UV; texcoords[i1] = l.Edges[i1].UV; texcoords[i2] = l.Edges[i2].UV; } for (int i = 0; i < l.Indexes.Count() / 3; i++) { int i0, i1, i2; if (MPOpt.SKM_cullfaces) { i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 2]; i2 = l.Indexes[i * 3 + 1]; } else { i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 1]; i2 = l.Indexes[i * 3 + 2]; } normals[i0].Normalize(); normals[i1].Normalize(); normals[i2].Normalize(); } Vector4[] tangents = new Vector4[vertexCount]; Vector4[] bitangents = new Vector4[vertexCount]; Vector3[] tan1 = new Vector3[vertexCount]; Vector3[] tan2 = new Vector3[vertexCount]; for (int i = 0; i < l.Indexes.Count() / 3; i++) { int i0, i1, i2; if (MPOpt.SKM_cullfaces) { i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 2]; i2 = l.Indexes[i * 3 + 1]; } else { i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 1]; i2 = l.Indexes[i * 3 + 2]; } Vector3 v1 = vertices[i0]; Vector3 v2 = vertices[i1]; Vector3 v3 = vertices[i2]; Vector2 w1 = texcoords[i0]; Vector2 w2 = texcoords[i1]; Vector2 w3 = texcoords[i2]; float x1 = v2.X - v1.X; float x2 = v3.X - v1.X; float y1 = v2.Y - v1.Y; float y2 = v3.Y - v1.Y; float z1 = v2.Z - v1.Z; float z2 = v3.Z - v1.Z; float s1 = w2.X - w1.X; float s2 = w3.X - w1.X; float t1 = w2.Y - w1.Y; float t2 = w3.Y - w1.Y; float r = 1.0f / (s1 * t2 - s2 * t1); Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); tan1[i0] += sdir; tan1[i1] += sdir; tan1[i2] += sdir; tan2[i0] += tdir; tan2[i1] += tdir; tan2[i2] += tdir; } for (int i = 0; i < vertexCount; i++) { Vector3 n = normals[i]; Vector3 t = tan1[i]; Vector3 t2 = tan2[i]; Vector3 tmp = (t - n * Vector3.Dot(n, t)); tmp.Normalize(); t2.Normalize(); tangents[i] = new Vector4(tmp.X, tmp.Y, tmp.Z, 0); tangents[i].W = (Vector3.Dot(Vector3.Cross(n, t), t2) < 0.0f) ? -1.0f : 1.0f; tangents[i].Normalize(); } for (int i = 0; i < vertexCount; i++) { Vector3 n = normals[i]; Vector3 t = tan2[i]; Vector3 t2 = tan1[i]; Vector3 tmp = (t - n * Vector3.Dot(n, t)); tmp.Normalize(); t2.Normalize(); bitangents[i] = new Vector4(tmp.X, tmp.Y, tmp.Z, 0); bitangents[i].W = (Vector3.Dot(Vector3.Cross(n, t), t2) < 0.0f) ? -1.0f : 1.0f; bitangents[i].Normalize(); } for (int i = 0; i < l.Indexes.Count() / 3; i++) { int i0, i1, i2; if (MPOpt.SKM_cullfaces) { i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 2]; i2 = l.Indexes[i * 3 + 1]; } else { i0 = l.Indexes[i * 3]; i1 = l.Indexes[i * 3 + 1]; i2 = l.Indexes[i * 3 + 2]; } Vector4 bi0 = bitangents[i0]; Vector4 bi1 = bitangents[i1]; Vector4 bi2 = bitangents[i2]; Vector4 tn0 = tangents[i0]; Vector4 tn1 = tangents[i1]; Vector4 tn2 = tangents[i2]; if (MPOpt.SKM_fixtexcoord) { Vector2 t1 = texcoords[i1] - texcoords[i0]; Vector2 t2 = texcoords[i2] - texcoords[i1]; Vector3 tc = Vector3.Cross(Vector3.Normalize(new Vector3(t1.X, t1.Y, 0)), Vector3.Normalize(new Vector3(t2.X, t2.Y, 0))); if (tc.Z > 0) //facing backwards? { bi0 *= -1; bi1 *= -1; bi2 *= -1; tn0 *= -1; tn1 *= -1; tn2 *= -1; } } #region component flips if (MPOpt.SKM_tnflipX) { tn0.X *= -1; tn1.X *= -1; tn2.X *= -1; } if (MPOpt.SKM_tnflipY) { tn0.Y *= -1; tn1.Y *= -1; tn2.Y *= -1; } if (MPOpt.SKM_tnflipZ) { tn0.Z *= -1; tn1.Z *= -1; tn2.Z *= -1; } if (MPOpt.SKM_tnflipW) { tn0.W *= -1; tn1.W *= -1; tn2.W *= -1; } if (MPOpt.SKM_biflipX) { bi0.X *= -1; bi1.X *= -1; bi2.X *= -1; } if (MPOpt.SKM_biflipY) { bi0.Y *= -1; bi1.Y *= -1; bi2.Y *= -1; } if (MPOpt.SKM_biflipZ) { bi0.Z *= -1; bi1.Z *= -1; bi2.Z *= -1; } if (MPOpt.SKM_biflipW) { bi0.W *= -1; bi1.W *= -1; bi2.W *= -1; } #endregion if (MPOpt.SKM_tnW100) { tn0.W *= 0.01f; tn1.W *= 0.01f; tn2.W *= 0.01f; tn0.Normalize(); tn1.Normalize(); tn2.Normalize(); } if (MPOpt.SKM_normalize) { bi0.Normalize(); bi1.Normalize(); bi2.Normalize(); tn0.Normalize(); tn1.Normalize(); tn2.Normalize(); } if (MPOpt.SKM_swaptangents) { ApplyTangents(l, i0, tn0, bi0); ApplyTangents(l, i1, tn1, bi1); ApplyTangents(l, i2, tn2, bi2); } else { ApplyTangents(l, i0, bi0, tn0); ApplyTangents(l, i1, bi1, tn1); ApplyTangents(l, i2, bi2, tn2); } } }