private int mXResolution, mYResolution; // parse result from resolution #endregion Fields #region Constructors /// <summary> /// Constructor from parser. /// Please DO NOT change the parser, unless you really know what you are doing!! /// </summary> /// <param name="parser"></param> public ImageSpec(CommandFileParser parser) { mXResolution = 64; mYResolution = 64; mSamplesPerPixel = 1; parser.ParserRead(); while (!parser.IsEndElement("imagespec")) { if (parser.IsElement() && (!parser.IsElement("imagespec"))) { if (parser.IsElement("samples")) mSamplesPerPixel = parser.ReadInt(); else if (parser.IsElement("resolution")) { Vector2 n = parser.ReadVector2(); mXResolution = (int)n.X; mYResolution = (int)n.Y; } else parser.ParserError("ImageSpec"); } else parser.ParserRead(); } }
/// <summary> /// Constructor from parser. /// Please DO NOT change the parsing routine unless you know what you are doing). /// </summary> /// <param name="parser"></param> public RTLight(CommandFileParser parser) { parser.ParserRead(); while (!parser.IsEndElement("light")) { if (parser.IsElement() && (!parser.IsElement("light"))) { if (parser.IsElement("type")) { String type = parser.ReadString(); if (type.Equals("point")) mLight = new RTLightType_Point(parser); else if (type.Equals("directional")) mLight = new RTLightType_Directional(parser); else if (type.Equals("spot")) mLight = new RTLightType_Spot(parser); else parser.ParserError("Light: Unknown light type"); } else parser.ParserError("Light"); } else parser.ParserRead(); } }
private int mXResolution, mYResolution; // parse result from resolution /// <summary> /// Constructor from parser. /// Please DO NOT change the parser, unless you really know what you are doing!! /// </summary> /// <param name="parser"></param> public ImageSpec(CommandFileParser parser) { mXResolution = 64; mYResolution = 64; mSamplesPerPixel = 1; parser.ParserRead(); while (!parser.IsEndElement("imagespec")) { if (parser.IsElement() && (!parser.IsElement("imagespec"))) { if (parser.IsElement("samples")) { mSamplesPerPixel = parser.ReadInt(); } else if (parser.IsElement("resolution")) { Vector2 n = parser.ReadVector2(); mXResolution = (int)n.X; mYResolution = (int)n.Y; } else { parser.ParserError("ImageSpec"); } } else { parser.ParserRead(); } } }
public void Parse(CommandFileParser parser) { parser.ParserRead(); while (!parser.IsEndElement("rtspec")) { if (parser.IsElement() && (!parser.IsElement("rtspec"))) { if (parser.IsElement("generation")) { mGeneration = parser.ReadInt(); } else if (parser.IsElement("shadow")) { mComputeShadow = parser.ReadBool(); } else if (parser.IsElement("reflection")) { mComputeReflection = parser.ReadBool(); } else if (parser.IsElement("background")) { mBgColor = parser.ReadVector3(); } else { parser.ParserError("RTWorld"); } } else { parser.ParserRead(); } } }
private float muSize, mvSize; // entire object size in the U and V direction /// <summary> /// Constructs from parsing file and then intialize for intersection computation. /// </summary> /// <param name="parser"></param> public RTRectangle(CommandFileParser parser) { mType = RTGeometryType.Rectangle; // do we have a transform? bool hasTransform = false; Matrix xform = Matrix.Identity; mVertices = new Vector3[4]; mMaterialIndex = 0; int count = 0; parser.ParserRead(); while (!parser.IsEndElement("rectangle")) { if (parser.IsElement() && (!parser.IsElement("rectangle"))) { if (parser.IsElement("vertices")) { mVertices[count] = parser.ReadVector3(); count++; } else if (parser.IsElement("material")) { mMaterialIndex = parser.ReadInt(); } else if (parser.IsElement("xform")) { hasTransform = true; xform = ParseTransform(parser); } else { parser.ParserError("Rectangle"); } } else { parser.ParserRead(); } } if (count != 4) { parser.ParserError("Rectangle: vertex indexPtr = " + count); } else { if (hasTransform) { for (int i = 0; i < 4; i++) { mVertices[i] = Vector3.Transform(mVertices[i], xform); } } InitializeRectangle(); } }
private Vector3[] mVertices; // always 3 vertices #endregion Fields #region Constructors /// <summary> /// Constructs from parsing file and then intialize for intersection computation. /// </summary> /// <param name="parser"></param> public RTTriangle(CommandFileParser parser) { mType = RTGeometryType.Triangle; // do we have a transform? bool hasTransform = false; Matrix xform = Matrix.Identity; mVertices = new Vector3[3]; mVertexUV = new Vector2[3]; mMaterialIndex = 0; int count = 0; parser.ParserRead(); while (!parser.IsEndElement("triangle")) { if (parser.IsElement() && (!parser.IsElement("triangle"))) { if (parser.IsElement("vertices")) { mVertices[count] = parser.ReadVector3(); } else if (parser.IsElement("uv")) { mVertexUV[count] = parser.ReadVector2(); count++; } else if (parser.IsElement("xform")) { hasTransform = true; xform = ParseTransform(parser); } else if (parser.IsElement("material")) mMaterialIndex = parser.ReadInt(); else parser.ParserError("Triangle"); } else parser.ParserRead(); } if (count != 3) { parser.ParserError("Triangle: vertex indexPtr = " + count); } else { if (hasTransform) { mVertices[0] = Vector3.Transform(mVertices[0], xform); mVertices[1] = Vector3.Transform(mVertices[1], xform); mVertices[2] = Vector3.Transform(mVertices[2], xform); } InitializeTriangle(); } }
/// <summary> /// constructs from parsing command file. /// </summary> /// <param name="parser"></param> public RTSphere(CommandFileParser parser) { mType = RTGeometryType.Sphere; // do we have a transform? bool hasTransform = false; Matrix xform = Matrix.Identity; mCenter = new Vector3(0f, 0f, 0f); mRadius = 1f; mMaterialIndex = 0; parser.ParserRead(); while (!parser.IsEndElement("sphere")) { if (parser.IsElement() && (!parser.IsElement("sphere"))) { if (parser.IsElement("center")) { mCenter = parser.ReadVector3(); } else if (parser.IsElement("radius")) { mRadius = parser.ReadFloat(); } else if (parser.IsElement("material")) { mMaterialIndex = parser.ReadInt(); } else if (parser.IsElement("xform")) { hasTransform = true; xform = ParseTransform(parser); } else { parser.ParserError("Sphere"); } } else { parser.ParserRead(); } } if (hasTransform) { Vector3 p = mCenter + Vector3.One * mRadius; mCenter = Vector3.Transform(mCenter, xform); p = Vector3.Transform(p, xform); // ****WARNING****: does not handle unporportional scaling!! mRadius = (mCenter - p).Length(); } mRadiusSquared = mRadius * mRadius; }
protected Vector3 mPixelOrigin; // lower left corner /// <summary> /// Construcs from parsing the command file. /// DO NOT CHANGE the parsing loop unless you know what you are doing. /// You can add in initialization computation after the loop /// </summary> /// <param name="parser"></param> public RTCamera(CommandFileParser parser) { mEye = new Vector3(0f, 0f, 0f); mAt = new Vector3(0f, 0f, 1f); mUp = new Vector3(0f, 1f, 0f); mFOV = 25f; mFocus = 1f; parser.ParserRead(); while (!parser.IsEndElement("camera")) { if (parser.IsElement() && (!parser.IsElement("camera"))) { if (parser.IsElement("eye")) { mEye = parser.ReadVector3(); } else if (parser.IsElement("lookat")) { mAt = parser.ReadVector3(); } else if (parser.IsElement("upvector")) { mUp = parser.ReadVector3(); } else if (parser.IsElement("fov")) { mFOV = parser.ReadFloat(); } else if (parser.IsElement("focus")) { mFocus = parser.ReadFloat(); } else { parser.ParserError("Camera"); } } else { parser.ParserRead(); } } // You can add in your initialization computation after this line mViewDir = mAt - mEye; // now make sure ViewDir and Up are perpendicular mSideVec = Vector3.Cross(mUp, mViewDir); mUp = Vector3.Cross(mViewDir, mSideVec); mSideVec.Normalize(); mViewDir.Normalize(); mUp.Normalize(); }
private float mThetaRange; // range from 0 to this value (mPeroid * 2PI) #endregion Fields #region Constructors /// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Sine(CommandFileParser parser) { mPeriod = 1f; mDirection = Vector2.UnitX; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("period")) mPeriod = parser.ReadFloat(); else if (parser.IsElement("direction")) mDirection = parser.ReadVector2(); else if (parser.IsElement("color1")) mColor1 = parser.ReadVector3(); else if (parser.IsElement("color2")) mColor2 = parser.ReadVector3(); else parser.ParserError("TextureType_Sine"); } else parser.ParserRead(); } mThetaRange = mPeriod * (float) Math.PI * 2f; mDirection = Vector2.Normalize(mDirection); }
private Bitmap mTextureImage; // the bitmap image file. /// <summary> /// Constructs from parsing the command file. /// DO NOT change the parser loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Color(CommandFileParser parser) { while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("filename")) { String name = parser.ReadString(); name = parser.FullPath() + "\\" + name; if (System.IO.File.Exists(name)) { mTextureImage = new Bitmap(name, true); } else { parser.ParserError("TextureType_Color filename"); } } else { parser.ParserError("TextureType_Color"); } } else { parser.ParserRead(); } } }
/// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Noise(CommandFileParser parser) { if (null == mPermutation) InitPermutation(); mColor1 = Vector3.One; mColor2 = Vector3.Zero; mFrequency = 1; mAmplitude = 1f; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("color1")) mColor1 = parser.ReadVector3(); else if (parser.IsElement("color2")) mColor2 = parser.ReadVector3(); else if (parser.IsElement("frequency")) mFrequency = parser.ReadInt(); else if (parser.IsElement("amplitude")) mAmplitude = parser.ReadFloat(); else parser.ParserError("TextureType_Noise"); } else parser.ParserRead(); } }
/// <summary> /// Constructor from parser. /// Please DO NOT change the parsing routine unless you know what you are doing). /// </summary> /// <param name="parser"></param> public RTLightType_Directional(CommandFileParser parser) { mLightSourceType = RTLightSourceType.RTLightSourceTypeDirection; while (!parser.IsEndElement("light")) { if (parser.IsElement() && (!parser.IsElement("light"))) { if (parser.IsElement("color")) { mColor = parser.ReadVector3(); } else if (parser.IsElement("position")) { mPosition = parser.ReadVector3(); } else if (parser.IsElement("direction")) { mDirection = parser.ReadVector3(); } else { parser.ParserError("Light"); } } else { parser.ParserRead(); } } mDirection = -Vector3.Normalize(mDirection); }
private Bitmap mTextureImage; // the bitmap image file. #endregion Fields #region Constructors /// <summary> /// Constructs from parsing the command file. /// DO NOT change the parser loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Bump(CommandFileParser parser) { mGain = 1.0f; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("filename")) { String name = parser.ReadString(); name = parser.FullPath() + "\\" + name; if (System.IO.File.Exists(name)) mTextureImage = new Bitmap(name, true); else parser.ParserError("TextureType_Bump filename"); } else if (parser.IsElement("gain")) mGain = parser.ReadFloat(); else parser.ParserError("TextureType_Bump"); } else parser.ParserRead(); } mInvWidth = 1f / (float)(mTextureImage.Width - 1); mInvHeight = 1f / (float)(mTextureImage.Height - 1); }
/// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Checker(CommandFileParser parser) { while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("urepeat")) { mURepeat = parser.ReadInt(); } else if (parser.IsElement("vrepeat")) { mVRepeat = parser.ReadInt(); } else if (parser.IsElement("color1")) { mColor1 = parser.ReadVector3(); } else if (parser.IsElement("color2")) { mColor2 = parser.ReadVector3(); } else { parser.ParserError("TextureType_Checker"); } } else { parser.ParserRead(); } } }
private bool mUseDepthMap = false; // off /// <summary> /// Constructor from parser. /// Please DO NOT change the parsing routine unless you know what you are doing). /// </summary> /// <param name="parser"></param> public RTLightType_Spot(CommandFileParser parser) { mLightSourceType = RTLightSourceType.RTLightSourceTypeSpot; while (!parser.IsEndElement("light")) { if (parser.IsElement() && (!parser.IsElement("light"))) { if (parser.IsElement("color")) { mColor = parser.ReadVector3(); } else if (parser.IsElement("position")) { mPosition = parser.ReadVector3(); } else if (parser.IsElement("direction")) { mDirection = parser.ReadVector3(); } else if (parser.IsElement("innerAngle")) { mInnerAngle = MathHelper.ToRadians(parser.ReadFloat()); } else if (parser.IsElement("outerAngle")) { mOuterAngle = MathHelper.ToRadians(parser.ReadFloat()); } else if (parser.IsElement("falloff")) { mFallOff = parser.ReadFloat(); } else if (parser.IsElement("depthMap")) { mUseDepthMap = parser.ReadBool(); } else if (parser.IsElement("depthMapResolution")) { mRes = parser.ReadInt(); } else if (parser.IsElement("depthMapFilterRes")) { mFilterRes = parser.ReadInt(); } else { parser.ParserError("Light"); } } else { parser.ParserRead(); } } mDirection = -Vector3.Normalize(mDirection); mCosInAngle = (float)Math.Cos(mInnerAngle / 2); mCosOutAngle = (float)Math.Cos(mOuterAngle / 2); mFallOffDenominator = 1f / (mCosInAngle - mCosOutAngle); }
/// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Ramp(CommandFileParser parser) { mRepeat = 1f; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("repeat")) { mRepeat = parser.ReadFloat(); } else if (parser.IsElement("color1")) { mColor1 = parser.ReadVector3(); } else if (parser.IsElement("color2")) { mColor2 = parser.ReadVector3(); } else { parser.ParserError("TextureType_Ramp"); } } else { parser.ParserRead(); } } if (mRepeat <= 0) { mRepeat = 1f; } }
/// <summary> /// Constructor from parser. /// Please DO NOT change the parsing routine unless you know what you are doing). /// </summary> /// <param name="parser"></param> public RTLightType_Point(CommandFileParser parser) { mLightSourceType = RTLightSourceType.RTLightSourceTypePoint; while (!parser.IsEndElement("light")) { if (parser.IsElement() && (!parser.IsElement("light"))) { if (parser.IsElement("color")) { mColor = parser.ReadVector3(); } else if (parser.IsElement("position")) { mPosition = parser.ReadVector3(); } else { parser.ParserError("Light"); } } else { parser.ParserRead(); } } }
/// <summary> /// Parse command line for <xform> </xform> that is embedeed inside /// Geometry. /// </summary> /// <param name="parser"></param> /// <returns></returns> static protected Matrix ParseTransform(CommandFileParser parser) { Matrix xform = Matrix.Identity; Vector3 translation = Vector3.Zero; Matrix rotation = Matrix.Identity; Vector3 scale = Vector3.One; parser.ParserRead(); while (!parser.IsEndElement("xform")) { if (parser.IsElement() && (!parser.IsElement("xform"))) { if (parser.IsElement("translation")) { translation = parser.ReadVector3(); } else if (parser.IsElement("rotationX")) { float rotXInDegree = parser.ReadFloat(); rotation = rotation * Matrix.CreateRotationX(MathHelper.ToRadians(rotXInDegree)); } else if (parser.IsElement("rotationY")) { float rotXInDegree = parser.ReadFloat(); rotation = rotation * Matrix.CreateRotationY(MathHelper.ToRadians(rotXInDegree)); } else if (parser.IsElement("rotationZ")) { float rotXInDegree = parser.ReadFloat(); rotation = rotation * Matrix.CreateRotationZ(MathHelper.ToRadians(rotXInDegree)); } else if (parser.IsElement("scale")) { scale = parser.ReadVector3(); } else { parser.ParserError("xform"); } } else { parser.ParserRead(); } } return(Matrix.CreateScale(scale) * rotation * Matrix.CreateTranslation(translation)); }
private float mRadiusSquared; // r*r #endregion Fields #region Constructors /// <summary> /// constructs from parsing command file. /// </summary> /// <param name="parser"></param> public RTSphere(CommandFileParser parser) { mType = RTGeometryType.Sphere; // do we have a transform? bool hasTransform = false; Matrix xform = Matrix.Identity; mCenter = new Vector3(0f, 0f, 0f); mRadius = 1f; mMaterialIndex = 0; parser.ParserRead(); while (!parser.IsEndElement("sphere")) { if (parser.IsElement() && (!parser.IsElement("sphere"))) { if (parser.IsElement("center")) mCenter = parser.ReadVector3(); else if (parser.IsElement("radius")) mRadius = parser.ReadFloat(); else if (parser.IsElement("material")) mMaterialIndex = parser.ReadInt(); else if (parser.IsElement("xform")) { hasTransform = true; xform = ParseTransform(parser); } else parser.ParserError("Sphere"); } else parser.ParserRead(); } if (hasTransform) { Vector3 p = mCenter + Vector3.One * mRadius; mCenter = Vector3.Transform(mCenter, xform); p = Vector3.Transform(p, xform); // ****WARNING****: does not handle unporportional scaling!! mRadius = (mCenter - p).Length(); } mRadiusSquared = mRadius * mRadius; }
/// <summary> /// Construcs from parsing the command file. /// DO NOT CHANGE the parsing loop unless you know what you are doing. /// You can add in initialization computation after the loop /// </summary> /// <param name="parser"></param> public RTCamera(CommandFileParser parser) { mEye = new Vector3(0f, 0f, 0f); mAt = new Vector3(0f, 0f, 1f); mUp = new Vector3(0f, 1f, 0f); mFOV = 25f; mFocus = 1f; parser.ParserRead(); while (!parser.IsEndElement("camera")) { if (parser.IsElement() && (!parser.IsElement("camera"))) { if (parser.IsElement("eye")) mEye = parser.ReadVector3(); else if (parser.IsElement("lookat")) mAt = parser.ReadVector3(); else if (parser.IsElement("upvector")) mUp = parser.ReadVector3(); else if (parser.IsElement("fov")) mFOV = parser.ReadFloat(); else if (parser.IsElement("focus")) mFocus = parser.ReadFloat(); else parser.ParserError("Camera"); } else parser.ParserRead(); } // You can add in your initialization computation after this line mViewDir = mAt - mEye; // now make sure ViewDir and Up are perpendicular mSideVec = Vector3.Cross(mUp, mViewDir); mUp = Vector3.Cross(mViewDir, mSideVec); mSideVec.Normalize(); mViewDir.Normalize(); mUp.Normalize(); }
private float mThetaRange; // range from 0 to this value (mPeroid * 2PI) /// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Marble(CommandFileParser parser) { // From super class: // Color1/2 // Frequency and // Amplitude mPeriod = 1f; mDirection = Vector3.UnitY; mAmplitude = 1f; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("period")) { mPeriod = parser.ReadFloat(); } else if (parser.IsElement("frequency")) { mFrequency = parser.ReadInt(); } else if (parser.IsElement("amplitude")) { mAmplitude = parser.ReadFloat(); } else if (parser.IsElement("direction")) { mDirection = parser.ReadVector3(); } else if (parser.IsElement("color1")) { mColor1 = parser.ReadVector3(); } else if (parser.IsElement("color2")) { mColor2 = parser.ReadVector3(); } else { parser.ParserError("TextureType_Marble"); } } else { parser.ParserRead(); } } mThetaRange = mPeriod * (float)Math.PI * 2f; mDirection = Vector3.Normalize(mDirection); }
public void Parse(CommandFileParser parser) { parser.ParserRead(); while (!parser.IsEndElement("rtspec")) { if (parser.IsElement() && (!parser.IsElement("rtspec"))) { if (parser.IsElement("generation")) mGeneration = parser.ReadInt(); else if (parser.IsElement("shadow")) mComputeShadow = parser.ReadBool(); else if (parser.IsElement("reflection")) mComputeReflection = parser.ReadBool(); else if (parser.IsElement("background")) mBgColor = parser.ReadVector3(); else parser.ParserError("RTWorld"); } else parser.ParserRead(); } }
/// <summary> /// Parse command line for <xform> </xform> that is embedeed inside /// Geometry. /// </summary> /// <param name="parser"></param> /// <returns></returns> protected static Matrix ParseTransform(CommandFileParser parser) { Matrix xform = Matrix.Identity; Vector3 translation = Vector3.Zero; Matrix rotation = Matrix.Identity; Vector3 scale = Vector3.One; parser.ParserRead(); while (!parser.IsEndElement("xform")) { if (parser.IsElement() && (!parser.IsElement("xform"))) { if (parser.IsElement("translation")) translation = parser.ReadVector3(); else if (parser.IsElement("rotationX")) { float rotXInDegree = parser.ReadFloat(); rotation = rotation * Matrix.CreateRotationX(MathHelper.ToRadians(rotXInDegree)); } else if (parser.IsElement("rotationY")) { float rotXInDegree = parser.ReadFloat(); rotation = rotation * Matrix.CreateRotationY(MathHelper.ToRadians(rotXInDegree)); } else if (parser.IsElement("rotationZ")) { float rotXInDegree = parser.ReadFloat(); rotation = rotation * Matrix.CreateRotationZ(MathHelper.ToRadians(rotXInDegree)); } else if (parser.IsElement("scale")) scale = parser.ReadVector3(); else parser.ParserError("xform"); } else parser.ParserRead(); } return Matrix.CreateScale(scale) * rotation * Matrix.CreateTranslation(translation); }
private RTTextureType mTexture; // The actualy texture functionality. #endregion Fields #region Constructors /// <summary> /// Constrctus from parsing command file. xlm elements: /// index, type /// MUST exist before any other texture type-specific elements!! /// </summary> /// <param name="parser"></param> public RTTexture(CommandFileParser parser) { parser.ParserRead(); while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("index")) { int i = parser.ReadInt(); SetResourceIndex(i); } else if (parser.IsElement("type")) { String type = parser.ReadString(); if (type.Equals("color")) mTexture = new RTTextureType_Color(parser); else if (type.Equals("checker")) mTexture = new RTTextureType_Checker(parser); else if (type.Equals("noise")) mTexture = new RTTextureType_Noise(parser); else if (type.Equals("sine")) mTexture = new RTTextureType_Sine(parser); else if (type.Equals("marble")) mTexture = new RTTextureType_Marble(parser); else if (type.Equals("ramp")) mTexture = new RTTextureType_Ramp(parser); else if (type.Equals("grid")) mTexture = new RTTextureType_Grid(parser); else if (type.Equals("bump")) mTexture = new RTTextureType_Bump(parser); else parser.ParserError("Texture: unknown type"); } else parser.ParserError("Texture"); } else parser.ParserRead(); } }
/// <summary> /// Constructor from parser. /// Please DO NOT change the parsing routine unless you know what you are doing). /// </summary> /// <param name="parser"></param> public RTLight(CommandFileParser parser) { parser.ParserRead(); while (!parser.IsEndElement("light")) { if (parser.IsElement() && (!parser.IsElement("light"))) { if (parser.IsElement("type")) { String type = parser.ReadString(); if (type.Equals("point")) { mLight = new RTLightType_Point(parser); } else if (type.Equals("directional")) { mLight = new RTLightType_Directional(parser); } else if (type.Equals("spot")) { mLight = new RTLightType_Spot(parser); } else { parser.ParserError("Light: Unknown light type"); } } else { parser.ParserError("Light"); } } else { parser.ParserRead(); } } }
/// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Noise(CommandFileParser parser) { if (null == mPermutation) { InitPermutation(); } mColor1 = Vector3.One; mColor2 = Vector3.Zero; mFrequency = 1; mAmplitude = 1f; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("color1")) { mColor1 = parser.ReadVector3(); } else if (parser.IsElement("color2")) { mColor2 = parser.ReadVector3(); } else if (parser.IsElement("frequency")) { mFrequency = parser.ReadInt(); } else if (parser.IsElement("amplitude")) { mAmplitude = parser.ReadFloat(); } else { parser.ParserError("TextureType_Noise"); } } else { parser.ParserRead(); } } }
/// <summary> /// Constructor from parser. /// Please DO NOT change the parsing routine unless you know what you are doing). /// </summary> /// <param name="parser"></param> public RTLightType_Point(CommandFileParser parser) { mLightSourceType = RTLightSourceType.RTLightSourceTypePoint; while (!parser.IsEndElement("light")) { if (parser.IsElement() && (!parser.IsElement("light"))) { if (parser.IsElement("color")) mColor = parser.ReadVector3(); else if (parser.IsElement("position")) mPosition = parser.ReadVector3(); else parser.ParserError("Light"); } else parser.ParserRead(); } }
private Bitmap mTextureImage; // the bitmap image file. #endregion Fields #region Constructors /// <summary> /// Constructs from parsing the command file. /// DO NOT change the parser loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Color(CommandFileParser parser) { while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("filename")) { String name = parser.ReadString(); name = parser.FullPath() + "\\" + name; if (System.IO.File.Exists(name)) mTextureImage = new Bitmap(name, true); else parser.ParserError("TextureType_Color filename"); } else parser.ParserError("TextureType_Color"); } else parser.ParserRead(); } }
private int mURepeat, mVRepeat; // UV Repeat from command file #endregion Fields #region Constructors /// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Checker(CommandFileParser parser) { while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("urepeat")) mURepeat = parser.ReadInt(); else if (parser.IsElement("vrepeat")) mVRepeat = parser.ReadInt(); else if (parser.IsElement("color1")) mColor1 = parser.ReadVector3(); else if (parser.IsElement("color2")) mColor2 = parser.ReadVector3(); else parser.ParserError("TextureType_Checker"); } else parser.ParserRead(); } }
/// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Sine(CommandFileParser parser) { mPeriod = 1f; mDirection = Vector2.UnitX; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("period")) { mPeriod = parser.ReadFloat(); } else if (parser.IsElement("direction")) { mDirection = parser.ReadVector2(); } else if (parser.IsElement("color1")) { mColor1 = parser.ReadVector3(); } else if (parser.IsElement("color2")) { mColor2 = parser.ReadVector3(); } else { parser.ParserError("TextureType_Sine"); } } else { parser.ParserRead(); } } mThetaRange = mPeriod * (float)Math.PI * 2f; mDirection = Vector2.Normalize(mDirection); }
private bool mUseDepthMap = false; // off #endregion Fields #region Constructors /// <summary> /// Constructor from parser. /// Please DO NOT change the parsing routine unless you know what you are doing). /// </summary> /// <param name="parser"></param> public RTLightType_Spot(CommandFileParser parser) { mLightSourceType = RTLightSourceType.RTLightSourceTypeSpot; while (!parser.IsEndElement("light")) { if (parser.IsElement() && (!parser.IsElement("light"))) { if (parser.IsElement("color")) mColor = parser.ReadVector3(); else if (parser.IsElement("position")) mPosition = parser.ReadVector3(); else if (parser.IsElement("direction")) mDirection = parser.ReadVector3(); else if (parser.IsElement("innerAngle")) mInnerAngle = MathHelper.ToRadians(parser.ReadFloat()); else if (parser.IsElement("outerAngle")) mOuterAngle = MathHelper.ToRadians(parser.ReadFloat()); else if (parser.IsElement("falloff")) mFallOff = parser.ReadFloat(); else if (parser.IsElement("depthMap")) mUseDepthMap = parser.ReadBool(); else if (parser.IsElement("depthMapResolution")) mRes = parser.ReadInt(); else if (parser.IsElement("depthMapFilterRes")) mFilterRes = parser.ReadInt(); else parser.ParserError("Light"); } else parser.ParserRead(); } mDirection = -Vector3.Normalize(mDirection); mCosInAngle = (float) Math.Cos(mInnerAngle / 2); mCosOutAngle = (float)Math.Cos(mOuterAngle / 2); mFallOffDenominator = 1f / (mCosInAngle - mCosOutAngle); }
/// <summary> /// Constructs from parsing the command file. /// DO NOT change the parser loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Bump(CommandFileParser parser) { mGain = 1.0f; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("filename")) { String name = parser.ReadString(); name = parser.FullPath() + "\\" + name; if (System.IO.File.Exists(name)) { mTextureImage = new Bitmap(name, true); } else { parser.ParserError("TextureType_Bump filename"); } } else if (parser.IsElement("gain")) { mGain = parser.ReadFloat(); } else { parser.ParserError("TextureType_Bump"); } } else { parser.ParserRead(); } } mInvWidth = 1f / (float)(mTextureImage.Width - 1); mInvHeight = 1f / (float)(mTextureImage.Height - 1); }
/// <summary> /// Constructor from parser. /// Please DO NOT change the parsing routine unless you know what you are doing). /// </summary> /// <param name="parser"></param> public RTLightType_Directional(CommandFileParser parser) { mLightSourceType = RTLightSourceType.RTLightSourceTypeDirection; while (!parser.IsEndElement("light")) { if (parser.IsElement() && (!parser.IsElement("light"))) { if (parser.IsElement("color")) mColor = parser.ReadVector3(); else if (parser.IsElement("position")) mPosition = parser.ReadVector3(); else if (parser.IsElement("direction")) mDirection = parser.ReadVector3(); else parser.ParserError("Light"); } else parser.ParserRead(); } mDirection = -Vector3.Normalize(mDirection); }
private float mRepeat; // how many periods to be fitted within 0 to 1 U #endregion Fields #region Constructors /// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Ramp(CommandFileParser parser) { mRepeat = 1f; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("repeat")) mRepeat = parser.ReadFloat(); else if (parser.IsElement("color1")) mColor1 = parser.ReadVector3(); else if (parser.IsElement("color2")) mColor2 = parser.ReadVector3(); else parser.ParserError("TextureType_Ramp"); } else parser.ParserRead(); } if (mRepeat <= 0) mRepeat = 1f; }
private float mThetaRange; // range from 0 to this value (mPeroid * 2PI) #endregion Fields #region Constructors /// <summary> /// Constrcuts from the commandfile. /// DO NOT change the pasing loop unless you know what you are doing. /// </summary> /// <param name="parser"></param> public RTTextureType_Marble(CommandFileParser parser) { // From super class: // Color1/2 // Frequency and // Amplitude mPeriod = 1f; mDirection = Vector3.UnitY; mAmplitude = 1f; while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("period")) mPeriod = parser.ReadFloat(); else if (parser.IsElement("frequency")) mFrequency = parser.ReadInt(); else if (parser.IsElement("amplitude")) mAmplitude = parser.ReadFloat(); else if (parser.IsElement("direction")) mDirection = parser.ReadVector3(); else if (parser.IsElement("color1")) mColor1 = parser.ReadVector3(); else if (parser.IsElement("color2")) mColor2 = parser.ReadVector3(); else parser.ParserError("TextureType_Marble"); } else parser.ParserRead(); } mThetaRange = mPeriod * (float) Math.PI * 2f; mDirection = Vector3.Normalize(mDirection); }
public static void ParseMeshForTriangles(CommandFileParser parser, ContentManager meshLoader, SceneDatabase sceneDatabase) { String meshFileName = null; int material = 0; // has xform? bool hasTransform = false; Matrix xform = Matrix.Identity; Matrix invT = Matrix.Identity; #region Parse the command file parser.ParserRead(); while (!parser.IsEndElement("mesh")) { if (parser.IsElement() && (!parser.IsElement("mesh"))) { if (parser.IsElement("filename")) { meshFileName = parser.ReadString(); } else if (parser.IsElement("xform")) { hasTransform = true; xform = ParseTransform(parser); } else if (parser.IsElement("material")) material = parser.ReadInt(); else parser.ParserError("mesh"); } else parser.ParserRead(); } #endregion if (null == meshFileName) { parser.ParserError("No Mesh filename!"); return; } if (hasTransform) invT = Matrix.Transpose(Matrix.Invert(xform)); Model model = meshLoader.Load<Model>(meshFileName); Byte[] localVertexBuffer = null; Int32[] localIndexBuffer = null; Vector3[] vertexPosition = null; Vector3[] normalAtVertex = null; Vector2[] uvAtVertex = null; bool hasPosition = false; bool hasNormal = false; bool hasUV = false; foreach (ModelMesh mesh in model.Meshes) { foreach (ModelMeshPart part in mesh.MeshParts) { int numIndices = part.IndexBuffer.IndexCount; // total number of localIndexBuffer in the buffer int numVertices = part.VertexBuffer.VertexCount; // total number of vertices in the buffer #region Only need to load/translate these buffers once! // *** REALLY? *** if (null == localIndexBuffer) { vertexPosition = new Vector3[numVertices]; normalAtVertex = new Vector3[numVertices]; uvAtVertex = new Vector2[numVertices]; localIndexBuffer = LoadIndexBuffer(part); int numBytes = numVertices * part.VertexBuffer.VertexDeclaration.VertexStride; localVertexBuffer = new Byte[numBytes]; part.VertexBuffer.GetData<Byte>(localVertexBuffer); VertexElement[] vertexElements = part.VertexBuffer.VertexDeclaration.GetVertexElements(); int bufferOffset = 0; #region parse each vertex // now get all the vertices for (int vertCount = 0; vertCount < numVertices; vertCount++) { // parse through the elements bufferOffset = vertCount * part.VertexBuffer.VertexDeclaration.VertexStride; hasUV = false; // do this for each vertex for (int e = 0; e < vertexElements.Length; e++) { switch (vertexElements[e].VertexElementUsage) { case VertexElementUsage.Position: hasPosition = true; // Vertex position int vertexByteOffset = bufferOffset + vertexElements[e].Offset; vertexPosition[vertCount].X = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); vertexByteOffset += 4; vertexPosition[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); vertexByteOffset += 4; vertexPosition[vertCount].Z = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); break; case VertexElementUsage.Normal: hasNormal = true; int normalByteOffset = bufferOffset + vertexElements[e].Offset; normalAtVertex[vertCount].X = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); normalByteOffset += 4; normalAtVertex[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); normalByteOffset += 4; normalAtVertex[vertCount].Z = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); break; case VertexElementUsage.TextureCoordinate: if (!hasUV) { // if more than one defined, will only use the first one hasUV = true; int uvByteOffset = bufferOffset + vertexElements[e].Offset; uvAtVertex[vertCount].X = BitConverter.ToSingle(localVertexBuffer, uvByteOffset); uvByteOffset += 4; uvAtVertex[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, uvByteOffset); } break; // ignore all other cases } // the switch on usage for parsing } // for of vertexElements } // for each vertex #endregion #region compute the transform for each vertex // now do the transform if (hasTransform) { for (int v = 0; v < numVertices; v++) vertexPosition[v] = Vector3.Transform(vertexPosition[v], xform); if (hasNormal) for (int v = 0; v < numVertices; v++) { normalAtVertex[v] = Vector3.Transform(normalAtVertex[v], invT); normalAtVertex[v] = Vector3.Normalize(normalAtVertex[v]); } } #endregion } #endregion // now start working on this particular part ... int startIndex = part.StartIndex; int vertexOffset = part.VertexOffset; // start from part.StartIndex int numTriangles = part.PrimitiveCount; #region create the triangles // now all vertice are stored. // let's create the Triangles for (int nthT = 0; nthT < numTriangles; nthT++) { Vector3[] vertices = new Vector3[3]; Vector2[] uv = new Vector2[3]; Vector3[] normals = null; if (hasNormal) normals = new Vector3[3]; #region copy vertex info int indexOffset = startIndex + (nthT * 3); for (int i = 0; i < 3; i++) { int index = vertexOffset + localIndexBuffer[indexOffset + i]; vertices[i] = vertexPosition[index]; uv[i] = uvAtVertex[index]; if (hasNormal) normals[i] = normalAtVertex[index]; } #endregion // now create the new triangle // watch out for bad triangles!! if (hasPosition) { if (!hasNormal) normalAtVertex = null; Vector3 aVec = vertices[1] - vertices[0]; if (aVec.LengthSquared() > float.Epsilon) { Vector3 bVec = vertices[2] - vertices[0]; if (bVec.LengthSquared() > float.Epsilon) { RTTriangle t = new RTTriangle(vertices, normals, uv, material); sceneDatabase.AddGeom(t); } } } } #endregion } } }
private RTTextureType mTexture; // The actualy texture functionality. /// <summary> /// Constrctus from parsing command file. xlm elements: /// index, type /// MUST exist before any other texture type-specific elements!! /// </summary> /// <param name="parser"></param> public RTTexture(CommandFileParser parser) { parser.ParserRead(); while (!parser.IsEndElement("texture")) { if (parser.IsElement() && (!parser.IsElement("texture"))) { if (parser.IsElement("index")) { int i = parser.ReadInt(); SetResourceIndex(i); } else if (parser.IsElement("type")) { String type = parser.ReadString(); if (type.Equals("color")) { mTexture = new RTTextureType_Color(parser); } else if (type.Equals("checker")) { mTexture = new RTTextureType_Checker(parser); } else if (type.Equals("noise")) { mTexture = new RTTextureType_Noise(parser); } else if (type.Equals("sine")) { mTexture = new RTTextureType_Sine(parser); } else if (type.Equals("marble")) { mTexture = new RTTextureType_Marble(parser); } else if (type.Equals("ramp")) { mTexture = new RTTextureType_Ramp(parser); } else if (type.Equals("grid")) { mTexture = new RTTextureType_Grid(parser); } else if (type.Equals("bump")) { mTexture = new RTTextureType_Bump(parser); } else { parser.ParserError("Texture: unknown type"); } } else { parser.ParserError("Texture"); } } else { parser.ParserRead(); } } }
static public void ParseMeshForTriangles(CommandFileParser parser, ContentManager meshLoader, SceneDatabase sceneDatabase) { String meshFileName = null; int material = 0; // has xform? bool hasTransform = false; Matrix xform = Matrix.Identity; Matrix invT = Matrix.Identity; #region Parse the command file parser.ParserRead(); while (!parser.IsEndElement("mesh")) { if (parser.IsElement() && (!parser.IsElement("mesh"))) { if (parser.IsElement("filename")) { meshFileName = parser.ReadString(); } else if (parser.IsElement("xform")) { hasTransform = true; xform = ParseTransform(parser); } else if (parser.IsElement("material")) { material = parser.ReadInt(); } else { parser.ParserError("mesh"); } } else { parser.ParserRead(); } } #endregion if (null == meshFileName) { parser.ParserError("No Mesh filename!"); return; } if (hasTransform) { invT = Matrix.Transpose(Matrix.Invert(xform)); } Model model = meshLoader.Load <Model>(meshFileName); Byte[] localVertexBuffer = null; Int32[] localIndexBuffer = null; Vector3[] vertexPosition = null; Vector3[] normalAtVertex = null; Vector2[] uvAtVertex = null; bool hasPosition = false; bool hasNormal = false; bool hasUV = false; foreach (ModelMesh mesh in model.Meshes) { foreach (ModelMeshPart part in mesh.MeshParts) { int numIndices = part.IndexBuffer.IndexCount; // total number of localIndexBuffer in the buffer int numVertices = part.VertexBuffer.VertexCount; // total number of vertices in the buffer #region Only need to load/translate these buffers once! // *** REALLY? *** if (null == localIndexBuffer) { vertexPosition = new Vector3[numVertices]; normalAtVertex = new Vector3[numVertices]; uvAtVertex = new Vector2[numVertices]; localIndexBuffer = LoadIndexBuffer(part); int numBytes = numVertices * part.VertexBuffer.VertexDeclaration.VertexStride; localVertexBuffer = new Byte[numBytes]; part.VertexBuffer.GetData <Byte>(localVertexBuffer); VertexElement[] vertexElements = part.VertexBuffer.VertexDeclaration.GetVertexElements(); int bufferOffset = 0; #region parse each vertex // now get all the vertices for (int vertCount = 0; vertCount < numVertices; vertCount++) { // parse through the elements bufferOffset = vertCount * part.VertexBuffer.VertexDeclaration.VertexStride; hasUV = false; // do this for each vertex for (int e = 0; e < vertexElements.Length; e++) { switch (vertexElements[e].VertexElementUsage) { case VertexElementUsage.Position: hasPosition = true; // Vertex position int vertexByteOffset = bufferOffset + vertexElements[e].Offset; vertexPosition[vertCount].X = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); vertexByteOffset += 4; vertexPosition[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); vertexByteOffset += 4; vertexPosition[vertCount].Z = BitConverter.ToSingle(localVertexBuffer, vertexByteOffset); break; case VertexElementUsage.Normal: hasNormal = true; int normalByteOffset = bufferOffset + vertexElements[e].Offset; normalAtVertex[vertCount].X = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); normalByteOffset += 4; normalAtVertex[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); normalByteOffset += 4; normalAtVertex[vertCount].Z = BitConverter.ToSingle(localVertexBuffer, normalByteOffset); break; case VertexElementUsage.TextureCoordinate: if (!hasUV) { // if more than one defined, will only use the first one hasUV = true; int uvByteOffset = bufferOffset + vertexElements[e].Offset; uvAtVertex[vertCount].X = BitConverter.ToSingle(localVertexBuffer, uvByteOffset); uvByteOffset += 4; uvAtVertex[vertCount].Y = BitConverter.ToSingle(localVertexBuffer, uvByteOffset); } break; // ignore all other cases } // the switch on usage for parsing } // for of vertexElements } // for each vertex #endregion #region compute the transform for each vertex // now do the transform if (hasTransform) { for (int v = 0; v < numVertices; v++) { vertexPosition[v] = Vector3.Transform(vertexPosition[v], xform); } if (hasNormal) { for (int v = 0; v < numVertices; v++) { normalAtVertex[v] = Vector3.Transform(normalAtVertex[v], invT); normalAtVertex[v] = Vector3.Normalize(normalAtVertex[v]); } } } #endregion } #endregion // now start working on this particular part ... int startIndex = part.StartIndex; int vertexOffset = part.VertexOffset; // start from part.StartIndex int numTriangles = part.PrimitiveCount; #region create the triangles // now all vertice are stored. // let's create the Triangles for (int nthT = 0; nthT < numTriangles; nthT++) { Vector3[] vertices = new Vector3[3]; Vector2[] uv = new Vector2[3]; Vector3[] normals = null; if (hasNormal) { normals = new Vector3[3]; } #region copy vertex info int indexOffset = startIndex + (nthT * 3); for (int i = 0; i < 3; i++) { int index = vertexOffset + localIndexBuffer[indexOffset + i]; vertices[i] = vertexPosition[index]; uv[i] = uvAtVertex[index]; if (hasNormal) { normals[i] = normalAtVertex[index]; } } #endregion // now create the new triangle // watch out for bad triangles!! if (hasPosition) { if (!hasNormal) { normalAtVertex = null; } Vector3 aVec = vertices[1] - vertices[0]; if (aVec.LengthSquared() > float.Epsilon) { Vector3 bVec = vertices[2] - vertices[0]; if (bVec.LengthSquared() > float.Epsilon) { RTTriangle t = new RTTriangle(vertices, normals, uv, material); sceneDatabase.AddGeom(t); } } } } #endregion } } }
public RTMaterial(CommandFileParser parser) { InitializeMaterial(); parser.ParserRead(); while (!parser.IsEndElement("material")) { if (parser.IsElement() && (!parser.IsElement("material"))) { if (parser.IsElement("index")) { int i = parser.ReadInt(); SetResourceIndex(i); } else if (parser.IsElement("ka")) { mKa.SetAttribute(parser.ReadVector3()); } else if (parser.IsElement("ks")) { mKs.SetAttribute(parser.ReadVector3()); } else if (parser.IsElement("kd")) { mKd.SetAttribute(parser.ReadVector3()); } else if (parser.IsElement("n")) { mN = parser.ReadFloat(); } else if (parser.IsElement("textureindex")) // backward compatibility { mKd.SetTextureIndex(parser.ReadInt()); } else if (parser.IsElement("kaIndex")) { mKa.SetTextureIndex(parser.ReadInt()); } else if (parser.IsElement("kdIndex")) { mKd.SetTextureIndex(parser.ReadInt()); } else if (parser.IsElement("ksIndex")) { mKs.SetTextureIndex(parser.ReadInt()); } else if (parser.IsElement("tIndex")) { mTransparency.SetTextureIndex(parser.ReadInt()); } else if (parser.IsElement("rIndex")) { mReflectivity.SetTextureIndex(parser.ReadInt()); } else if (parser.IsElement("nIndex")) { mNormal.SetTextureIndex(parser.ReadInt()); } else if (parser.IsElement("ptIndex")) { mPosition.SetTextureIndex(parser.ReadInt()); } else if (parser.IsElement("reflectivity")) { mReflectivity.SetAttribute(parser.ReadFloat()); } else if (parser.IsElement("transparency")) { mTransparency.SetAttribute(parser.ReadFloat()); } else if (parser.IsElement("refractiveindex")) { mRefractiveIndex = parser.ReadFloat(); } else { parser.ParserError("Material"); } } else { parser.ParserRead(); } } }
private Vector2 mD02, mD12; // delta UV between vertex-0 and 2; and vertex-1 and 2 /// <summary> /// Constructs from parsing file and then intialize for intersection computation. /// </summary> /// <param name="parser"></param> public RTTriangle(CommandFileParser parser) { mType = RTGeometryType.Triangle; // do we have a transform? bool hasTransform = false; Matrix xform = Matrix.Identity; mVertices = new Vector3[3]; mVertexUV = new Vector2[3]; mMaterialIndex = 0; int count = 0; parser.ParserRead(); while (!parser.IsEndElement("triangle")) { if (parser.IsElement() && (!parser.IsElement("triangle"))) { if (parser.IsElement("vertices")) { mVertices[count] = parser.ReadVector3(); } else if (parser.IsElement("uv")) { mVertexUV[count] = parser.ReadVector2(); count++; } else if (parser.IsElement("xform")) { hasTransform = true; xform = ParseTransform(parser); } else if (parser.IsElement("material")) { mMaterialIndex = parser.ReadInt(); } else { parser.ParserError("Triangle"); } } else { parser.ParserRead(); } } if (count != 3) { parser.ParserError("Triangle: vertex indexPtr = " + count); } else { if (hasTransform) { mVertices[0] = Vector3.Transform(mVertices[0], xform); mVertices[1] = Vector3.Transform(mVertices[1], xform); mVertices[2] = Vector3.Transform(mVertices[2], xform); } InitializeTriangle(); } }