第一步:新建WavefrontObjLoader.cs

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Globalization;
using System.IO; namespace WpfApplication2
{ public class ModelVisual3DWithName : ModelVisual3D, ICloneable
{
public string Name { get; set; } public object Tag { get; set; } public object Clone()
{
var model = new ModelVisual3DWithName
{
Content = Content.Clone(),
Name = Name,
Tag = Tag
};
model.SetColor(Brushes.Wheat);
return model;
} public void SetMaterial(Material material)
{
var geometrymodel = Content as GeometryModel3D;
if (geometrymodel != null)
{
geometrymodel.Material = material;
}
else
{ }
} public Material GetMaterial()
{
var geometrymodel = Content as GeometryModel3D;
if (geometrymodel == null)
{
return null;
}
return geometrymodel.Material;
} public void SetColor(Brush color)
{
var geometrymodel = Content as GeometryModel3D; if (geometrymodel.Material is MaterialGroup)
{
var materialGroup = geometrymodel.Material as MaterialGroup;
SetMaterialGroupColor(materialGroup, color);
}
else
{
DiffuseMaterial material = geometrymodel.Material as DiffuseMaterial;
if (material != null && !material.IsFrozen)
{
material.Brush = color;
}
}
} private void SetMaterialGroupColor(MaterialGroup materialGroup, Brush color)
{
foreach (var groupItem in materialGroup.Children)
{
if (groupItem is DiffuseMaterial && !groupItem.IsFrozen)
{
var tmpItem = groupItem as DiffuseMaterial;
tmpItem.Brush = color;
}
}
}
} public class WavefrontObjLoader
{ private static readonly char[] CommentCharacters = new char[] { '#', '$' };
private List<Point3D> coordinates;
private static readonly Material DefaultWhiteMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.White));
private List<Face> faces;
private static readonly double GeneratedVertexTolerance = 1E-;
private bool generateNormals = true;
private bool generateTextureCoordinates = true;
private List<Group> groups;
private static readonly KeywordData[] Keywords = new KeywordData[] {
new KeywordData("v", KeywordType.GeometricVertex), new KeywordData("vn", KeywordType.VertexNormal), new KeywordData("vt", KeywordType.TextureVertex), new KeywordData("f", KeywordType.Face), new KeywordData("fo", KeywordType.Face), new KeywordData("g", KeywordType.Group), new KeywordData("l", KeywordType.Line), new KeywordData("o", KeywordType.ObjectName), new KeywordData("s", KeywordType.SmoothingGroup), new KeywordData("mtllib", KeywordType.MaterialLibrary), new KeywordData("usemtl", KeywordType.UseMaterial), new KeywordData("usemap", KeywordType.UseMap), new KeywordData("bevel", KeywordType.UnimplementedKeyword), new KeywordData("bmat", KeywordType.UnimplementedKeyword), new KeywordData("bsp", KeywordType.UnimplementedKeyword), new KeywordData("bzp", KeywordType.UnimplementedKeyword),
new KeywordData("c_interop", KeywordType.UnimplementedKeyword), new KeywordData("cdc", KeywordType.UnimplementedKeyword), new KeywordData("con", KeywordType.UnimplementedKeyword), new KeywordData("cstype", KeywordType.UnimplementedKeyword), new KeywordData("ctech", KeywordType.UnimplementedKeyword), new KeywordData("curv", KeywordType.UnimplementedKeyword), new KeywordData("curv2", KeywordType.UnimplementedKeyword), new KeywordData("d_interop", KeywordType.UnimplementedKeyword), new KeywordData("deg", KeywordType.UnimplementedKeyword), new KeywordData("end", KeywordType.UnimplementedKeyword), new KeywordData("hole", KeywordType.UnimplementedKeyword), new KeywordData("lod", KeywordType.UnimplementedKeyword), new KeywordData("maplib", KeywordType.UnimplementedKeyword), new KeywordData("mg", KeywordType.UnimplementedKeyword), new KeywordData("p", KeywordType.UnimplementedKeyword), new KeywordData("param", KeywordType.UnimplementedKeyword),
new KeywordData("parm", KeywordType.UnimplementedKeyword), new KeywordData("res", KeywordType.UnimplementedKeyword), new KeywordData("scrv", KeywordType.UnimplementedKeyword), new KeywordData("shadow_obj", KeywordType.UnimplementedKeyword), new KeywordData("sp", KeywordType.UnimplementedKeyword), new KeywordData("stech", KeywordType.UnimplementedKeyword), new KeywordData("step", KeywordType.UnimplementedKeyword), new KeywordData("surf", KeywordType.UnimplementedKeyword), new KeywordData("trace_obj", KeywordType.UnimplementedKeyword), new KeywordData("trim", KeywordType.UnimplementedKeyword), new KeywordData("vp", KeywordType.UnimplementedKeyword), new KeywordData("newmtl", KeywordType.NewMaterial), new KeywordData("illum", KeywordType.IlluminationMode), new KeywordData("Ka", KeywordType.Ambient), new KeywordData("Kd", KeywordType.Diffuse), new KeywordData("Ks", KeywordType.Specular),
new KeywordData("Ke", KeywordType.Emissive), new KeywordData("d", KeywordType.Alpha), new KeywordData("Tf", KeywordType.Transparency), new KeywordData("Tr", KeywordType.Alpha), new KeywordData("Ns", KeywordType.Shininess), new KeywordData("Ni", KeywordType.RefractionIndex), new KeywordData("map_Ka", KeywordType.AmbientTextureFilename), new KeywordData("map_bump", KeywordType.BumpTextureFilename), new KeywordData("bump", KeywordType.BumpTextureFilename), new KeywordData("map_Kd", KeywordType.DiffuseTextureFilename), new KeywordData("map_Ks", KeywordType.SpecularTextureFilename), new KeywordData("map_Ns", KeywordType.ShininessTextureFilename), new KeywordData("map_refl", KeywordType.ReflectionTextureFilename), new KeywordData("refl", KeywordType.ReflectionTextureFilename), new KeywordData("sharpness", KeywordType.Sharpness)
};
// private IMessageLoggingService logger;
// private IMessageDisplayService manager;
private int nextFaceIndex;
// private SceneViewModel sceneViewModel;
private static readonly char[] Separators = new char[] { ' ', '\t' };
private Dictionary<int, List<int>> smoothingGroups;
private List<Point> textureCoordinates;
private int totalGeneratedVertices;
private int totalVertices;
private int totalVerticesInObj;
private List<Vector3D> vertexNormals; //public WavefrontObjLoader(SceneViewModel sceneViewModel, IMessageLoggingService logger, IMessageDisplayService manager)
//{
// this.sceneViewModel = sceneViewModel;
// this.logger = logger;
// this.manager = manager;
//}
private Dictionary<string, ModelVisual3DWithName> dictionaries; public WavefrontObjLoader()
{
dictionaries = new Dictionary<string, ModelVisual3DWithName>();
} private GeometryModel3D BuildGeometryModel3DFromGeometry(Geometry geometry)
{
GeometryModel3D modeld = new GeometryModel3D();
MeshGeometry3D geometryd = new MeshGeometry3D();
SortedDictionary<UniqueVertex, int> dictionary = new SortedDictionary<UniqueVertex, int>(new UniqueVertexComparer());
geometryd.TriangleIndices = new Int32Collection();
bool flag = false;
bool flag2 = false;
Rect3D empty = Rect3D.Empty;
for (int i = geometry.FirstFaceIndex; i <= geometry.LastFaceIndex; i++)
{
Face face = this.faces[i];
int[] numArray = new int[face.CoordinateIndices.Count];
for (int k = ; k < face.CoordinateIndices.Count; k++)
{
UniqueVertex key = new UniqueVertex();
key.Coordinate = this.coordinates[face.CoordinateIndices[k]];
if (face.NormalIndices != null)
{
key.Normal = this.vertexNormals[face.NormalIndices[k]];
flag = true;
}
if (face.TextureCoordinateIndices != null)
{
key.TextureCoordinates = this.textureCoordinates[face.TextureCoordinateIndices[k]];
flag2 = true;
}
int num3 = -;
if (!dictionary.TryGetValue(key, out num3))
{
num3 = dictionary.Count;
dictionary.Add(key, num3);
empty.Union(key.Coordinate);
}
numArray[k] = num3;
}
for (int m = ; m < (numArray.Length - ); m++)
{
geometryd.TriangleIndices.Add(numArray[]);
geometryd.TriangleIndices.Add(numArray[m]);
geometryd.TriangleIndices.Add(numArray[m + ]);
}
}
int count = dictionary.Count;
if (count == )
{
return null;
}
if (this.generateTextureCoordinates)
{
flag2 = true;
}
geometryd.Positions = new Point3DCollection(count);
if (flag)
{
geometryd.Normals = new Vector3DCollection(count);
}
if (flag2)
{
geometryd.TextureCoordinates = new PointCollection(count);
}
Point3D center = empty.Location + new Vector3D(empty.SizeX / 2.0, empty.SizeY / 2.0, empty.SizeZ / 2.0);
Point3D pointd2 = new Point3D();
Vector3D vectord = new Vector3D();
Point point = new Point();
for (int j = ; j < count; j++)
{
geometryd.Positions.Add(pointd2);
if (flag)
{
geometryd.Normals.Add(vectord);
}
if (flag2)
{
geometryd.TextureCoordinates.Add(point);
}
}
foreach (KeyValuePair<UniqueVertex, int> pair in dictionary)
{
geometryd.Positions[pair.Value] = pair.Key.Coordinate;
if (pair.Key.NormalSet)
{
geometryd.Normals[pair.Value] = pair.Key.Normal;
}
if (pair.Key.TextureCoordinatesSet)
{
geometryd.TextureCoordinates[pair.Value] = pair.Key.TextureCoordinates;
}
else
{
geometryd.TextureCoordinates[pair.Value] = GetPositionalSphericalTextureCoordinateFromPoint(pair.Key.Coordinate, center);
}
}
modeld.Geometry = geometryd;
modeld.Material = geometry.Material.Clone();
// modeld.SetValue(CommonProperties.NameProperty, SceneElementIDHelper.ToCSharpID(geometry.Name));
return modeld;
} private static Material CreateMaterial(ObjMaterial currentMaterial)
{
MaterialGroup group = new MaterialGroup();
if (currentMaterial.AmbientTexture != null)
{
group.Children.Add(new EmissiveMaterial(new ImageBrush(currentMaterial.AmbientTexture)));
}
else
{
if (currentMaterial.Alpha < 1.0)
{
currentMaterial.Ambient.ScA = (float)currentMaterial.Alpha;
}
group.Children.Add(new EmissiveMaterial(new SolidColorBrush(currentMaterial.Ambient)));
}
if (currentMaterial.DiffuseTexture != null)
{
group.Children.Add(new DiffuseMaterial(new ImageBrush(currentMaterial.DiffuseTexture)));
}
else
{
if (currentMaterial.Alpha < 1.0)
{
currentMaterial.Diffuse.ScA = (float)currentMaterial.Alpha;
}
group.Children.Add(new DiffuseMaterial(new SolidColorBrush(currentMaterial.Diffuse)));
}
if (currentMaterial.IlluminationMode > )
{
if (currentMaterial.SpecularTexture != null)
{
group.Children.Add(new SpecularMaterial(new ImageBrush(currentMaterial.SpecularTexture), currentMaterial.Shininess));
return group;
}
if (currentMaterial.Alpha < 1.0)
{
currentMaterial.Specular.ScA = (float)currentMaterial.Alpha;
}
group.Children.Add(new SpecularMaterial(new SolidColorBrush(currentMaterial.Specular), currentMaterial.Shininess));
}
return group;
} private static Material DefaultMaterial()
{
Random random = new Random();
Material material = new DiffuseMaterial(new SolidColorBrush(Color.FromScRgb(1f, (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())));
return DefaultWhiteMaterial;
} private bool FinishCurrentGeometry(Group group, Material material, string name, string materialName)
{
if (name == null)
{
name = materialName;
}
if ((this.faces.Count - ) >= this.nextFaceIndex)
{
group.Geometry.Add(new Geometry(name, material, this.nextFaceIndex, this.faces.Count - ));
this.nextFaceIndex = this.faces.Count;
return true;
}
return false;
} private void FinishCurrentGroup(Group group)
{
if (group.Geometry.Count > )
{
this.groups.Add(group);
}
} private ModelVisual3DWithName GenerateAvalonTree()
{
var visuald = new ModelVisual3DWithName {Name = "RootGeometryContainer"};
if (!dictionaries.ContainsKey(visuald.Name))
{
dictionaries.Add(visuald.Name, visuald);
} for (int i = ; i < this.groups.Count; i++)
{
Group group = this.groups[i];
var visuald2 = new ModelVisual3DWithName {Name = group.Name};
if (!dictionaries.ContainsKey(visuald2.Name))
{
dictionaries.Add(visuald2.Name, visuald2);
} if (group.Geometry.Count > )
{
for (int j = ; j < group.Geometry.Count; j++)
{
var visuald3 = new ModelVisual3DWithName
{
Name = group.Geometry[j].Name,
Content = BuildGeometryModel3DFromGeometry(
group.Geometry[j])
};
if (visuald3.Content != null)
{
visuald2.Children.Add(visuald3);
}
}
}
else if (group.Geometry.Count == )
{
visuald2.Content = BuildGeometryModel3DFromGeometry(group.Geometry[]);
}
visuald.Children.Add(visuald2);
} return visuald;
} private static Point GetPositionalSphericalTextureCoordinateFromPoint(Point3D point, Point3D center)
{
Vector3D vectord = point - center;
vectord.Normalize();
return new Point((Math.Asin(vectord.X) / 3.1415926535897931) + 0.5, 1.0 - ((Math.Asin(vectord.Y) / 3.1415926535897931) + 0.5));
} private Dictionary<string, ObjMaterial> LoadMtlFile(string mtlFilename)
{
Dictionary<string, ObjMaterial> materialLibrary = null;
StreamReader reader;
try
{
reader = new StreamReader(mtlFilename);
}
catch (FileNotFoundException)
{
return materialLibrary;
} StreamReader reader2 = reader;
try
{
ParseMtlFile(reader, Path.GetDirectoryName(mtlFilename), ref materialLibrary);
}
catch (Exception)
{
// this.manager.ShowError(message, StringTable.WavefrontObjAssetCreateElementFailedDialogTitle);
}
finally
{
if (reader2 != null)
{
reader2.Dispose();
}
}
return materialLibrary;
} public ModelVisual3DWithName LoadObjFile(string targetFile)
{
using (Stream fs = new FileStream(targetFile, FileMode.Open, FileAccess.Read))
{
return LoadObjFile(new StreamReader(fs),
Path.GetFullPath(targetFile).Replace(
Path.GetFileName(targetFile),""),
Path.GetFileName(targetFile));
}
} public ModelVisual3DWithName LoadObjFile(StreamReader streamReader, string rootPath, string filename)
{
this.coordinates = new List<Point3D>();
this.vertexNormals = new List<Vector3D>();
this.textureCoordinates = new List<Point>();
this.smoothingGroups = new Dictionary<int, List<int>>();
this.faces = new List<Face>();
this.groups = new List<Group>();
this.nextFaceIndex = ;
this.totalVerticesInObj = ;
this.totalVertices = ;
this.totalGeneratedVertices = ;
Dictionary<string, ObjMaterial> dictionary = null;
bool flag = false;
string name = "DefaultGroup";
string str2 = null;
string materialName = "DefaultMaterial";
int key = ;
Material material2 = DefaultMaterial();
Group group = new Group(name);
string str4 = string.Empty;
while ((str4 = streamReader.ReadLine()) != null)
{
int length = str4.IndexOfAny(CommentCharacters);
if (length != -)
{
str4 = str4.Substring(, length);
}
int num3 = str4.IndexOfAny(Separators);
string line = string.Empty;
string content = string.Empty;
if (str4.Trim().Length != )
{
if (num3 != -)
{
line = str4.Substring(, num3);
while ((num3 < str4.Length) && ((str4[num3] == ' ') || (str4[num3] == '\t')))
{
num3++;
}
content = str4.Substring(num3);
}
else
{
line = str4;
}
switch (ParseKeyword(line))
{
case KeywordType.UnrecognizedKeyword:
{
continue;
}
case KeywordType.UnimplementedKeyword:
{
continue;
}
case KeywordType.Comment:
case KeywordType.Line:
{
continue;
}
case KeywordType.Face:
{
Face face;
if (!ParseFace(content, out face) || !this.NormalizeFaceIndices(face))
{
goto Label_0301;
}
this.faces.Add(face);
if (key != )
{
List<int> list;
if (!this.smoothingGroups.TryGetValue(key, out list))
{
list = new List<int>();
this.smoothingGroups.Add(key, list);
}
list.Add(this.faces.Count - );
}
continue;
}
case KeywordType.Group:
{
if (this.FinishCurrentGeometry(group, material2, str2, materialName))
{
str2 = null;
}
this.FinishCurrentGroup(group);
content = content.TrimEnd(Separators);
if (content.Length != )
{
name = content;
}
group = new Group(name);
continue;
}
case KeywordType.MaterialLibrary:
{
dictionary = LoadMtlFile(Path.Combine(rootPath, content));
continue;
}
case KeywordType.ObjectName:
{
str2 = content.TrimEnd(Separators);
continue;
}
case KeywordType.SmoothingGroup:
{
content = content.Trim(Separators);
if (!(content == "off"))
{
goto Label_03EA;
}
key = ;
continue;
}
case KeywordType.UseMaterial:
{
if (this.FinishCurrentGeometry(group, material2, str2, materialName))
{
str2 = null;
}
if ((dictionary == null) && !flag)
{
dictionary = this.LoadMtlFile(System.IO.Path.Combine(rootPath, filename.Replace(".obj", string.Empty) + ".mtl"));
flag = true;
}
if (dictionary == null)
{
goto Label_0207;
}
try
{
ObjMaterial material = dictionary[content];
material2 = material.Material;
materialName = content;
}
catch (KeyNotFoundException)
{
material2 = DefaultMaterial();
}
continue;
}
case KeywordType.GeometricVertex:
{
Point3D pointd;
if (!ParseVertex(content, out pointd))
{
goto Label_0345;
}
this.totalVerticesInObj++;
this.coordinates.Add(pointd);
continue;
}
case KeywordType.VertexNormal:
{
Vector3D vectord;
if (!ParseVertexNormal(content, out vectord))
{
goto Label_037B;
}
this.vertexNormals.Add(vectord);
continue;
}
case KeywordType.TextureVertex:
{
Point point;
if (!ParseVertexTextureCoordinate(content, out point))
{
goto Label_03B1;
}
this.textureCoordinates.Add(point);
continue;
}
}
}
continue;
Label_0207: ;
material2 = DefaultMaterial();
continue;
Label_0301:
continue;
Label_0345:
continue;
Label_037B:
continue;
Label_03B1:
continue;
Label_03EA:
if (!int.TryParse(content, NumberStyles.Integer, CultureInfo.InvariantCulture, out key))
{
//MessageBox.Show("string.Format(CultureInfo.CurrentCulture, StringTable.WavefrontObjLoaderErrorInvalidSmoothingGroup, new object[] { content })");
}
}
this.FinishCurrentGeometry(group, material2, str2, materialName);
this.FinishCurrentGroup(group);
if (this.generateNormals)
{
foreach (KeyValuePair<int, List<int>> pair in this.smoothingGroups)
{
List<int> list2 = pair.Value;
Dictionary<int, Vector3D> dictionary2 = new Dictionary<int, Vector3D>();
for (int i = ; i < list2.Count; i++)
{
Face face2 = this.faces[list2[i]];
if (face2.NormalIndices == null)
{
for (int k = ; k < face2.CoordinateIndices.Count; k++)
{
Vector3D normal;
if (!dictionary2.TryGetValue(face2.CoordinateIndices[k], out normal))
{
normal = face2.Normal;
dictionary2.Add(face2.CoordinateIndices[k], normal);
}
else
{
normal += face2.Normal;
dictionary2[face2.CoordinateIndices[k]] = normal;
}
}
}
}
Dictionary<int, int> dictionary3 = new Dictionary<int, int>();
foreach (KeyValuePair<int, Vector3D> pair2 in dictionary2)
{
Vector3D item = pair2.Value;
item.Normalize();
this.vertexNormals.Add(item);
dictionary3[pair2.Key] = this.vertexNormals.Count - ;
}
for (int j = ; j < list2.Count; j++)
{
Face face3 = this.faces[list2[j]];
if (face3.NormalIndices == null)
{
face3.NormalIndices = new List<int>(face3.CoordinateIndices.Count);
for (int m = ; m < face3.CoordinateIndices.Count; m++)
{
face3.NormalIndices.Add(dictionary3[face3.CoordinateIndices[m]]);
}
}
}
}
}
ModelVisual3DWithName visuald = this.GenerateAvalonTree();
return visuald;
} public ModelVisual3DWithName Find(string name)
{
ModelVisual3DWithName model;
if (dictionaries.TryGetValue(name, out model))
{
return model;
} return null;
} public void Add(string name, ModelVisual3DWithName modelVisual3D)
{
if (Find(name) == null)
{
dictionaries.Add(name, modelVisual3D);
}
} public void Remove(string name)
{
if (Find(name) != null)
{
dictionaries.Remove(name);
}
} private BitmapImage LoadTexture(string rootPath, string content)
{
BitmapImage image = null;
try
{
if (content[] == '-')
{
content.IndexOfAny(Separators);
content = content.Substring(content.LastIndexOfAny(Separators)).TrimStart(Separators);
}
}
catch (Exception)
{
} string path = System.IO.Path.Combine(rootPath, content);
if (File.Exists(path))
{ image = new BitmapImage();
image.BeginInit();
image.UriSource = new Uri(path , UriKind.RelativeOrAbsolute);
image.EndInit();
}
return image;
} private bool NormalizeFaceIndices(Face face)
{
for (int i = ; i < face.CoordinateIndices.Count; i++)
{
if (face.CoordinateIndices[i] < )
{
List<int> list;
int num2;
(list = face.CoordinateIndices)[num2 = i] = list[num2] + this.coordinates.Count;
}
else
{
List<int> list2;
int num3;
(list2 = face.CoordinateIndices)[num3 = i] = list2[num3] - ;
}
if ((face.CoordinateIndices[i] >= this.coordinates.Count) || (face.CoordinateIndices[i] < ))
{
return false;
}
if (face.NormalIndices != null)
{
if (face.NormalIndices[i] < )
{
List<int> list3;
int num4;
(list3 = face.NormalIndices)[num4 = i] = list3[num4] + this.vertexNormals.Count;
}
else
{
List<int> list4;
int num5;
(list4 = face.NormalIndices)[num5 = i] = list4[num5] - ;
}
if ((face.NormalIndices[i] >= this.vertexNormals.Count) || (face.NormalIndices[i] < -))
{
face.NormalIndices = null;
}
}
if (face.TextureCoordinateIndices != null)
{
if (face.TextureCoordinateIndices[i] < )
{
List<int> list5;
int num6;
(list5 = face.TextureCoordinateIndices)[num6 = i] = list5[num6] + this.textureCoordinates.Count;
}
else
{
List<int> list6;
int num7;
(list6 = face.TextureCoordinateIndices)[num7 = i] = list6[num7] - ;
}
if ((face.TextureCoordinateIndices[i] >= this.textureCoordinates.Count) || (face.TextureCoordinateIndices[i] < -))
{
face.TextureCoordinateIndices = null;
}
}
}
Vector3D vectord = this.coordinates[face.CoordinateIndices[]] - this.coordinates[face.CoordinateIndices[]];
Vector3D vectord2 = this.coordinates[face.CoordinateIndices[]] - this.coordinates[face.CoordinateIndices[]];
face.Normal = Vector3D.CrossProduct(vectord, vectord2);
return true;
} private static bool ParseColor(string content, out Color color)
{
float num;
float num2;
float num3;
string[] strArray = content.Split(Separators, StringSplitOptions.RemoveEmptyEntries);
if (strArray.Length < )
{
color = new Color();
return false;
}
bool flag = true;
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num);
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num2);
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num3);
color = Color.FromScRgb(1f, num, num2, num3);
return flag;
} private static bool ParseFace(string content, out Face face)
{
face = new Face();
face.CoordinateIndices = new List<int>();
face.NormalIndices = new List<int>();
face.TextureCoordinateIndices = new List<int>();
foreach (string str in content.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
{
int num;
int num2;
int num3;
if (!ParseVertexReference(str, out num, out num2, out num3))
{
return false;
}
face.CoordinateIndices.Add(num);
face.NormalIndices.Add(num3);
face.TextureCoordinateIndices.Add(num2);
}
if (face.CoordinateIndices.Count < )
{
return false;
}
bool flag = face.TextureCoordinateIndices[] != 0x7fffffff;
bool flag2 = face.NormalIndices[] != 0x7fffffff;
for (int i = ; i < face.CoordinateIndices.Count; i++)
{
if ((face.TextureCoordinateIndices[i] != 0x7fffffff) != flag)
{
return false;
}
if ((face.NormalIndices[i] != 0x7fffffff) != flag2)
{
return false;
}
}
if (!flag)
{
face.TextureCoordinateIndices = null;
}
if (!flag2)
{
face.NormalIndices = null;
}
return true;
} private static KeywordType ParseKeyword(string line)
{
if ((line[] == '#') || (line[] == '$'))
{
return KeywordType.Comment;
}
foreach (KeywordData data in Keywords)
{
if (string.Compare(line, data.Name, StringComparison.OrdinalIgnoreCase) == )
{
return data.Type;
}
}
return KeywordType.UnrecognizedKeyword;
} private void ParseMtlFile(StreamReader streamReader, string rootPath, ref Dictionary<string, ObjMaterial> materialLibrary)
{
materialLibrary = new Dictionary<string, ObjMaterial>();
ObjMaterial currentMaterial = new ObjMaterial();
currentMaterial.Alpha = 1.0;
string str = string.Empty;
while ((str = streamReader.ReadLine()) != null)
{
str = str.TrimStart(Separators);
int length = str.IndexOfAny(Separators);
string line = string.Empty;
string s = string.Empty;
if (str.Trim().Length != )
{
BitmapImage image;
if (length != -)
{
line = str.Substring(, length);
while ((length < str.Length) && ((str[length] == ' ') || (str[length] == '\t')))
{
length++;
}
s = str.Substring(length);
}
else
{
line = str;
}
switch (ParseKeyword(line))
{
case KeywordType.UnrecognizedKeyword:
{
continue;
}
case KeywordType.UnimplementedKeyword:
case KeywordType.Comment:
case KeywordType.Face:
case KeywordType.Group:
case KeywordType.MaterialLibrary:
case KeywordType.ObjectName:
case KeywordType.SmoothingGroup:
case KeywordType.UseMaterial:
case KeywordType.GeometricVertex:
case KeywordType.VertexNormal:
case KeywordType.TextureVertex:
case KeywordType.RefractionIndex:
case KeywordType.Sharpness:
{
continue;
}
case KeywordType.IlluminationMode:
{
int num2;
if (!int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out num2))
{
goto Label_015A;
}
currentMaterial.IlluminationMode = num2;
continue;
}
case KeywordType.Alpha:
{
double num3;
if (!double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out num3))
{
goto Label_0192;
}
currentMaterial.Alpha = num3;
continue;
}
case KeywordType.Ambient:
{
Color color2;
if (!ParseColor(s, out color2))
{
goto Label_01C0;
}
currentMaterial.Ambient = color2;
continue;
}
case KeywordType.Diffuse:
{
Color color3;
if (!ParseColor(s, out color3))
{
goto Label_01EE;
}
currentMaterial.Diffuse = color3;
continue;
}
case KeywordType.Specular:
{
Color color4;
if (!ParseColor(s, out color4))
{
goto Label_02A8;
}
currentMaterial.Specular = color4;
continue;
}
case KeywordType.Emissive:
{
Color color5;
if (!ParseColor(s, out color5))
{
goto Label_02D6;
}
currentMaterial.Emissive = color5;
continue;
}
case KeywordType.AmbientTextureFilename:
{
image = this.LoadTexture(rootPath, s);
if (image != null)
{
currentMaterial.AmbientTextureFilename = s;
currentMaterial.AmbientTexture = image;
}
continue;
}
case KeywordType.BumpTextureFilename:
{
image = this.LoadTexture(rootPath, s);
if (image != null)
{
currentMaterial.BumpTextureFilename = s;
currentMaterial.BumpTexture = image;
}
continue;
}
case KeywordType.DiffuseTextureFilename:
{
image = this.LoadTexture(rootPath, s);
if (image != null)
{
currentMaterial.DiffuseTextureFilename = s;
currentMaterial.DiffuseTexture = image;
}
continue;
}
case KeywordType.ReflectionTextureFilename:
{
image = this.LoadTexture(rootPath, s);
if (image != null)
{
currentMaterial.ReflectionTextureFilename = s;
currentMaterial.ReflectionTexture = image;
}
continue;
}
case KeywordType.SpecularTextureFilename:
{
image = this.LoadTexture(rootPath, s);
if (image != null)
{
currentMaterial.SpecularTextureFilename = s;
currentMaterial.SpecularTexture = image;
}
continue;
}
case KeywordType.ShininessTextureFilename:
{
image = this.LoadTexture(rootPath, s);
if (image != null)
{
currentMaterial.ShininessTextureFilename = s;
currentMaterial.ShininessTexture = image;
}
continue;
}
case KeywordType.NewMaterial:
{
if ((currentMaterial.MaterialName != null) && (currentMaterial.Material == null))
{
currentMaterial.Material = CreateMaterial(currentMaterial);
materialLibrary[currentMaterial.MaterialName] = currentMaterial;
}
currentMaterial = new ObjMaterial();
currentMaterial.Alpha = 1.0;
currentMaterial.MaterialName = s;
continue;
}
case KeywordType.Shininess:
{
double num4;
if (!double.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out num4))
{
goto Label_027A;
}
currentMaterial.Shininess = num4;
continue;
}
case KeywordType.Transparency:
{
Color color;
ParseColor(s, out color);
continue;
}
}
}
continue;
Label_015A:
continue;
Label_0192:
continue;
Label_01C0:
continue;
Label_01EE:
continue;
Label_027A:
continue;
Label_02A8:
continue;
Label_02D6:
; }
if ((currentMaterial.MaterialName != null) && (currentMaterial.Material == null))
{
currentMaterial.Material = CreateMaterial(currentMaterial);
materialLibrary[currentMaterial.MaterialName] = currentMaterial;
}
} private static bool ParseVertex(string content, out Point3D vertex)
{
float num;
float num2;
float num3;
string[] strArray = content.Split(Separators, StringSplitOptions.RemoveEmptyEntries);
if (strArray.Length < )
{
vertex = new Point3D();
return false;
}
bool flag = true;
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num);
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num2);
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num3);
vertex = new Point3D((double)num, (double)num2, (double)num3);
return flag;
} private static bool ParseVertexNormal(string content, out Vector3D vector)
{
float num;
float num2;
float num3;
string[] strArray = content.Split(Separators, StringSplitOptions.RemoveEmptyEntries);
if (strArray.Length < )
{
vector = new Vector3D();
return false;
}
bool flag = true;
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num);
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num2);
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num3);
vector = new Vector3D((double)num, (double)num2, (double)num3);
return flag;
} private static bool ParseVertexReference(string content, out int geometricVertexIndex, out int textureVertexIndex, out int vertexNormalIndex)
{
string[] strArray = content.Split(new char[] { '/' });
bool flag = false;
geometricVertexIndex = 0x7fffffff;
textureVertexIndex = 0x7fffffff;
vertexNormalIndex = 0x7fffffff;
if (strArray.Length > )
{
flag = int.TryParse(strArray[], NumberStyles.Integer, CultureInfo.InvariantCulture, out geometricVertexIndex);
}
if ((strArray.Length > ) && (strArray[].Length > ))
{
flag &= int.TryParse(strArray[], NumberStyles.Integer, CultureInfo.InvariantCulture, out textureVertexIndex);
}
if ((strArray.Length > ) && (strArray[].Length > ))
{
flag &= int.TryParse(strArray[], NumberStyles.Integer, CultureInfo.InvariantCulture, out vertexNormalIndex);
}
return flag;
} private static bool ParseVertexTextureCoordinate(string content, out Point textureCoordinate)
{
float num;
float num2;
string[] strArray = content.Split(Separators, StringSplitOptions.RemoveEmptyEntries);
if (strArray.Length < )
{
textureCoordinate = new Point();
return false;
}
bool flag = true;
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num);
flag &= float.TryParse(strArray[], NumberStyles.Float, CultureInfo.InvariantCulture, out num2);
textureCoordinate = new Point((double)num, (double)(1f - num2));
return flag;
} private class Face
{
private List<int> coordinateIndices;
private Vector3D normal;
private List<int> normalIndices;
private List<int> textureCoordinateIndices; public List<int> CoordinateIndices
{
get
{
return this.coordinateIndices;
}
set
{
this.coordinateIndices = value;
}
} public Vector3D Normal
{
get
{
return this.normal;
}
set
{
this.normal = value;
}
} public List<int> NormalIndices
{
get
{
return this.normalIndices;
}
set
{
this.normalIndices = value;
}
} public List<int> TextureCoordinateIndices
{
get
{
return this.textureCoordinateIndices;
}
set
{
this.textureCoordinateIndices = value;
}
}
} private class Geometry
{
private int firstFaceIndex;
private int lastFaceIndex;
private System.Windows.Media.Media3D.Material material;
private string name; public Geometry(string name, System.Windows.Media.Media3D.Material material, int firstFaceIndex, int lastFaceIndex)
{
this.name = name;
this.material = material;
this.firstFaceIndex = firstFaceIndex;
this.lastFaceIndex = lastFaceIndex;
} public int FirstFaceIndex
{
get
{
return this.firstFaceIndex;
}
} public int LastFaceIndex
{
get
{
return this.lastFaceIndex;
}
} public System.Windows.Media.Media3D.Material Material
{
get
{
return this.material;
}
set
{
this.material = value;
}
} public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
} private class Group
{
private List<WavefrontObjLoader.Geometry> geometry = new List<WavefrontObjLoader.Geometry>();
private string name; public Group(string name)
{
this.name = name;
} public List<WavefrontObjLoader.Geometry> Geometry
{
get
{
return this.geometry;
}
} public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
} // [StructLayout(LayoutKind.Sequential)]
private struct KeywordData
{
public string Name;
public WavefrontObjLoader.KeywordType Type;
public KeywordData(string name, WavefrontObjLoader.KeywordType type)
{
this.Name = name;
this.Type = type;
}
} private enum KeywordType
{
InvalidKeyword,
UnrecognizedKeyword,
UnimplementedKeyword,
Comment,
Face,
Group,
MaterialLibrary,
ObjectName,
SmoothingGroup,
UseMaterial,
GeometricVertex,
VertexNormal,
TextureVertex,
IlluminationMode,
Alpha,
Ambient,
Diffuse,
Specular,
Emissive,
AmbientTextureFilename,
BumpTextureFilename,
DiffuseTextureFilename,
ReflectionTextureFilename,
SpecularTextureFilename,
ShininessTextureFilename,
NewMaterial,
RefractionIndex,
Shininess,
Sharpness,
Transparency,
Point,
Line,
Curve,
Curve2D,
Surface,
MergingGroup,
Call,
UseMap
} // [StructLayout(LayoutKind.Sequential)]
private struct ObjMaterial
{
public int IlluminationMode;
public Color Ambient;
public Color Diffuse;
public Color Specular;
public Color Emissive;
public double Alpha;
public double Shininess;
public string MaterialName;
public string AmbientTextureFilename;
public string BumpTextureFilename;
public string DiffuseTextureFilename;
public string ReflectionTextureFilename;
public string SpecularTextureFilename;
public string ShininessTextureFilename;
public BitmapImage AmbientTexture;
public BitmapImage BumpTexture;
public BitmapImage DiffuseTexture;
public BitmapImage ReflectionTexture;
public BitmapImage SpecularTexture;
public BitmapImage ShininessTexture;
public System.Windows.Media.Media3D.Material Material;
} private class UniqueVertex
{
private Point3D coordinate;
private Vector3D normal;
private bool normalSet;
private Point textureCoordinates;
private bool textureCoordinatesSet; public int CompareWithinTolerance(WavefrontObjLoader.UniqueVertex other, double tolerance)
{
if (other.normalSet != this.normalSet)
{
return other.normalSet.CompareTo(this.normalSet);
}
if (other.textureCoordinatesSet != this.textureCoordinatesSet)
{
return other.textureCoordinatesSet.CompareTo(this.textureCoordinatesSet);
}
if (!DoubleIsWithinToleranceOf(other.coordinate.X, this.coordinate.X, tolerance))
{
return other.coordinate.X.CompareTo(this.coordinate.X);
}
if (!DoubleIsWithinToleranceOf(other.coordinate.Y, this.coordinate.Y, tolerance))
{
return other.coordinate.Y.CompareTo(this.coordinate.Y);
}
if (!DoubleIsWithinToleranceOf(other.coordinate.Z, this.coordinate.Z, tolerance))
{
return other.coordinate.Z.CompareTo(this.coordinate.Z);
}
if (this.normalSet)
{
if (!DoubleIsWithinToleranceOf(other.normal.X, this.normal.X, tolerance))
{
return other.normal.X.CompareTo(this.normal.X);
}
if (!DoubleIsWithinToleranceOf(other.normal.Y, this.normal.Y, tolerance))
{
return other.normal.Y.CompareTo(this.normal.Y);
}
if (!DoubleIsWithinToleranceOf(other.normal.Z, this.normal.Z, tolerance))
{
return other.normal.Z.CompareTo(this.normal.X);
}
}
if (this.textureCoordinatesSet)
{
if (!DoubleIsWithinToleranceOf(other.textureCoordinates.X, this.textureCoordinates.X, tolerance))
{
return other.textureCoordinates.X.CompareTo(this.textureCoordinates.X);
}
if (!DoubleIsWithinToleranceOf(other.textureCoordinates.Y, this.textureCoordinates.Y, tolerance))
{
return other.textureCoordinates.Y.CompareTo(this.textureCoordinates.Y);
}
}
return ;
} private static bool DoubleIsWithinToleranceOf(double lhs, double rhs, double tolerance)
{
return (Math.Abs((double)(lhs - rhs)) < tolerance);
} public Point3D Coordinate
{
get
{
return this.coordinate;
}
set
{
this.coordinate = value;
}
} public Vector3D Normal
{
get
{
return this.normal;
}
set
{
this.normal = value;
this.normalSet = true;
}
} public bool NormalSet
{
get
{
return this.normalSet;
}
} public Point TextureCoordinates
{
get
{
return this.textureCoordinates;
}
set
{
this.textureCoordinates = value;
this.textureCoordinatesSet = true;
}
} public bool TextureCoordinatesSet
{
get
{
return this.textureCoordinatesSet;
}
}
} private class UniqueVertexComparer : Comparer<UniqueVertex>
{
public override int Compare(WavefrontObjLoader.UniqueVertex x, WavefrontObjLoader.UniqueVertex y)
{
return x.CompareWithinTolerance(y, WavefrontObjLoader.GeneratedVertexTolerance);
}
}
}
}

第二步:ModelVisual3DWithName.cs

public class ModelVisual3DWithName:ModelVisual3D
{
public string Name { get; set; } public object Tag { get; set; } }

第三步:MainWindow.xmal

<Grid x:Name="lay">
<Viewport3D x:Name="vp" Margin="0">
<Viewport3D.Camera>
<PerspectiveCamera FieldOfView="45" FarPlaneDistance="100" LookDirection="0,0,-3.4142135623731" NearPlaneDistance="0.1" Position="0,0,3.4142135623731" UpDirection="0,3,0"/>
</Viewport3D.Camera>
</Viewport3D>
<Slider Height="23" HorizontalAlignment="Left" Margin="220,288,0,0" Name="slider1" VerticalAlignment="Top" Width="100" Maximum="2000" />
<Slider Height="23" HorizontalAlignment="Left" Margin="49,288,0,0" Name="slider2" VerticalAlignment="Top" Width="100" Maximum="1000" />
<Slider Height="23" HorizontalAlignment="Left" Margin="367,288,0,0" Name="slider3" VerticalAlignment="Top" Width="100" Minimum="200" Maximum="2000" />
<Slider Height="23" HorizontalAlignment="Left" Margin="567,288,0,0" Name="slider4" VerticalAlignment="Top" Width="100" Minimum="200" Maximum="2000" />
</Grid>

第四步:MainWindow.xmal.cs

PerspectiveCamera myPCamera;
DirectionalLight myDirectionalLight;
Model3DGroup myModel3DGroup;
WavefrontObjLoader wfl;
ModelVisual3DWithName mv3dw;
public MainWindow()
{
InitializeComponent();
wfl = new WavefrontObjLoader(); slider1.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider1_ValueChanged);
slider2.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider2_ValueChanged);
slider3.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider3_ValueChanged);
slider4.ValueChanged += new RoutedPropertyChangedEventHandler<double>(slider4_ValueChanged);
createCamera();
createLight();
createModel3D();
create360();
//createAnimation();
}
#region //光源
private void createLight()
{
myDirectionalLight = new DirectionalLight();
myDirectionalLight.Color = Colors.White;
myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61);
}
#endregion
#region //摄像机
private void createCamera()
{
myPCamera = new PerspectiveCamera();
//myPCamera.Position = new Point3D(0,-1743,-4000);//看的方向
myPCamera.Position = new Point3D(0, 0, 1000);
myPCamera.LookDirection = new Vector3D(0,0,-1000);//摄影机看的方向
myPCamera.UpDirection = new Vector3D(0, 1, -0);
myPCamera.FieldOfView = 45;//法向量 摄影机上下颠倒,左转右转 myPCamera.NearPlaneDistance = 0.1;
myPCamera.FarPlaneDistance = 11050; vp.Camera = myPCamera;
}
#endregion
#region //模型
private void createModel3D()
{
myModel3DGroup = new Model3DGroup();
myModel3DGroup.Children.Add(myDirectionalLight); var m = wfl.LoadObjFile(@"C:/Users/Adminstrator/Desktop/3D动态加载/WpfApplication2/xx.obj");
m.Content = myModel3DGroup; vp.Children.Add(m);
}
#endregion
#region //360旋转动作
RotateTransform3D rtf3D;
AxisAngleRotation3D aar;
private void create360()
{
rtf3D = new RotateTransform3D();
aar = new AxisAngleRotation3D();
this.RegisterName("myAngleRotation", aar);
aar.Angle = 0;
aar.Axis = new Vector3D(0, 3, 0);
rtf3D.Rotation = aar;
myModel3DGroup.Transform = rtf3D;
myPCamera.Transform = rtf3D;
}
Storyboard sbd;
DoubleAnimation dan;
private void createAnimation()
{
sbd = new Storyboard();
dan = new DoubleAnimation(0,360,new Duration(TimeSpan.FromSeconds(10)));
dan.RepeatBehavior = RepeatBehavior.Forever;
Storyboard.SetTargetName(dan,"myAngleRotation");
Storyboard.SetTargetProperty(dan, new PropertyPath(AxisAngleRotation3D.AngleProperty));
sbd.Children.Add(dan);
sbd.BeginTime = TimeSpan.FromSeconds(5);//开始时间
sbd.Begin(this);
}
#endregion
void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
myPCamera.Position = new Point3D(slider1.Value , slider2.Value, slider3.Value);
}
void slider2_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
myPCamera.Position = new Point3D(slider1.Value, slider2.Value, slider3.Value);
}
void slider3_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
myPCamera.Position = new Point3D(slider1.Value, slider2.Value, slider3.Value);
}
void slider4_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
aar.Angle = slider4.Value;
}

WPF动态加载3D 放大-旋转-平移的更多相关文章

  1. WPF动态加载3D 放大-旋转-平移

    原文:WPF动态加载3D 放大-旋转-平移 WavefrontObjLoader.cs 第二步:ModelVisual3DWithName.cs public class ModelVisual3DW ...

  2. WPF 动态加载主题由zip

    经典主题的方式 主题战略 加载速度 本机支持 (不需要额外的代码) 支持代码为主题 (捆绑代码 & 资源成单独的文件) 支持资源层次结构中导航 动态加载 动态卸载 轻松地编辑和编译 (不需要安 ...

  3. WPF 3D动态加载模型文件

    原文:WPF 3D动态加载模型文件 这篇文章需要读者对WPF 3D有一个基本了解,至少看过官方的MSDN例子. 一般来说关于WPF使用3D的例子,都是下面的流程: 1.美工用3DMAX做好模型,生成一 ...

  4. [WPF学习笔记]动态加载XAML

    好久没写Blogs了,现在在看[WPF编程宝典],决定开始重新写博客,和大家一起分享技术. 在编程时我们常希望界面是动态的,可以随时变换而不需要重新编译自己的代码. 以下是动态加载XAML的一个事例代 ...

  5. mvvm模式下在WPF项目中动态加载项目的程序集和类

    在mvvm模式的wpf项目中有个需求需要去加载解决方案的程序集,并且根据程序集去动态加载当前程序集的类,做成下拉框形式. 效果: //全局定义 private ComboBox abList= nul ...

  6. WPF中动态加载XAML中的控件

    原文:WPF中动态加载XAML中的控件 using System; using System.Collections.Generic; using System.Linq; using System. ...

  7. WPF中Style文件的引用——使用xaml代码或者C#代码动态加载

    原文:WPF中Style文件的引用--使用xaml代码或者C#代码动态加载 WPF中控件拥有很多依赖属性(Dependency Property),我们可以通过编写自定义Style文件来控制控件的外观 ...

  8. Win8 Metro动态加载内容框架

    制作背景 为了参加ImagineCup 2013 世界公民类比赛,我们设计制作了一个可动态扩展的幼教类App.这个App需要能动态加载内容,内容包括带动画可交互的电子书,动画,视频,游戏. 技术支持 ...

  9. 携程Android App插件化和动态加载实践

    携程Android App的插件化和动态加载框架已上线半年,经历了初期的探索和持续的打磨优化,新框架和工程配置经受住了生产实践的考验.本文将详细介绍Android平台插件式开发和动态加载技术的原理和实 ...

随机推荐

  1. 短网址ShortUrl的算法

    场景: 我们在新浪微博上公布网址的时候.微博会自己主动判别网址.并将其转换.比如:http://t.cn/hrYnr0. 为什么要这样做的,原因我想有这样几点: 1.微博限制字数为140字一条,那么假 ...

  2. 适用android的MVP:怎样组织展示层

    原文 MVP for Android:How to organize presentation layer http://antonioleiva.com/mvp-android/ 译文 MVP(Mo ...

  3. [Android 4.4.2] 泛泰A870 Mokee4.4.2 20140531 RC1.0 by syhost

    欢迎关注泛泰非盈利专业第三方开发团队 VegaDevTeam  (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大师) loogeo cr ...

  4. window.print()打印网页(一)

    有时候需要将网页内容打印到纸上,最简单的一种方法是用window对象的print方法. window.print()默认打印当前网页的所有部分.(除了背景,默认打印都是白底黑字,如果有特别的设置 要另 ...

  5. C#添加水印

    using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...

  6. js cookie介绍和实例(用于自动登录,记住用户名等)

    js cookie介绍和实例(用于自动登录,记住用户名等) 一.总结 1.cookie在客户端:因为js是最初是用来在客户端和服务器端进行通信使用的,所以客户端比如js可以操作cookie正常 2.c ...

  7. Unity(IOC)学习笔记

    原文:Unity(IOC)学习笔记 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37591671/article/details/79432 ...

  8. 【BZOJ 4518】[Sdoi2016]征途

    [链接] 链接 [题意] 在这里输入题意 [题解] DP+斜率优化; \(D(x) = E(x^2)-E(x)^2\) 其中\(E(x)^2\)这一部分是确定的. 因为总长是确定的,分成的段数又是确定 ...

  9. ATL入门

    服务端代码----------------------------------------------------------------------------------------------- ...

  10. 2015第30周四Java日志组件

    Java 日志 API 从功能上来说,日志 API 本身所需求的功能非常简单,只需要能够记录一段文本即可.API 的使用者在需要进行记录时,根据当前的上下文信息构造出相应的文本信息,调用 API 完成 ...