aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRobert Adams2013-01-28 15:11:50 -0800
committerRobert Adams2013-01-28 15:11:50 -0800
commite9aff0a91d6a4d02498ce45759389bb09b34fcbc (patch)
tree7379562cbd8825413be1db2bc9a7f4a501e58207
parentBulletSim: rename 'uint' to 'UInt32' to make clear the type that is passed to... (diff)
downloadopensim-SC_OLD-e9aff0a91d6a4d02498ce45759389bb09b34fcbc.zip
opensim-SC_OLD-e9aff0a91d6a4d02498ce45759389bb09b34fcbc.tar.gz
opensim-SC_OLD-e9aff0a91d6a4d02498ce45759389bb09b34fcbc.tar.bz2
opensim-SC_OLD-e9aff0a91d6a4d02498ce45759389bb09b34fcbc.tar.xz
BulletSim: do not zero an avatar's standing velocity if it is standing
on a moving object. Rearrange pre/post action subscription code to put more in locks. Add meshmerizer params to BulletSimTestUtil scene creation (and fix line endings). Rebuilt version of DLLs and SOs with cleaned up code and no profiling for sure.
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs13
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs33
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs168
-rwxr-xr-xbin/lib32/BulletSim.dllbin545792 -> 545280 bytes
-rwxr-xr-xbin/lib32/libBulletSim.sobin1689992 -> 1690012 bytes
-rwxr-xr-xbin/lib64/BulletSim.dllbin693248 -> 693248 bytes
-rwxr-xr-xbin/lib64/libBulletSim.sobin1834903 -> 1834927 bytes
7 files changed, 118 insertions, 96 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 7603254..3884a5d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -56,7 +56,6 @@ public sealed class BSCharacter : BSPhysObject
56 private int _physicsActorType; 56 private int _physicsActorType;
57 private bool _isPhysical; 57 private bool _isPhysical;
58 private bool _flying; 58 private bool _flying;
59 private bool _wasWalking; // 'true' if the avatar was walking/moving last frame
60 private bool _setAlwaysRun; 59 private bool _setAlwaysRun;
61 private bool _throttleUpdates; 60 private bool _throttleUpdates;
62 private bool _floatOnWater; 61 private bool _floatOnWater;
@@ -84,7 +83,6 @@ public sealed class BSCharacter : BSPhysObject
84 _position = pos; 83 _position = pos;
85 84
86 _flying = isFlying; 85 _flying = isFlying;
87 _wasWalking = true; // causes first step to initialize standing
88 _orientation = OMV.Quaternion.Identity; 86 _orientation = OMV.Quaternion.Identity;
89 _velocity = OMV.Vector3.Zero; 87 _velocity = OMV.Vector3.Zero;
90 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 88 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
@@ -220,7 +218,13 @@ public sealed class BSCharacter : BSPhysObject
220 { 218 {
221 // The avatar shouldn't be moving 219 // The avatar shouldn't be moving
222 _velocityMotor.Zero(); 220 _velocityMotor.Zero();
223 ZeroMotion(true /* inTaintTime */); 221
222 // If we are colliding with a stationary object, presume we're standing and don't move around
223 if (!ColliderIsMoving)
224 {
225 DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
226 ZeroMotion(true /* inTaintTime */);
227 }
224 228
225 // Standing has more friction on the ground 229 // Standing has more friction on the ground
226 if (_currentFriction != BSParam.AvatarStandingFriction) 230 if (_currentFriction != BSParam.AvatarStandingFriction)
@@ -229,8 +233,6 @@ public sealed class BSCharacter : BSPhysObject
229 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction); 233 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
230 } 234 }
231 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue); 235 DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue);
232
233 _wasWalking = false;
234 } 236 }
235 else 237 else
236 { 238 {
@@ -260,7 +262,6 @@ public sealed class BSCharacter : BSPhysObject
260 262
261 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce); 263 DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
262 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce); 264 PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
263 _wasWalking = true;
264 } 265 }
265 }); 266 });
266 } 267 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 5e8143c..a113530 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -96,6 +96,7 @@ public abstract class BSPhysObject : PhysicsActor
96 CollidingStep = 0; 96 CollidingStep = 0;
97 CollidingGroundStep = 0; 97 CollidingGroundStep = 0;
98 CollisionAccumulation = 0; 98 CollisionAccumulation = 0;
99 ColliderIsMoving = false;
99 CollisionScore = 0; 100 CollisionScore = 0;
100 } 101 }
101 102
@@ -177,13 +178,14 @@ public abstract class BSPhysObject : PhysicsActor
177 public abstract OMV.Vector3 RawPosition { get; set; } 178 public abstract OMV.Vector3 RawPosition { get; set; }
178 public abstract OMV.Vector3 ForcePosition { get; set; } 179 public abstract OMV.Vector3 ForcePosition { get; set; }
179 180
180 // Position is what the simulator thinks the positions of the prim is. 181 // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
181 // Because Bullet needs the zero coordinate to be the center of mass of the linkset, 182 // Because Bullet needs the zero coordinate to be the center of mass of the linkset,
182 // sometimes it is necessary to displace the position the physics engine thinks 183 // sometimes it is necessary to displace the position the physics engine thinks
183 // the position is. PositionDisplacement must be added and removed from the 184 // the position is. PositionDisplacement must be added and removed from the
184 // position as the simulator position is stored and fetched from the physics 185 // position as the simulator position is stored and fetched from the physics
185 // engine. 186 // engine. Similar to OrientationDisplacement.
186 public virtual OMV.Vector3 PositionDisplacement { get; set; } 187 public virtual OMV.Vector3 PositionDisplacement { get; set; }
188 public virtual OMV.Quaternion OrientationDisplacement { get; set; }
187 189
188 public abstract OMV.Quaternion RawOrientation { get; set; } 190 public abstract OMV.Quaternion RawOrientation { get; set; }
189 public abstract OMV.Quaternion ForceOrientation { get; set; } 191 public abstract OMV.Quaternion ForceOrientation { get; set; }
@@ -240,6 +242,9 @@ public abstract class BSPhysObject : PhysicsActor
240 protected long CollidingObjectStep { get; set; } 242 protected long CollidingObjectStep { get; set; }
241 // The collision flags we think are set in Bullet 243 // The collision flags we think are set in Bullet
242 protected CollisionFlags CurrentCollisionFlags { get; set; } 244 protected CollisionFlags CurrentCollisionFlags { get; set; }
245 // On a collision, check the collider and remember if the last collider was moving
246 // Used to modify the standing of avatars (avatars on stationary things stand still)
247 protected bool ColliderIsMoving;
243 248
244 // Count of collisions for this object 249 // Count of collisions for this object
245 protected long CollisionAccumulation { get; set; } 250 protected long CollisionAccumulation { get; set; }
@@ -307,7 +312,10 @@ public abstract class BSPhysObject : PhysicsActor
307 312
308 CollisionAccumulation++; 313 CollisionAccumulation++;
309 314
310 // if someone has subscribed for collision events.... 315 // For movement tests, remember if we are colliding with an object that is moving.
316 ColliderIsMoving = collidee != null ? collidee.RawVelocity != OMV.Vector3.Zero : false;
317
318 // If someone has subscribed for collision events log the collision so it will be reported up
311 if (SubscribedEvents()) { 319 if (SubscribedEvents()) {
312 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 320 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
313 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", 321 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}",
@@ -393,12 +401,13 @@ public abstract class BSPhysObject : PhysicsActor
393 public override bool SubscribedEvents() { 401 public override bool SubscribedEvents() {
394 return (SubscribedEventsMs > 0); 402 return (SubscribedEventsMs > 0);
395 } 403 }
396 // Because 'CollisionScore' is calls many times while sorting it should not be recomputed 404 // Because 'CollisionScore' is called many times while sorting, it should not be recomputed
397 // each time called. So this is built to be light weight for each collision and to do 405 // each time called. So this is built to be light weight for each collision and to do
398 // all the processing when the user asks for the info. 406 // all the processing when the user asks for the info.
399 public void ComputeCollisionScore() 407 public void ComputeCollisionScore()
400 { 408 {
401 // Scale the collision count by the time since the last collision 409 // Scale the collision count by the time since the last collision.
410 // The "+1" prevents dividing by zero.
402 long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1; 411 long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1;
403 CollisionScore = CollisionAccumulation / timeAgo; 412 CollisionScore = CollisionAccumulation / timeAgo;
404 } 413 }
@@ -423,13 +432,15 @@ public abstract class BSPhysObject : PhysicsActor
423 UnRegisterPreStepAction(op, id); 432 UnRegisterPreStepAction(op, id);
424 433
425 RegisteredPrestepActions[identifier] = actn; 434 RegisteredPrestepActions[identifier] = actn;
435
436 PhysicsScene.BeforeStep += actn;
426 } 437 }
427 PhysicsScene.BeforeStep += actn;
428 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier); 438 DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
429 } 439 }
430 440
431 // Unregister a pre step action. Safe to call if the action has not been registered. 441 // Unregister a pre step action. Safe to call if the action has not been registered.
432 protected void UnRegisterPreStepAction(string op, uint id) 442 // Returns 'true' if an action was actually removed
443 protected bool UnRegisterPreStepAction(string op, uint id)
433 { 444 {
434 string identifier = op + "-" + id.ToString(); 445 string identifier = op + "-" + id.ToString();
435 bool removed = false; 446 bool removed = false;
@@ -443,6 +454,7 @@ public abstract class BSPhysObject : PhysicsActor
443 } 454 }
444 } 455 }
445 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed); 456 DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
457 return removed;
446 } 458 }
447 459
448 protected void UnRegisterAllPreStepActions() 460 protected void UnRegisterAllPreStepActions()
@@ -468,13 +480,15 @@ public abstract class BSPhysObject : PhysicsActor
468 UnRegisterPostStepAction(op, id); 480 UnRegisterPostStepAction(op, id);
469 481
470 RegisteredPoststepActions[identifier] = actn; 482 RegisteredPoststepActions[identifier] = actn;
483
484 PhysicsScene.AfterStep += actn;
471 } 485 }
472 PhysicsScene.AfterStep += actn;
473 DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier); 486 DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
474 } 487 }
475 488
476 // Unregister a pre step action. Safe to call if the action has not been registered. 489 // Unregister a pre step action. Safe to call if the action has not been registered.
477 protected void UnRegisterPostStepAction(string op, uint id) 490 // Returns 'true' if an action was actually removed.
491 protected bool UnRegisterPostStepAction(string op, uint id)
478 { 492 {
479 string identifier = op + "-" + id.ToString(); 493 string identifier = op + "-" + id.ToString();
480 bool removed = false; 494 bool removed = false;
@@ -488,6 +502,7 @@ public abstract class BSPhysObject : PhysicsActor
488 } 502 }
489 } 503 }
490 DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed); 504 DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed);
505 return removed;
491 } 506 }
492 507
493 protected void UnRegisterAllPostStepActions() 508 protected void UnRegisterAllPostStepActions()
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
index 6c2247a..e7657f9 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BulletSimTestsUtil.cs
@@ -1,81 +1,87 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq; 30using System.Linq;
31using System.Text; 31using System.Text;
32 32
33using Nini.Config; 33using Nini.Config;
34 34
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Physics.BulletSPlugin; 36using OpenSim.Region.Physics.BulletSPlugin;
37using OpenSim.Region.Physics.Meshing; 37using OpenSim.Region.Physics.Meshing;
38 38
39namespace OpenSim.Region.Physics.BulletSPlugin.Tests 39namespace OpenSim.Region.Physics.BulletSPlugin.Tests
40{ 40{
41// Utility functions for building up and tearing down the sample physics environments 41// Utility functions for building up and tearing down the sample physics environments
42public static class BulletSimTestsUtil 42public static class BulletSimTestsUtil
43{ 43{
44 // 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA" 44 // 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA"
45 // 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults) 45 // 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults)
46 // May be 'null' if there are no overrides. 46 // May be 'null' if there are no overrides.
47 public static BSScene CreateBasicPhysicsEngine(string engineName, Dictionary<string,string> paramOverrides) 47 public static BSScene CreateBasicPhysicsEngine(Dictionary<string,string> paramOverrides)
48 { 48 {
49 if (engineName == null) 49 IConfigSource openSimINI = new IniConfigSource();
50 engineName = "BulletUnmanaged"; 50 IConfig startupConfig = openSimINI.AddConfig("StartUp");
51 51 startupConfig.Set("physics", "BulletSim");
52 IConfigSource openSimINI = new IniConfigSource(); 52 startupConfig.Set("meshing", "Meshmerizer");
53 IConfig startupConfig = openSimINI.AddConfig("StartUp"); 53 startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps
54 startupConfig.Set("meshing", "Meshmerizer"); 54
55 startupConfig.Set("physics", "BulletSim"); 55 IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim");
56 56 // If the caller cares, specify the bullet engine otherwise it will default to "BulletUnmanaged".
57 IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim"); 57 // bulletSimConfig.Set("BulletEngine", "BulletUnmanaged");
58 bulletSimConfig.Set("BulletEngine", engineName); 58 // bulletSimConfig.Set("BulletEngine", "BulletXNA");
59 if (paramOverrides != null) 59 bulletSimConfig.Set("MeshSculptedPrim", "false");
60 { 60 bulletSimConfig.Set("ForceSimplePrimMeshing", "true");
61 foreach (KeyValuePair<string, string> kvp in paramOverrides) 61 if (paramOverrides != null)
62 { 62 {
63 bulletSimConfig.Set(kvp.Key, kvp.Value); 63 foreach (KeyValuePair<string, string> kvp in paramOverrides)
64 } 64 {
65 } 65 bulletSimConfig.Set(kvp.Key, kvp.Value);
66 // bulletSimConfig.Set("PhysicsLoggingEnabled","True"); 66 }
67 // bulletSimConfig.Set("PhysicsLoggingDoFlush","True"); 67 }
68 // bulletSimConfig.Set("VehicleLoggingEnabled","True"); 68 // bulletSimConfig.Set("PhysicsLoggingEnabled","True");
69 69 // bulletSimConfig.Set("PhysicsLoggingDoFlush","True");
70 BSPlugin bsPlugin = new BSPlugin(); 70 // bulletSimConfig.Set("VehicleLoggingEnabled","True");
71 71
72 BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion"); 72 BSPlugin bsPlugin = new BSPlugin();
73 73
74 Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI); 74 BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion");
75 bsScene.Initialise(mesher, openSimINI); 75
76 76 // Since the asset requestor is not initialized, any mesh or sculptie will be a cube.
77 return bsScene; 77 // In the future, add a fake asset fetcher to get meshes and sculpts.
78 } 78 // bsScene.RequestAssetMethod = ???;
79 79
80} 80 Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI);
81} 81 bsScene.Initialise(mesher, openSimINI);
82
83 return bsScene;
84 }
85
86}
87}
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index d8be6c7..24dffac 100755
--- a/bin/lib32/BulletSim.dll
+++ b/bin/lib32/BulletSim.dll
Binary files differ
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so
index e188cbf..7e3ed20 100755
--- a/bin/lib32/libBulletSim.so
+++ b/bin/lib32/libBulletSim.so
Binary files differ
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll
index 5403913..808f433 100755
--- a/bin/lib64/BulletSim.dll
+++ b/bin/lib64/BulletSim.dll
Binary files differ
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so
index a695fa4..9382751 100755
--- a/bin/lib64/libBulletSim.so
+++ b/bin/lib64/libBulletSim.so
Binary files differ