Strange duplication of ModelBones across instances of objects using the model - xna

This is the first question I have asked, I'll try and keep this brief and detailed.
Basically, I am trying to create randomized cars made from a selection of models. I have 5 of each model part: Chassis, Engine, Spoiler and Wheels. The randomizer is working, models are loading. However, there is an issue where models are being drawn on other models. Usually there are only small parts of the model being drawn on other parts.
The models are being made in Maya(2013), Exported as .FBX and loaded into XNA. I follow this procedure for exporting: 1. Make Model.
2. Freeze transformation, center pivotpoint and delete history for each part of the model.
3. Combine the mesh and name appropriately.
Example to visualize this. Apparently I can't post images, so here is an Imgur link.
http://imgur.com/a/KHvPU#0
Thanks in advance for your help. This issue happens across more than just this example. I have 5 of each type (wheels, engines, chassis and spoilers), along with separate turbine instances for any models which have them, and other misc. parts. It seems to be totally random from one .FBX file to another... I cant work out if this is a Maya issue, or an XNA issue, or a combination of both :(
Relevant code. This is in a car Class, I have selected the relevant parts.
namespace CGD_RRR_Flipbook
{
//This is a class for the physics, position, color and perhaps race position (i.e. rank) of a car
public class Car : PhysicsObject
{
public string partName;
public int partNumber = 1; //(Initialised for wheel rotation requirements)
public List<string> partList = new List<string>();
//Animation Mesh and Bones Setup
//Chassis
public ModelBone chassis_01 { get; set; }
public ModelBone chassis_02 { get; set; }
public ModelBone chassis_03 { get; set; }
public ModelBone chassis_04 { get; set; }
public ModelBone chassis_05 { get; set; }
//Chassis Turbines
public ModelBone chassis_01_Turbine { get; set; }
public Matrix chassis_01_TurbineTransform { get; set; }
public ModelBone chassis_02_Turbine { get; set; }
public Matrix chassis_02_TurbineTransform { get; set; }
public ModelBone chassis_05_Turbine_Right { get; set; }
public Matrix chassis_05_Turbine_RightTransform { get; set; }
public ModelBone chassis_05_Turbine_Left { get; set; }
public Matrix chassis_05_Turbine_LeftTransform { get; set; }
//Engine
public ModelBone engine01 { get; set; }
public Matrix engine01Transform { get; set; }
public Matrix[] boneTransforms { get; set; }
//Movable Mesh and Bones setup
public int partPosition = 1; //Sets x-position amount
public float wheelRotationValueBase { get; set; }
public float wheelRotationValueUpdate { get; set; }
public float engineRotationValueBase { get; set; }
public float engineRotationValueUpdate { get; set; }
public Car(
ParticleSystem exhaustSmokeParticles,
ParticleSystem exhaustFlameParticles,
ParticleSystem exhaustBoostParticles,
ParticleSystem carDustParticles,
ParticleSystem sandstormParticles,
ParticleSystem explosionParticles,
HUDController _hudController, PlayerIndex _playerIndex, Terrain _terrain, GraphicsDevice _device, Effect _effect, Random randomNumber,
Controls keyBindings, int _player, SoundController _soundcontroller, string fileName = "", ContentManager content = null)
: base(fileName, content)
{
//Load Model
chassis_01_Turbine = model.Bones["Chassis_01_Turbine"];
chassis_01_TurbineTransform = chassis_01_Turbine.Transform;
chassis_02_Turbine = model.Bones["Chassis_02_Turbine"];
chassis_02_TurbineTransform = chassis_02_Turbine.Transform;
chassis_05_Turbine_Left = model.Bones["Chassis_05_Turbine_Left"];
chassis_05_Turbine_LeftTransform = chassis_05_Turbine_Left.Transform;
chassis_05_Turbine_Right = model.Bones["Chassis_05_Turbine_Right"];
chassis_05_Turbine_RightTransform = chassis_05_Turbine_Right.Transform;
chassis_01 = model.Bones["Chassis_01"];
chassis_02 = model.Bones["Chassis_02"];
chassis_03 = model.Bones["Chassis_03"];
chassis_04 = model.Bones["Chassis_04"];
chassis_05 = model.Bones["Chassis_05"];
engine01 = model.Bones["Engine_01"];
engine01Transform = engine01.Transform;
Update Function
public override void update(float dt)
{
//Calls randomiser (once) when player presses key in the generation state
if ((keyState.IsKeyDown(keyBinds.controlsList[player].forward)) && (!oldKeyState.IsKeyDown(keyBinds.controlsList[player].forward))
|| (padState.IsButtonDown(keyBinds.contForward)) && (!oldPadState.IsButtonDown(keyBinds.contForward)))
{
carRandomiser();
}
}
base.update(dt);
}
Draw Function.
public override void draw(Camera cam)
{
model.Root.Transform = worldMat; //sets model root transform to world
float wheelRotationValue = (wheelRotationValueBase + wheelRotationValueUpdate);
float engineRotationValue = (wheelRotationValueBase + wheelRotationValueUpdate);
//Chassis Engine Rotation Animation
Matrix engineRotation = Matrix.CreateRotationZ(engineRotationValue * 20);
chassis_01_Turbine.Transform = engineRotation * chassis_01_TurbineTransform;
chassis_02_Turbine.Transform = engineRotation * chassis_02_TurbineTransform;
chassis_05_Turbine_Left.Transform = engineRotation * chassis_05_Turbine_LeftTransform;
chassis_05_Turbine_Right.Transform = engineRotation * chassis_05_Turbine_RightTransform;
//Wheel Rotation Animation
//Matrix wheelRotation = Matrix.CreateRotationX(wheelRotationValue); //Create rotation Matrix
boneTransforms = new Matrix[model.Bones.Count]; //Creates array for holding modelBone transform matricies for use in draw method.
model.CopyAbsoluteBoneTransformsTo(boneTransforms); //Allocate trasform matricies
if (model != null)
{
foreach (ModelMesh mesh in model.Meshes)
{
//Draw parts assigned to car from partList.
foreach (string part in partList)
{
//Allows only the part in the list to be drawn, as opposed to all the possible parts.
if (mesh.Name == part)
{
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
effect.World = boneTransforms[mesh.ParentBone.Index];// + worldMat;
effect.Projection = cam.projMat;
effect.View = cam.viewMat;
mesh.Draw();
}
}
}
}
}
}
The randomiser function.
//Car Randomiser Function. Looks for model bones allocated in FBX file.
public void carRandomiser()
{
//Delete contents of list.
partList.Clear();
//Spawn car engine
partNumber = rand.Next(0) + 1;
partName = ("Engine_0") + partNumber.ToString();
partList.Add(partName);
//Spawn car chassis
partNumber = rand.Next(5) + 1;
partName = ("Chassis_0") +partNumber.ToString();
partList.Add(partName);
//Spawn engine turbine for selected engine.
if (partName == ("Chassis_01"))
{
partList.Add("Chassis_01_Turbine");
}
if (partName == ("Chassis_02"))
{
partList.Add("Chassis_02_Turbine");
}
if (partName == ("Chassis_05"))
{
partList.Add("Chassis_05_Turbine_Left");
partList.Add("Chassis_05_Turbine_Right");
}
}
}
}

Related

How to bind list of another list to telerik grid in mvc

I really got stuck here.
How do I bind a list of another list data to Telerik grid in MVC?
Example:
public class GetTripDetailsResponse
{
public DateTime PersonalDriveDate { set; get; }
public List<AllDrivesInfo> AllDrives { set; get; }
}
public class AllDrivesInfo
{
public int TripId { set; get; }
public string Time { set; get; }
public string Where { set; get; }
public decimal Miles { set; get; }
public decimal Value { set; get; }
public string Purpose { set; get; }
}
Now how to bind it to Telerik grid? How to bind to columns? How to display data?
Please use below code to bind the list from another list.
public ActionResult GetDrivesInfo()
{
List<AllDrivesInfo> AllDrives = null;
var objDrive = new AllDrivesInfo { TripId = 1, Time = "Time", Where = "where", Miles = 10, Value = 20, Purpose = "my purpose" }; //Get Code here
foreach (AllDrivesInfo d in objDrive)
{
AllDrives.Add(new AllDrivesInfo { TripId = d.TripId, Time = d.Time, Where = d.Where, Miles = d.Miles, Value = d.Value, Purpose = d.Purpose });
}
}
Bind Telerik GridView
You need to return Json result to bind the gridview:
public ActionResult Drives_Get([DataSourceRequest] DataSourceRequest request)
{
//Bind "DrivesList" here
return Json(DrivesModel.DrivesList.ToDataSourceResult(request));
}
Gridview
.Read(read => read.Action("Drives_Get", "Drives"))

Google Chrome HttpPost issue

I'm relatively new to ASP.net mvc, and am experiencing a very strange browser error. The problem is that it's on the customer's pc (which I have yet to get access to).
There seems to be an intermittent problem posting data from his computer, at the moment he has only tried chrome (and I have requested he try different browsers). I haven't been able to replicate the issue and have tried on two computers, three browsers and three different operating systems (windows 7, windows 8 (via mac parallels) and Osx Mavericks) .
I'll post the model and relevant controller code (hopefully it's not too sloppy coding)
I've clarified the following:
- we are both using the same version of chrome
- we both use the same ISP
- He has AVG running
-the site is hosted on Azure
- there is plenty of database and file memory allocated (only 10% being used)
- very little in my code has varied from online examples and again, it all works for me
So my question is really, where else do I look to find the errors:
- is there something in the code that I should consider adding or changing
- could it be a cookie issue on his version of chrome?
- is there a firewall issue somewhere?
model
public class KitchenItem:Post
{
public virtual ICollection<Image> Images { get; set; }
//Optional Project Variables
public bool Project { get; set; }
public string ProjectName { get; set; }
public string Customer { get; set; }
public DateTime? projectStart { get; set; }
public DateTime? projectEnd { get; set; }
}
}
inherited model:
public class Post
{
public int Id
{ get; set; }
[Required]
public string Title
{ get; set; }
[Required]
[Display(Name="Short Description")]
[DataType(DataType.MultilineText )]
public string ShortDescription
{ get; set; }
[Required]
[AllowHtml]
[UIHint("tinymce_full_compressed")]
public string Description
{ get; set; }
[Display(Name = "Meta Keywords")]
[DefaultValue (" ")]
public string Meta
{ get; set; }
public string UrlSlug
{ get; set; }
public bool Published
{ get; set; }
public DateTime? PostedOn
{ get; set; }
public DateTime? Modified
{ get; set; }
public int? CategoryID { get; set; }
public Category Category
{ get; set; }
[NotMapped]
public HttpPostedFileBase uploadedFile { get; set; }
public string mainImagePath { get; set; }
public virtual ICollection<Tag> Tags
{ get; set; }
}
ViewModel:
public class CreateProjectViewModel
{
public KitchenItem KitchenItem { get; set; }
[Display(Name = "Upload Image")]
public HttpPostedFileBase[] ImagesFiles { get; set; }
public Image[] Images { get; set; }
public int CategoryID { get; set; }
public int[] imageDeletes { get; set; }
}
Create Post:
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult Create(CreateProjectViewModel viewModel)
{
KitchenItem model = new KitchenItem();
model = viewModel.KitchenItem;
try
{
/*
*Create ID from total Images to allow for specific folders to be created when file saved, iteration (totalImages)
*Calls for loop for each element of array to ensure that specific titles and tags are associated to correct image
* Add image to model collection to be saved to db
*/
List<Image> imgCollection = new List<Image>();
int totalKitchenItems = unitofWork.KitchenItemRepository.dbSet.Count() + 1;
//update model images
model.Images = handleEditImage(viewModel.ImagesFiles, viewModel.Images, imgCollection, model.Id);
//Log date posted
model.PostedOn = DateTime.Now;
Category cat = new Category();
model.Category = unitofWork.CategoryRepository.GetByID(viewModel.CategoryID);
//create post
unitofWork.KitchenItemRepository.Insert(model);
unitofWork.Save();
return RedirectToAction("Index");
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
validationErrors.Entry.Entity.GetType().FullName,
validationError.PropertyName,
validationError.ErrorMessage);
}
foreach (var eve in dbEx.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
}
PopulateCategoriesDropDownList(0);
return RedirectToAction("Index");
}
}
Handle Image & Add Image Functions:
public ICollection<Image> handleEditImage(HttpPostedFileBase[] imageFiles, Image[] images, ICollection<Image> modelImages, int modelID)
{
/*
*Create ID from total Images to allow for specific folders to be created when file saved, iteration (totalImages)
*Calls for loop for each element of array to ensure that specific titles and tags are associated to correct image
* Add image to model collection to be saved to db
*/
List<Image> imgCollection = new List<Image>();
for (int i = 0; i < 5; i++)
{
Image uploadImage = new Image();
//check to make sure there is an image
if (imageFiles[i] != null)
{
//handle httppostedfilebase conversion to image file and add Url to image model
uploadImage = AddImage(imageFiles[i], images[i], modelID);
//Add img to be updated to model
imgCollection.Add(uploadImage);
}
}
if (modelImages != null)
{
//check for deleted images
foreach (var img in modelImages)
{
//loop through image array to determine whether image is currently assigned to model
for (int i = 0; i < 5; i++)
{
if (images[i].ImageUrl != null)
{
//replace string element modified before passed to view
images[i].ImageUrl = images[i].ImageUrl.Replace("../../", "~/");
}
if (img.ImageUrl == images[i].ImageUrl)
{
imgCollection.Add(img);
}
}
}
}
return imgCollection;
}
public Image AddImage(HttpPostedFileBase imageToSave, Image modelImage, int Id)
{
Image img = new Image();
img = modelImage;
img.ImageUrl = SaveUploadedFile(imageToSave, Id);
unitofWork.ImagesRepository.Insert(img);
return img;
}

Loop Adding Records Throws Exception

Does anyone know what the proper way of adding records using loops?
I have a system that handles Inventory, Currently I need to be able to Mass Create inventory as creating 50-100 identical items with different ID's would be tedious, What I did was create a MassCreate viewmodel that would essentially take a StartID and an EndID and a base Inventory Class and in the controller loop through the difference between those two ID's and create a record
The ViewModel isn't an issue and passes the data just fine:
public class MassCreateInventoryViewModel
{
public Inventory InventoryBase { get; set; }
public int StartID { get; set; }
public int EndID { get; set; }
public IEnumerable<SelectListItem> Products { get; set; }
}
I read somewhere that the db.SaveChanges() should be outside of the loop as it should only be called once:
for (int inventoryID = viewModel.StartID; inventoryID <= viewModel.EndID; inventoryID++)
{
Inventory newInventory = new Inventory
{
InventoryID = inventoryID,
ProductID = viewModel.InventoryBase.ProductID,
DateEdited = DateTime.Now,
EditedByUserID = WebSecurity.CurrentUserId,
CustomProperties = viewModel.InventoryBase.CustomProperties
};
Database.Inventories.Add(newInventory);
if (newInventory.CustomProperties != null && newInventory.CustomProperties.Any())
{
foreach (CustomDataType dt in newInventory.CustomProperties.Select(x => x.DataType).ToList())
{
Database.Entry(dt).State = EntityState.Unchanged;
}
}
}
Database.SaveChanges();
}
But when I try looping, it stores the first record just fine then throws a Collection was modified; enumeration operation may not execute. Exception. When I include the Database.SaveChanges() after the Add method, it throws A The property 'InventoryID' is part of the object's key information and cannot be modified. error.
The InventoryID is the Key in this table but has been set so that I can input my own ID.
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Display(Name = "Inventory ID")]
public new int InventoryID { get; set; }
The Custom Property is split into two models, the first being the base class.
public class CustomProperty
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CustomPropertyID { get; set; }
public int CustomDataTypeID { get; set; }
[ForeignKey("CustomDataTypeID")]
public CustomDataType DataType { get; set; }
public string PropertyValue { get; set; }
}
and the second being the model thats mapped to the database:
[Table("CustomInventoryProperty")]
public class CustomInventoryProperty : CustomProperty
{
public int InventoryID { get; set; }
[ForeignKey("InventoryID")]
public virtual Inventory Inventory { get; set; }
}
Replace your for loop with this:
var dateEdited = DateTime.Now;
for (int inventoryID = viewModel.StartID; inventoryID <= viewModel.EndID; inventoryID++)
{
Inventory newInventory = new Inventory
{
InventoryID = inventoryID,
ProductID = viewModel.InventoryBase.ProductID,
DateEdited = dateEdited,
EditedByUserID = WebSecurity.CurrentUserId
};
if(viewModel.InventoryBase.CustomProperties != null)
{
newInventory.CustomProperties = new List<CustomProperties>();
foreach(var customProperty in viewModel.InventoryBase.CustomProperties)
{
newInventory.CustomProperties.Add(customProperty);
}
}
Database.Inventories.Add(newInventory);
Database.SaveChanges();
}

Casting collection from one db table to add to another db table

Below is a chunk of my ActionMethod. The part I'm struggling with is casting a new variable integers with all IntegerBufferValues from db.IntegerBuffers and then adding them to db.IntegerList.
var integers = new ICollection<Integers>();
const int COUNT = 1000000;
Stopwatch watch = Stopwatch.StartNew();
for (int c = 0; c < COUNT; c++)
{
integers = db.IntegerBuffers.OrderBy(i => i.IntegerBufferValue);
};
watch.Stop();
var integerList = new IntegerList
{
Direction = direction,
Performance = watch.ElapsedMilliseconds,
Integers = integers
};
db.IntegerLists.Add(integerList);
IntegerList
namespace Project.Models
{
public class IntegerList
{
public int IntegerListID { get; set; }
public string Direction { get; set; }
public long Performance { get; set; }
public virtual ICollection<Integer> Integers { get; set; }
}
}
IntegerBuffer
namespace Project.Models
{
public class IntegerBuffer
{
public int IntegerBufferID { get; set; }
public int IntegerBufferValue { get; set; }
}
}
Edit: To show Integer class.
Integer
namespace IntegerSorterApp.Models
{
public class Integer
{
public int IntegerID { get; set; }
public int IntegerValue { get; set; }
public int IntegerListID { get; set; }
public virtual IntegerList IntegerList { get; set; }
}
}
integers is currently a collection of IntegerBuffer objects. Use .Select to project them to just integers:
IEnumerable<int> integers;
// ...
integers = db.IntegerBuffers
.OrderBy(i => i.IntegerBufferValue)
.Select(i => i.IntegerBufferValue);
Or:
integers =
from buffer in db.IntegerBuffers
orderby buffer.IntegerBufferValue
select buffer.IntegerBufferValue;
Then, you assign to the collection, you could do something like this:
var integerList = new IntegerList
{
Direction = direction,
Performance = watch.ElapsedMilliseconds,
Integers = integers.ToList()
};
Update:
Oops, I didn't see that Integer is a class. My answer is to create a list of Int32 objects. The basics still apply: you'll need to use select to project to whatever structure you need. Now I don't understand your data model, but perhaps you want something like this:
// Create your list first so that the list ID is saved
var integerList = new IntegerList
{
Direction = direction,
Performance = watch.ElapsedMilliseconds,
};
db.IntegerLists.Add(integerList);
// Now create your Integer records with the ID of the list
foreach (var buffer in db.IntegerBuffers.OrderBy(b => b.IntegerBufferValue))
{
db.Integers.Add(new Integer
{
IntegerValue = buffer.IntegerBufferValue,
IntegerListID = integerList.IntegerListID
});
}
If this is a one-to-many relationship, which it appears to be, then setting IntegerListID on your Integer record will implicitly add it to the Integers collection of the list.

Saving a List of Objects in Windows Phone 7 XNA

i need to save a List of Objects, The Objects are created from a class i made. what should i do?
i tried the XmlSerializer, and i added the [XmlElement] to the fields i need to be serialized. but it kept giving me "There is an Error in XML Document".
I tried also the DataContractSerializer, and i used the [DataContract] and [DataMember] but it wont save my objects.
both storage classes work for basic elements (int,bool .. etc) but not my objects.
heres my code for saving:
using (IsolatedStorageFile saveGameFile = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream SaveGameStream = new IsolatedStorageFileStream("GemsCollector1.dat", FileMode.OpenOrCreate, saveGameFile))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Card>));
serializer.Serialize(SaveGameStream, Cards);
}
and this one for loading:
using (IsolatedStorageFile saveGameFile = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream saveGameStream = new IsolatedStorageFileStream("GemsCollector1.dat", FileMode.OpenOrCreate, saveGameFile))
{
if (saveGameStream.Length > 0)
{
XmlSerializer serializer = new XmlSerializer(typeof(List<Card>));
Cards = (List<Card>)serializer.Deserialize(saveGameStream);
}
}
my Card Class:
public class Card
{
[XmlElement]
public CardType CardType { get; set; }
[XmlElement]
public CardColor CardColor { get; set; }
[XmlElement]
public int Value { get; set; }
[XmlElement]
public Vector2 Position { get; set; }
[XmlElement]
public PlayerPosition playerPosition { get; set; }
[XmlElement]
public CardStatus Status { get; set; }
public Rectangle BoundingBox
{
get
{
int width = (playerPosition == PlayerPosition.Left || playerPosition == PlayerPosition.Right) ? 150 : 100;
int height = (playerPosition == PlayerPosition.Left || playerPosition == PlayerPosition.Right) ? 100 : 150;
return new Rectangle((int)Position.X, (int)Position.Y, width, height); ;
}
}
[XmlElement]
public bool isUsed;
public Vector2 endPosition = new Vector2(235,200);
public Rectangle ThrowArea = new Rectangle(235, 200, 350, 120);
[XmlElement]
public string cardTextureName;
private string back = "back";
private static bool ReserveDrag;
[XmlElement]
private Vector2 touchFromCenter;
[XmlElement]
private int touchId;
public Card()
{
}
}
can anybody please tell me how we save List of userdefined objects in XNA?
You're attempting to serialize private properties. That's not supported on Windows Phone 7. Which could easily be cause for the error.
Also, you have to ensure that all of the types you used for properties, is also serializeable, and that all types have a empty constructor.

Resources