public AttachmentPoint(AttachmentPoint other) { this.name = other.name; this.parentBone = other.parentBone; this.orientation = other.orientation; this.position = other.position; }
public AttachmentPoint(string name, string parentBone, Quaternion orientation, Vector3 position) { this.name = name; this.parentBone = parentBone; this.orientation = orientation; this.position = position; }
/// <summary> /// Constructor. /// </summary> /// <param name="name">Name of this plane.</param> public MovablePlane(string name) { this.name = name; lastTranslate = Vector3.Zero; lastRotate = Quaternion.Identity; isDirty = true; }
public AddMarkerAtCameraCommand(WorldEditor app, IWorldContainer parent, string name) { this.app = app; this.parent = parent; this.name = name; this.pos = app.CameraPosition; this.orient = new Quaternion(app.CameraOrientation.w, app.CameraOrientation.x, app.CameraOrientation.y, app.CameraOrientation.z); }
public AddWaypointParticleEffectCommand(Waypoint parent, WorldEditor app, string particleEffectName, float positionScale, float velocityScale, Quaternion orientation) { this.app = app; this.parent = parent; this.particleEffectName = particleEffectName; this.positionScale = positionScale; this.velocityScale = velocityScale; this.orientation = parent.Orientation; }
public AddObjectParticleEffectCommand(StaticObject parent, WorldEditor app, string particleEffectName, float positionScale, float velocityScale, string attachmentPointName, Quaternion orientation) { this.app = app; this.parent = parent; this.particleEffectName = particleEffectName; this.positionScale = positionScale; this.velocityScale = velocityScale; this.attachmentPointName = attachmentPointName; this.orientation = orientation; }
/// <summary> /// Creates a new Entity (should not occur on it's own) /// </summary> public Entity() { uuid = new libsecondlife.LLUUID(); localid = 0; m_pos = new LLVector3(); velocity = new LLVector3(); rotation = new Quaternion(); m_name = "(basic entity)"; children = new List<Entity>(); }
public ParticleEffect(IWorldObject parent, WorldEditor app, string particleEffectName, float particleScale, float velocityScale, Quaternion orientation) { this.parent = parent; this.app = app; this.orientation = orientation; this.particleEffectName = particleEffectName; this.particleScale = particleScale; this.velocityScale = velocityScale; }
public AddParticleEffectMessage() { this.MessageType = WorldMessageType.AddParticleEffect; orientation = Quaternion.Identity; velocityMultiplier = 1.0f; particleSizeMultiplier = 1.0f; particleBooleans = 0; color = null; }
protected override void ParseMessage(IncomingMessage inMessage) { orientation = inMessage.ReadQuaternion(); }
protected override void ParseMessage(IncomingMessage inMessage) { base.ParseMessage(inMessage); name = inMessage.ReadString(); location = inMessage.ReadIntVector(); orientation = inMessage.ReadQuaternion(); scale = inMessage.ReadVector(); objectType = (ObjectNodeType)inMessage.ReadInt32(); followTerrain = inMessage.ReadBool(); try { direction = inMessage.ReadVector(); lastInterp = inMessage.ReadTimestamp(); } catch (System.IO.EndOfStreamException) { // ignore this - it means we got an old style response } }
protected override void ParseMessage(IncomingMessage inMessage) { base.ParseMessage(inMessage); lightType = (LightNodeType)inMessage.ReadInt32(); name = inMessage.ReadString(); diffuse = inMessage.ReadColor(); specular = inMessage.ReadColor(); attenuationRange = inMessage.ReadSingle(); attenuationConstant = inMessage.ReadSingle(); attenuationLinear = inMessage.ReadSingle(); attenuationQuadratic = inMessage.ReadSingle(); switch (lightType) { case LightNodeType.Point: location = inMessage.ReadIntVector(); break; case LightNodeType.Directional: orientation = inMessage.ReadQuaternion(); break; case LightNodeType.Spotlight: location = inMessage.ReadIntVector(); orientation = inMessage.ReadQuaternion(); spotlightInnerAngle = inMessage.ReadSingle(); spotlightOuterAngle = inMessage.ReadSingle(); spotlightFalloff = inMessage.ReadSingle(); break; default: throw new Exception("Invalid light node type: " + lightType); } }
protected void GetCompositeTransform(ref Quaternion orientation, ref Vector3 translation, Bone bone, Animation anim, int keyFrameIndex) { if (bone == null) return; Quaternion tmpOrient = Quaternion.Identity; Vector3 tmpTranslate = Vector3.Zero; GetCompositeTransform(ref tmpOrient, ref tmpTranslate, (Bone)bone.Parent, anim, keyFrameIndex); AnimationTrack track = GetBoneTrack(anim, bone.Handle); KeyFrame keyFrame = track.KeyFrames[keyFrameIndex]; orientation = tmpOrient * bone.Orientation * keyFrame.Rotation; translation = tmpTranslate + bone.Position + keyFrame.Translate; }
/// <summary> /// Creates this shader as an OGRE material. /// </summary> /// <remarks> /// Creates a new material based on this shaders settings and registers it with the /// SceneManager passed in. /// Material name is in the format of: shader#lightmap. /// </remarks> /// <param name="sm">SceneManager to register the material with.</param> /// <param name="lightmapNumber">Lightmap number</param> public Material CreateAsMaterial(SceneManager sm, int lightmapNumber) { string materialName = String.Format("{0}#{1}", name, lightmapNumber); Material material = sm.CreateMaterial(materialName); LogManager.Instance.Write("Using Q3 shader {0}", name); for(int p = 0; p < pass.Count; ++p) { TextureUnitState t; // Create basic texture t = LoadMaterialTextures(p, lightmapNumber, material); // Blending if(p == 0) { // scene blend material.SetSceneBlending(pass[p].blendSrc, pass[p].blendDest); if(material.IsTransparent && (pass[p].blendSrc != SceneBlendFactor.SourceAlpha)) material.DepthWrite = false; t.SetColorOperation(LayerBlendOperation.Replace); } else { if(pass[p].customBlend) { // Fallback for now t.SetColorOperation(LayerBlendOperation.Modulate); } else { t.SetColorOperation(pass[p].blend); } } // Tex coords if(pass[p].texGen == ShaderTextureGen.Base) t.TextureCoordSet = 0; else if(pass[p].texGen == ShaderTextureGen.Lightmap) t.TextureCoordSet = 1; else if(pass[p].texGen == ShaderTextureGen.Environment) t.SetEnvironmentMap(true, EnvironmentMap.Planar); // Tex mod // Scale t.SetTextureScaleU(pass[p].tcModScale[0]); t.SetTextureScaleV(pass[p].tcModScale[1]); CreateProceduralTextureMods(p, t); // Address mode t.TextureAddressing = pass[p].addressMode; // Alpha mode t.SetAlphaRejectSettings(pass[p].alphaFunc, pass[p].alphaVal); } // Do farbox (create new material) // Do skydome (use this material) if(skyDome) { float halfAngle = 0.5f * (0.5f * (4.0f * (float) Math.Atan(1.0f))); float sin = (float) Math.Sin(halfAngle); // Quake3 is always aligned with Z upwards Quaternion q = new Quaternion( (float) Math.Cos(halfAngle), sin * Vector3.UnitX.x, sin * Vector3.UnitY.y, sin * Vector3.UnitX.z ); // Also draw last, and make close to camera (far clip plane is shorter) sm.SetSkyDome(true, materialName, 20 - (cloudHeight / 256 * 18), 12, 2000, false, q); } material.CullingMode = Axiom.Graphics.CullingMode.None; material.ManualCullMode = cullMode; material.Lighting = false; material.Load(); return material; }
/// <summary> /// Gets the shortest arc quaternion to rotate this vector to the destination vector. /// </summary> /// <remarks> /// Don't call this if you think the dest vector can be close to the inverse /// of this vector, since then ANY axis of rotation is ok. /// </remarks> public Quaternion GetRotationTo(Vector3 destination) { // Based on Stan Melax's article in Game Programming Gems Quaternion q = new Quaternion(); Vector3 v0 = new Vector3(this.x, this.y, this.z); Vector3 v1 = destination; // normalize both vectors v0.Normalize(); v1.Normalize(); // get the cross product of the vectors Vector3 c = v0.Cross(v1); // If the cross product approaches zero, we get unstable because ANY axis will do // when v0 == -v1 float d = v0.Dot(v1); // If dot == 1, vectors are the same if (d >= 1.0f) { return Quaternion.Identity; } float s = MathUtil.Sqrt( (1+d) * 2 ); float inverse = 1 / s; q.x = c.x * inverse; q.y = c.y * inverse; q.z = c.z * inverse; q.w = s * 0.5f; return q; }
public QuaternionValue(Quaternion val): base((object)val) { }
/// <summary> /// Reads and returns a Quaternion. /// </summary> /// <returns></returns> protected Quaternion ReadQuat(BinaryMemoryReader reader) { Quaternion quat = new Quaternion(); quat.x = reader.ReadSingle(); quat.y = reader.ReadSingle(); quat.z = reader.ReadSingle(); quat.w = reader.ReadSingle(); return quat; }
private SceneNode NewSceneObject(string meshName, Vector3 position, Vector3 scale, Quaternion orientation) { SceneNode node = UnscaledSceneObject(meshName, position); node.ScaleFactor = scale; node.Orientation = orientation; return node; }
protected void UpdateOrientation() { Quaternion azimuthRotation = Quaternion.FromAngleAxis(MathUtil.DegreesToRadians(azimuth), Vector3.UnitY); Quaternion zenithRotation = Quaternion.FromAngleAxis(MathUtil.DegreesToRadians(-zenith), Vector3.UnitX); Matrix3 lightMatrix = (azimuthRotation * zenithRotation).ToRotationMatrix(); // Compute "position" of light (actually just reverse direction) Vector3 relativeLightPos = lightMatrix * Vector3.UnitZ; relativeLightPos.Normalize(); this.lightDirection = -relativeLightPos; Quaternion displayZenithRotation = Quaternion.FromAngleAxis(MathUtil.DegreesToRadians(-Zenith + 90), Vector3.UnitX); this.orientation = (azimuthRotation * displayZenithRotation); if (inScene) { this.displayObject.SetOrientation(orientation); } }
/// <summary> /// Generates billboard corners. /// </summary> /// <param name="camera"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="billboard"></param> /// <remarks>Billboard param only required for type OrientedSelf</remarks> protected virtual void GenerateBillboardAxes(ref Vector3 x, ref Vector3 y, Billboard bb) { // If we're using accurate facing, recalculate camera direction per BB if (accurateFacing && (billboardType == BillboardType.Point || billboardType == BillboardType.OrientedCommon || billboardType == BillboardType.OrientedSelf)) { // cam -> bb direction camDir = bb.Position - camPos; camDir.Normalize(); } switch (billboardType) { case BillboardType.Point: if (accurateFacing) { // Point billboards will have 'up' based on but not equal to cameras y = camQ * Vector3.UnitY; x = camDir.Cross(y); x.Normalize(); y = x.Cross(camDir); // both normalised already } else { // Get camera axes for X and Y (depth is irrelevant) x = camQ * Vector3.UnitX; y = camQ * Vector3.UnitY; } break; case BillboardType.OrientedCommon: // Y-axis is common direction // X-axis is cross with camera direction y = commonDirection; x = camDir.Cross(y); x.Normalize(); break; case BillboardType.OrientedSelf: // Y-axis is direction // X-axis is cross with camera direction // Scale direction first y = bb.Direction; x = camDir.Cross(y); x.Normalize(); break; case BillboardType.PerpendicularCommon: // X-axis is up-vector cross common direction // Y-axis is common direction cross X-axis x = commonUpVector.Cross(commonDirection); y = commonDirection.Cross(x); break; case BillboardType.PerpendicularSelf: // X-axis is up-vector cross own direction // Y-axis is own direction cross X-axis x = commonUpVector.Cross(bb.Direction); x.Normalize(); y = bb.Direction.Cross(x); // both should be normalised break; } #if NOT // Default behavior is that billboards are in local node space // so orientation of camera (in world space) must be reverse-transformed // into node space to generate the axes Quaternion invTransform = parentNode.DerivedOrientation.Inverse(); Quaternion camQ = Quaternion.Zero; switch (billboardType) { case BillboardType.Point: // Get camera world axes for X and Y (depth is irrelevant) camQ = camera.DerivedOrientation; // Convert into billboard local space camQ = invTransform * camQ; x = camQ * Vector3.UnitX; y = camQ * Vector3.UnitY; break; case BillboardType.OrientedCommon: // Y-axis is common direction // X-axis is cross with camera direction y = commonDirection; y.Normalize(); // Convert into billboard local space camQ = invTransform * camQ; x = camQ * camera.DerivedDirection.Cross(y); x.Normalize(); break; case BillboardType.OrientedSelf: // Y-axis is direction // X-axis is cross with camera direction y = billboard.Direction; // Convert into billboard local space camQ = invTransform * camQ; x = camQ * camera.DerivedDirection.Cross(y); x.Normalize(); break; case BillboardType.PerpendicularCommon: // X-axis is common direction cross common up vector // Y-axis is coplanar with common direction and common up vector x = commonDirection.Cross(commonUpVector); x.Normalize(); y = x.Cross(commonDirection); y.Normalize(); break; case BillboardType.PerpendicularSelf: // X-axis is direction cross common up vector // Y-axis is coplanar with direction and common up vector x = billboard.Direction.Cross(commonUpVector); x.Normalize(); y = x.Cross(billboard.Direction); y.Normalize(); break; } #endif }
public ParticleEffect(IWorldObject parent, WorldEditor app, string particleEffectName, float particleScale, float velocityScale, string attachmentPointName, Quaternion orientation) : this(parent, app, particleEffectName, particleScale, velocityScale, orientation) { this.attachmentPointName = attachmentPointName; }
protected override void ParseMessage(IncomingMessage inMessage) { base.ParseMessage(inMessage); slotName = inMessage.ReadString(); effectName = inMessage.ReadString(); orientation = inMessage.ReadQuaternion(); velocityMultiplier = inMessage.ReadSingle(); particleSizeMultiplier = inMessage.ReadSingle(); particleBooleans = inMessage.ReadByte(); if (GetFlag(Flags.HasColor)) color = inMessage.ReadColor(); }
protected XmlElement WriteQuaternion(string elementName, Quaternion rot) { Vector3 axis = new Vector3(); float angle = 0; rot.ToAngleAxis(ref angle, ref axis); XmlElement node = document.CreateElement(elementName); XmlAttribute attr; attr = document.CreateAttribute("angle"); if (angle >= Math.PI && 2 * (float)Math.PI - angle < (float)Math.PI) { angle = 2 * (float)Math.PI - angle; axis = -1 * axis; Debug.Assert(angle < Math.PI); } Debug.Assert(angle < Math.PI + .0001); attr.Value = angle.ToString(); node.Attributes.Append(attr); XmlElement childNode = WriteAxis(axis); node.AppendChild(childNode); return node; }
public void HandleUpdate(AgentUpdatePacket pack) { if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_FLY) != 0) { if (this._physActor.Flying == false) { this.current_anim = Animations.AnimsLLUUID["ANIM_AGENT_FLY"]; this.anim_seq = 1; this.SendAnimPack(); } this._physActor.Flying = true; } else { if (this._physActor.Flying == true) { this.current_anim = Animations.AnimsLLUUID["ANIM_AGENT_STAND"]; this.anim_seq = 1; this.SendAnimPack(); } this._physActor.Flying = false; } if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_AT_POS) != 0) { Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z); if (((movementflag & 1) == 0) || (q != this.bodyRot)) { if (((movementflag & 1) == 0) && (!this._physActor.Flying)) { this.current_anim = Animations.AnimsLLUUID["ANIM_AGENT_WALK"]; this.anim_seq = 1; this.SendAnimPack(); } //we should add a new force to the list // but for now we will deal with velocities NewForce newVelocity = new NewForce(); Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0); Axiom.MathLib.Vector3 direc = q * v3; direc.Normalize(); //work out velocity for sim physics system direc = direc * ((0.03f) * 128f); if (this._physActor.Flying) { direc *= 2; } newVelocity.X = direc.x; newVelocity.Y = direc.y; newVelocity.Z = direc.z; this.forcesList.Add(newVelocity); movementflag = 1; this.bodyRot = q; } } else if ((((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_UP_POS) != 0) && (PhysicsEngineFlying)) { if (((movementflag & 2) == 0) && this._physActor.Flying) { //we should add a new force to the list // but for now we will deal with velocities NewForce newVelocity = new NewForce(); Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(0, 0, 1); Axiom.MathLib.Vector3 direc = v3; direc.Normalize(); //work out velocity for sim physics system direc = direc * ((0.03f) * 128f * 2); newVelocity.X = direc.x; newVelocity.Y = direc.y; newVelocity.Z = direc.z; this.forcesList.Add(newVelocity); movementflag = 2; } } else if ((((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && (PhysicsEngineFlying)) { if (((movementflag & 4) == 0) && this._physActor.Flying) { //we should add a new force to the list // but for now we will deal with velocities NewForce newVelocity = new NewForce(); Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(0, 0, -1); //Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z); Axiom.MathLib.Vector3 direc = v3; direc.Normalize(); //work out velocity for sim physics system direc = direc * ((0.03f) * 128f * 2); newVelocity.X = direc.x; newVelocity.Y = direc.y; newVelocity.Z = direc.z; this.forcesList.Add(newVelocity); movementflag = 4; } } else if (((uint)pack.AgentData.ControlFlags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_AT_NEG) != 0) { Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(pack.AgentData.BodyRotation.W, pack.AgentData.BodyRotation.X, pack.AgentData.BodyRotation.Y, pack.AgentData.BodyRotation.Z); if (((movementflag & 8) == 0) || (q != this.bodyRot)) { //we should add a new force to the list // but for now we will deal with velocities NewForce newVelocity = new NewForce(); Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(-1, 0, 0); Axiom.MathLib.Vector3 direc = q * v3; direc.Normalize(); //work out velocity for sim physics system direc = direc * ((0.03f) * 128f); if (this._physActor.Flying) { direc *= 2; } newVelocity.X = direc.x; newVelocity.Y = direc.y; newVelocity.Z = direc.z; this.forcesList.Add(newVelocity); movementflag = 8; this.bodyRot = q; } } else { if (movementflag == 16) { movementflag = 0; } if ((movementflag) != 0) { NewForce newVelocity = new NewForce(); newVelocity.X = 0; newVelocity.Y = 0; newVelocity.Z = 0; this.forcesList.Add(newVelocity); movementflag = 0; // We're standing still, so make it show! if (this._physActor.Flying == false) { this.current_anim = Animations.AnimsLLUUID["ANIM_AGENT_STAND"]; this.anim_seq = 1; this.SendAnimPack(); } this.movementflag = 16; } } }
protected XmlElement WriteRotation(Quaternion rot) { return WriteQuaternion("rotation", rot); }
/// <summary> /// Updates this lights position. /// </summary> public virtual void Update() { if(parentNode != null) { if(!localTransformDirty && parentNode.DerivedOrientation == lastParentOrientation && parentNode.DerivedPosition == lastParentPosition) { } else { // we are out of date with the scene node we are attached to lastParentOrientation = parentNode.DerivedOrientation; lastParentPosition = parentNode.DerivedPosition; derivedDirection = lastParentOrientation * direction; derivedPosition = (lastParentOrientation * position) + lastParentPosition; } } else { derivedPosition = position; derivedDirection = direction; } localTransformDirty = false; }
/// <summary> /// Gets the shortest arc quaternion to rotate this vector /// to the destination vector. /// </summary> /// <remarks> /// If you call this with a dest vector that is close to the inverse /// of this vector, we will rotate 180 degrees around the 'fallbackAxis' /// (if specified, or a generated axis if not) since in this case /// ANY axis of rotation is valid. /// </remarks> public Quaternion GetRotationTo(Vector3 destination, Vector3 fallbackAxis) { // Based on Stan Melax's article in Game Programming Gems Quaternion q = new Quaternion(); Vector3 v0 = new Vector3(this.x, this.y, this.z); Vector3 v1 = destination; // normalize both vectors v0.Normalize(); v1.Normalize(); // get the cross product of the vectors Vector3 c = v0.Cross(v1); // If the cross product approaches zero, we get unstable because ANY axis will do // when v0 == -v1 float d = v0.Dot(v1); // If dot == 1, vectors are the same if (d >= 1.0f) { return Quaternion.Identity; } if (d < (1e-6f - 1.0f)) { if (fallbackAxis != Vector3.Zero) // rotate 180 degrees about the fallback axis q = Quaternion.FromAngleAxis((float)Math.PI, fallbackAxis); else { // Generate an axis Vector3 axis = Vector3.UnitX.Cross(this); if (axis.IsZero) // pick another if colinear axis = Vector3.UnitY.Cross(this); axis.Normalize(); q = Quaternion.FromAngleAxis((float)Math.PI, axis); } } else { float s = MathUtil.Sqrt( (1+d) * 2 ); float inverse = 1 / s; q.x = c.x * inverse; q.y = c.y * inverse; q.z = c.z * inverse; q.w = s * 0.5f; q.Normalize(); } return q; }
protected void FromXml(XmlReader r, bool loadCollections) { string filename = ""; string baseName = worldFilePath.Substring(0, worldFilePath.LastIndexOf('\\')); bool loadColl = loadCollections; for (int i = 0; i < r.AttributeCount; i++) { r.MoveToAttribute(i); switch (r.Name) { case "Name": name = r.Value; break; } } r.MoveToElement(); while (r.Read()) { // look for the start of an element if (r.NodeType == XmlNodeType.Whitespace) { continue; } if (r.NodeType == XmlNodeType.EndElement) { break; } if (r.NodeType == XmlNodeType.Element) { switch (r.Name) { case "CameraPosition": cameraPosition = XmlHelperClass.ParseVectorAttributes(r); break; case "CameraOrientation": cameraOrientation = XmlHelperClass.ParseQuaternion(r); break; case "Terrain": worldTerrain = new WorldTerrain(app, r); break; case "TerrainDisplay": worldTerrain.DisplayParamsFromXml(r); break; case "Ocean": ocean = new Ocean(this, app, r); break; case "Skybox": skybox = new Skybox(this, app, r); break; case "GlobalFog": fog = new GlobalFog(this, app, r); break; case "GlobalAmbientLight": ambientLight = new GlobalAmbientLight(this, app, app.Scene, r); break; case "GlobalDirectionalLight": directionalLight = new GlobalDirectionalLight(this, app, r); break; case "PathObjectTypes": pathObjectTypes = new PathObjectTypeContainer(app, this, r); break; case "WorldCollection": string collectionName = null; filename = ""; for (int i = 0; i < r.AttributeCount; i++) { r.MoveToAttribute(i); switch (r.Name) { case "Name": collectionName = r.Value; break; case "Filename": filename = r.Value; break; } } string filepath = String.Format("{0}\\{1}", baseName, filename); if (filename != "") { if (filename.EndsWith("~.mwc")) { string autofilepath = String.Format("{0}\\{1}", baseName, filename); string normalfilepath = String.Format("{0}\\{1}", baseName, filename.Remove(filename.LastIndexOf("~"), 1)); if ((File.Exists(autofilepath) && File.Exists(normalfilepath) && (new FileInfo(autofilepath)).LastWriteTime < (new FileInfo(normalfilepath).LastWriteTime)) || (!File.Exists(autofilepath) && File.Exists(normalfilepath))) { filename = filename.Remove(filename.LastIndexOf("~"), 1); filepath = normalfilepath; } else { filepath = autofilepath; } } XmlReader childReader = XmlReader.Create(filepath, app.XMLReaderSettings); WorldObjectCollection collection = new WorldObjectCollection(childReader, collectionName, this, app, baseName, loadColl); collection.Filename = filename; while (collection.Filename.Contains("~")) { collection.Filename = collection.Filename.Remove(collection.Filename.LastIndexOf("~"), 1); } Add(collection); childReader.Close(); } else { XmlReader childReader = XmlReader.Create(String.Format("{0}\\{1}.mwc", baseName, collectionName), app.XMLReaderSettings); WorldObjectCollection collection = new WorldObjectCollection(childReader, collectionName, this, app, baseName, loadColl); collection.Filename = filename; Add(collection); while (collection.Filename.Contains("~")) { collection.Filename = collection.Filename.Remove(collection.Filename.LastIndexOf("~"), 1); } childReader.Close(); } r.MoveToElement(); break; } } } }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="plane"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="curvature"></param> /// <param name="xSegments"></param> /// <param name="ySegments"></param> /// <param name="normals"></param> /// <param name="numberOfTexCoordSets"></param> /// <param name="uTiles"></param> /// <param name="vTiles"></param> /// <param name="upVector"></param> /// <param name="orientation"></param> /// <param name="vertexBufferUsage"></param> /// <param name="indexBufferUsage"></param> /// <param name="vertexShadowBuffer"></param> /// <param name="indexShadowBuffer"></param> /// <returns></returns> public Mesh CreateCurvedIllusionPlane(string name, Plane plane, float width, float height, float curvature, int xSegments, int ySegments, bool normals, int numberOfTexCoordSets, float uTiles, float vTiles, Vector3 upVector, Quaternion orientation, BufferUsage vertexBufferUsage, BufferUsage indexBufferUsage, bool vertexShadowBuffer, bool indexShadowBuffer) { Mesh mesh = CreateManual(name); SubMesh subMesh = mesh.CreateSubMesh(name + "SubMesh"); // set up vertex data, use a single shared buffer mesh.SharedVertexData = new VertexData(); VertexData vertexData = mesh.SharedVertexData; // set up vertex declaration VertexDeclaration vertexDeclaration = vertexData.vertexDeclaration; int currentOffset = 0; // always need positions vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Position); currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3); // optional normals if(normals) { vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float3, VertexElementSemantic.Normal); currentOffset += VertexElement.GetTypeSize(VertexElementType.Float3); } for(ushort i = 0; i < numberOfTexCoordSets; i++) { // assumes 2d texture coordinates vertexDeclaration.AddElement(0, currentOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, i); currentOffset += VertexElement.GetTypeSize(VertexElementType.Float2); } vertexData.vertexCount = (xSegments + 1) * (ySegments + 1); // allocate vertex buffer HardwareVertexBuffer vertexBuffer = HardwareBufferManager.Instance.CreateVertexBuffer(vertexDeclaration.GetVertexSize(0), vertexData.vertexCount, vertexBufferUsage, vertexShadowBuffer); // set up the binding, one source only VertexBufferBinding binding = vertexData.vertexBufferBinding; binding.SetBinding(0, vertexBuffer); // work out the transform required, default orientation of plane is normal along +z, distance 0 Matrix4 xlate, xform, rot; Matrix3 rot3 = Matrix3.Identity; xlate = rot = Matrix4.Identity; // determine axes Vector3 zAxis, yAxis, xAxis; zAxis = plane.Normal; zAxis.Normalize(); yAxis = upVector; yAxis.Normalize(); xAxis = yAxis.Cross(zAxis); if(xAxis.Length == 0) { throw new AxiomException("The up vector for a plane cannot be parallel to the planes normal."); } rot3.FromAxes(xAxis, yAxis, zAxis); rot = rot3; // set up standard xform from origin xlate.Translation = plane.Normal * -plane.D; // concatenate xform = xlate * rot; // generate vertex data, imagine a large sphere with the camera located near the top, // the lower the curvature, the larger the sphere. use the angle from the viewer to the // points on the plane float cameraPosition; // camera position relative to the sphere center // derive sphere radius (unused) //float sphereDistance; // distance from the camera to the sphere along box vertex vector float sphereRadius; // actual values irrelevant, it's the relation between the sphere's radius and the camera's position which is important float SPHERE_RADIUS = 100; float CAMERA_DISTANCE = 5; sphereRadius = SPHERE_RADIUS - curvature; cameraPosition = sphereRadius - CAMERA_DISTANCE; // lock the whole buffer float xSpace = width / xSegments; float ySpace = height / ySegments; float halfWidth = width / 2; float halfHeight = height / 2; Vector3 vec = Vector3.Zero; Vector3 norm = Vector3.Zero; Vector3 min = Vector3.Zero; Vector3 max = Vector3.Zero; float maxSquaredLength = 0; bool firstTime = true; // generate vertex data GenerateCurvedIllusionPlaneVertexData(vertexBuffer, ySegments, xSegments, xSpace, halfWidth, ySpace, halfHeight, xform, firstTime, normals, orientation, cameraPosition, sphereRadius, uTiles, vTiles, numberOfTexCoordSets, ref min, ref max, ref maxSquaredLength); // generate face list subMesh.useSharedVertices = true; Tesselate2DMesh(subMesh, xSegments + 1, ySegments + 1, false, indexBufferUsage, indexShadowBuffer); // generate bounds for the mesh mesh.BoundingBox = new AxisAlignedBox(min, max); mesh.BoundingSphereRadius = MathUtil.Sqrt(maxSquaredLength); mesh.Load(); mesh.Touch(); return mesh; }
/// <summary> /// Reads and returns a Quaternion. /// </summary> protected void WriteQuat(BinaryWriter writer, Quaternion quat) { writer.Write(quat.x); writer.Write(quat.y); writer.Write(quat.z); writer.Write(quat.w); }
private static void GenerateCurvedIllusionPlaneVertexData(HardwareVertexBuffer vertexBuffer, int ySegments, int xSegments, float xSpace, float halfWidth, float ySpace, float halfHeight, Matrix4 xform, bool firstTime, bool normals, Quaternion orientation, float cameraPosition, float sphereRadius, float uTiles, float vTiles, int numberOfTexCoordSets, ref Vector3 min, ref Vector3 max, ref float maxSquaredLength) { Vector3 vec; Vector3 norm; float sphereDistance; unsafe { // lock the vertex buffer IntPtr data = vertexBuffer.Lock(BufferLocking.Discard); float* pData = (float*)data.ToPointer(); for (int y = 0; y < ySegments + 1; ++y) { for (int x = 0; x < xSegments + 1; ++x) { // centered on origin vec.x = (x * xSpace) - halfWidth; vec.y = (y * ySpace) - halfHeight; vec.z = 0.0f; // transform by orientation and distance vec = xform * vec; // assign to geometry *pData++ = vec.x; *pData++ = vec.y; *pData++ = vec.z; // build bounds as we go if (firstTime) { min = vec; max = vec; maxSquaredLength = vec.LengthSquared; firstTime = false; } else { min.Floor(vec); max.Ceil(vec); maxSquaredLength = MathUtil.Max(maxSquaredLength, vec.LengthSquared); } if (normals) { norm = Vector3.UnitZ; norm = orientation * norm; *pData++ = vec.x; *pData++ = vec.y; *pData++ = vec.z; } // generate texture coordinates, normalize position, modify by orientation to return +y up vec = orientation.Inverse() * vec; vec.Normalize(); // find distance to sphere sphereDistance = MathUtil.Sqrt(cameraPosition * cameraPosition * (vec.y * vec.y - 1.0f) + sphereRadius * sphereRadius) - cameraPosition * vec.y; vec.x *= sphereDistance; vec.z *= sphereDistance; // use x and y on sphere as texture coordinates, tiled float s = vec.x * (0.01f * uTiles); float t = vec.z * (0.01f * vTiles); for (int i = 0; i < numberOfTexCoordSets; i++) { *pData++ = s; *pData++ = (1 - t); } } // x } // y // unlock the buffer vertexBuffer.Unlock(); } // unsafe }