Skip to content

Commit

Permalink
Providing materials in model with valid values, see #270
Browse files Browse the repository at this point in the history
  • Loading branch information
AgustinVallejo committed Jul 24, 2024
1 parent 5bc0cef commit d042d53
Show file tree
Hide file tree
Showing 17 changed files with 125 additions and 56 deletions.
8 changes: 8 additions & 0 deletions js/buoyancy-basics/model/BuoyancyBasicsExploreModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Scale, { DisplayType } from '../../common/model/Scale.js';
import TwoBlockMode from '../../common/model/TwoBlockMode.js';
import densityBuoyancyCommon from '../../densityBuoyancyCommon.js';
import MassTag from '../../common/model/MassTag.js';
import { MaterialSchema } from '../../common/model/Mass.js';

type BuoyancyBasicsExploreModelOptions = DensityBuoyancyModelOptions;

Expand All @@ -37,11 +38,17 @@ export default class BuoyancyBasicsExploreModel extends DensityBuoyancyModel {
phetioFeatured: true
} );

const availableMassMaterials: MaterialSchema[] = [
...Material.SIMPLE_MASS_MATERIALS,
'CUSTOM'
];

const blockATandem = blocksTandem.createTandem( 'blockA' );
this.massA = Cube.createWithMass( this.engine, Material.WOOD, new Vector2( -0.2, 0.2 ), 2, {
tag: MassTag.OBJECT_A,
adjustableMaterial: true,
adjustableColor: false,
availableMassMaterials: availableMassMaterials,
tandem: blockATandem
} );
this.availableMasses.push( this.massA );
Expand All @@ -51,6 +58,7 @@ export default class BuoyancyBasicsExploreModel extends DensityBuoyancyModel {
tag: MassTag.OBJECT_B,
adjustableMaterial: true,
adjustableColor: false,
availableMassMaterials: availableMassMaterials,
tandem: blockBTandem,
visible: false
} );
Expand Down
12 changes: 11 additions & 1 deletion js/buoyancy/model/BuoyancyExploreModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Scale, { DisplayType } from '../../common/model/Scale.js';
import TwoBlockMode from '../../common/model/TwoBlockMode.js';
import densityBuoyancyCommon from '../../densityBuoyancyCommon.js';
import MassTag from '../../common/model/MassTag.js';
import { MaterialSchema } from '../../common/model/Mass.js';

export type BuoyancyExploreModelOptions = DensityBuoyancyModelOptions;

Expand All @@ -37,16 +38,25 @@ export default class BuoyancyExploreModel extends DensityBuoyancyModel {
phetioFeatured: true
} );

const availableMassMaterials: MaterialSchema[] = [
...Material.SIMPLE_MASS_MATERIALS,
'CUSTOM',
Material.MATERIAL_X,
Material.MATERIAL_Y
];

this.massA = Cube.createWithMass( this.engine, Material.WOOD, new Vector2( -0.2, 0.2 ), 2, {
tag: MassTag.OBJECT_A,
tandem: blocksTandem.createTandem( 'blockA' )
tandem: blocksTandem.createTandem( 'blockA' ),
availableMassMaterials: availableMassMaterials
} );
this.availableMasses.push( this.massA );
this.massB = Cube.createWithMass( this.engine, Material.ALUMINUM, new Vector2( 0.05, 0.35 ), 13.5, {
tag: MassTag.OBJECT_B,

// REVIEW: Tandem doesn't match variable name
tandem: blocksTandem.createTandem( 'blockB' ),
availableMassMaterials: availableMassMaterials,
visible: false
} );
this.availableMasses.push( this.massB );
Expand Down
11 changes: 10 additions & 1 deletion js/buoyancy/model/BuoyancyLabModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import DensityBuoyancyCommonConstants from '../../common/DensityBuoyancyCommonConstants.js';
import NumberIO from '../../../../tandem/js/types/NumberIO.js';
import ReadOnlyProperty from '../../../../axon/js/ReadOnlyProperty.js';
import { MaterialSchema } from '../../common/model/Mass.js';

export type BuoyancyLabModelOptions = DensityBuoyancyModelOptions;

Expand All @@ -31,8 +32,16 @@ export default class BuoyancyLabModel extends DensityBuoyancyModel {

super( options );

const availableMassMaterials: MaterialSchema[] = [
...Material.SIMPLE_MASS_MATERIALS,
'CUSTOM',
Material.MATERIAL_O,
Material.MATERIAL_P
];

this.block = Cube.createWithMass( this.engine, Material.WOOD, new Vector2( -0.2, 0.2 ), 2, {
tandem: options.tandem.createTandem( 'block' )
tandem: options.tandem.createTandem( 'block' ),
availableMassMaterials: availableMassMaterials
} );
this.availableMasses.push( this.block );

Expand Down
5 changes: 4 additions & 1 deletion js/buoyancy/model/applications/Boat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ import DensityBuoyancyCommonConstants, { toLiters } from '../../../common/Densit
import NumberProperty from '../../../../../axon/js/NumberProperty.js';
import Pool from '../../../common/model/Pool.js';

export type BoatOptions = StrictOmit<ApplicationsMassOptions, 'body' | 'shape' | 'volume' | 'material' | 'massShape'>;
// TODO Factor out this type, https://github.com/phetsims/density-buoyancy-common/issues/270
export type BoatOptions = StrictOmit<ApplicationsMassOptions,
'body' | 'shape' | 'volume' | 'material' | 'massShape' | 'availableMassMaterials'>;

export default class Boat extends ApplicationsMass {

Expand Down Expand Up @@ -65,6 +67,7 @@ export default class Boat extends ApplicationsMass {
volume: volume,
massShape: MassShape.BLOCK,
material: Material.BOAT_BODY,
availableMassMaterials: [ Material.BOAT_BODY ],

accessibleName: 'Boat'
}, providedOptions );
Expand Down
4 changes: 3 additions & 1 deletion js/buoyancy/model/applications/Bottle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ const BOTTLE_INITIAL_INTERIOR_VOLUME = 0.004;
// {Material}
const BOTTLE_INITIAL_INTERIOR_MATERIAL = Material.WATER;

export type BottleOptions = StrictOmit<ApplicationsMassOptions, 'body' | 'shape' | 'volume' | 'material' | 'massShape'>;
export type BottleOptions = StrictOmit<ApplicationsMassOptions,
'body' | 'shape' | 'volume' | 'material' | 'massShape' | 'availableMassMaterials'>;

export default class Bottle extends ApplicationsMass {

Expand All @@ -202,6 +203,7 @@ export default class Bottle extends ApplicationsMass {
shape: Shape.polygon( vertices ),
volume: BOTTLE_VOLUME,
material: 'CUSTOM',
availableMassMaterials: [ 'CUSTOM' ],
materialPropertyOptions: {
phetioReadOnly: true
},
Expand Down
22 changes: 20 additions & 2 deletions js/buoyancy/model/applications/BuoyancyApplicationsModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { BottleOrBoat, BottleOrBoatValues } from './BottleOrBoat.js';
import StringUnionProperty from '../../../../../axon/js/StringUnionProperty.js';
import MassTag from '../../../common/model/MassTag.js';
import Basin from '../../../common/model/Basin.js';
import Mass from '../../../common/model/Mass.js';
import Mass, { MaterialSchema } from '../../../common/model/Mass.js';

export type BuoyancyApplicationsModelOptions = DensityBuoyancyModelOptions;

Expand Down Expand Up @@ -67,9 +67,27 @@ export default class BuoyancyApplicationsModel extends DensityBuoyancyModel {
} );
this.availableMasses.push( this.bottle );

const sortedByDensity: MaterialSchema[] = _.sortBy( [
Material.PYRITE,
Material.STEEL,
Material.SILVER,
Material.TANTALUM,
Material.GOLD,
Material.PLATINUM
].concat( Material.SIMPLE_MASS_MATERIALS ),

material => material.density );
const availableMassMaterials = sortedByDensity.concat( [
// Adding custom/mystery Materials separately, so they aren't sorted above by density
'CUSTOM',
Material.MATERIAL_V,
Material.MATERIAL_W
] );

this.block = Cube.createWithVolume( this.engine, Material.BRICK, new Vector2( -0.5, 0.3 ), 0.001, {
visible: false,
tandem: objectsTandem.createTandem( 'block' )
tandem: objectsTandem.createTandem( 'block' ),
availableMassMaterials: availableMassMaterials
} );
this.availableMasses.push( this.block );

Expand Down
9 changes: 8 additions & 1 deletion js/buoyancy/model/shapes/BuoyancyShapesModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default class BuoyancyShapesModel extends DensityBuoyancyModel {
public readonly objectB: BuoyancyShapeModel;

public readonly materialProperty: MaterialProperty;
private readonly availableMaterials: Material[];

public constructor( options: BuoyancyShapesModelOptions ) {

Expand All @@ -54,11 +55,13 @@ export default class BuoyancyShapesModel extends DensityBuoyancyModel {
phetioFeatured: true
} );

this.availableMaterials = Material.SIMPLE_MASS_MATERIALS;

this.materialProperty = new MaterialProperty( Material.WOOD,

// This hack is a way of saying, we do not create or support a custom material in this case.
Material.WOOD,
Material.SIMPLE_MASS_MATERIALS, {
this.availableMaterials, {
tandem: objectsTandem.createTandem( 'materialProperty' ),
phetioValueType: ReferenceIO( IOType.ObjectIO )
} );
Expand Down Expand Up @@ -116,6 +119,10 @@ export default class BuoyancyShapesModel extends DensityBuoyancyModel {
private createMass( tandem: Tandem, shape: MassShape, widthRatio: number, heightRatio: number, tag: MassTag ): Mass {
const massOptions = {
material: this.materialProperty.value,
availableMassMaterials: this.availableMaterials,
materialPropertyOptions: {
phetioReadOnly: true
},
minVolume: 0.0002, // Cones have a smaller volume at min height/width
maxVolume: Cuboid.MAX_VOLUME, // Cubes are the highest volume object in this screen
tandem: tandem,
Expand Down
22 changes: 5 additions & 17 deletions js/buoyancy/view/applications/BuoyancyApplicationsScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,23 +204,11 @@ export default class BuoyancyApplicationsScreenView extends BuoyancyScreenView<B

const rightBottleContent = new Panel( bottleBox, DensityBuoyancyCommonConstants.PANEL_OPTIONS );

const blockControls = new MaterialMassVolumeControlNode( model.block.materialProperty, model.block.massProperty, model.block.volumeProperty, _.sortBy( [
Material.PYRITE,
Material.STEEL,
Material.SILVER,
Material.TANTALUM,
Material.GOLD,
Material.PLATINUM
].concat( Material.SIMPLE_MASS_MATERIALS ),
material => material.density ).concat( [
// Adding custom/mystery Materials separately, so they aren't sorted by density
model.block.materialProperty.customMaterial,
Material.MATERIAL_V,
Material.MATERIAL_W
] ), cubicMeters => model.block.updateSize( Cube.boundsFromVolume( cubicMeters ) ), this.popupLayer, true, {
tandem: tandem.createTandem( 'blockControls' ),
highDensityMaxMass: 215
} );
const blockControls = new MaterialMassVolumeControlNode( model.block.materialProperty, model.block.massProperty, model.block.volumeProperty,
model.block.materialProperty.availableValues, cubicMeters => model.block.updateSize( Cube.boundsFromVolume( cubicMeters ) ), this.popupLayer, true, {
tandem: tandem.createTandem( 'blockControls' ),
highDensityMaxMass: 215
} );

model.block.materialProperty.link( material => {
if ( material === Material.MATERIAL_V ) {
Expand Down
8 changes: 5 additions & 3 deletions js/common/model/CompareBlockSetModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ export default class CompareBlockSetModel extends BlockSetModel<BlockSet> {
sharedCubeOptions: {
materialPropertyOptions: {
phetioReadOnly: true // See https://github.com/phetsims/density-buoyancy-common/issues/270#issuecomment-2243371397
}
},
availableMassMaterials: [] // TODO: 'CUSTOM' isn't right in here, instead we need to figure out the "side MaterialProperty" instances first. https://github.com/phetsims/density-buoyancy-common/issues/273
},

// BlockSetModel options
Expand Down Expand Up @@ -168,11 +169,11 @@ export default class CompareBlockSetModel extends BlockSetModel<BlockSet> {
}, cubeData );
} );

const getCubeOptions = ( cubeOptions: StrictCubeOptions ) => combineOptions<CubeOptions>( {}, options.sharedCubeOptions, cubeOptions );
// TODO: We lost type checking for availableMassMaterials because of the `CubeOptions` type, https://github.com/phetsims/density-buoyancy-common/issues/273
const getCubeOptions = ( cubeOptions: StrictOmit<StrictCubeOptions, 'availableMassMaterials'> ) => combineOptions<CubeOptions>( {}, options.sharedCubeOptions, cubeOptions );

// TODO: Helpful documentation please, see https://github.com/phetsims/density-buoyancy-common/issues/273
const createMasses = ( model: BlockSetModel<BlockSet>, blockSet: BlockSet ) => {

// TODO: Helpful documentation please, see https://github.com/phetsims/density-buoyancy-common/issues/273
// In the following code, the cube instance persists for the lifetime of the simulation and the listeners
// don't need to be removed.
Expand Down Expand Up @@ -263,6 +264,7 @@ export default class CompareBlockSetModel extends BlockSetModel<BlockSet> {
* Otherwise, it creates a custom material with a modified color based on the density.
*
* TODO: Should this return MaterialProperty and create its own customMaterial? see https://github.com/phetsims/density-buoyancy-common/issues/273
* TODO: Can we use initialMaterials as the availableMassMaterials for the blocks created for this blockSet? https://github.com/phetsims/density-buoyancy-common/issues/273
*/
private static createMaterialProperty( tandem: Tandem, colorProperty: TReadOnlyProperty<Color>, densityProperty: TReadOnlyProperty<number>,
blockSetValueChangedProperty: TReadOnlyProperty<boolean>, initialMaterials: Material[] ): TReadOnlyProperty<Material> {
Expand Down
6 changes: 3 additions & 3 deletions js/common/model/Cube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import densityBuoyancyCommon from '../../densityBuoyancyCommon.js';
import Cuboid, { CuboidOptions } from './Cuboid.js';
import PhysicsEngine from './PhysicsEngine.js';
import optionize, { combineOptions } from '../../../../phet-core/js/optionize.js';
import Material from './Material.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import { MaterialSchema } from './Mass.js';

type SelfOptions = {

Expand Down Expand Up @@ -79,7 +79,7 @@ export default class Cube extends Cuboid {
/**
* Creates a Cube with a defined volume
*/
public static createWithVolume( engine: PhysicsEngine, material: Material | 'CUSTOM', position: Vector2, volume: number, options?: StrictCubeOptions ): Cube {
public static createWithVolume( engine: PhysicsEngine, material: MaterialSchema, position: Vector2, volume: number, options?: StrictCubeOptions ): Cube {
return new Cube( engine, volume, combineOptions<CubeOptions>( {
matrix: Matrix3.translation( position.x, position.y ),
minVolume: Cuboid.MIN_VOLUME,
Expand All @@ -91,7 +91,7 @@ export default class Cube extends Cuboid {
/**
* Creates a Cube with a defined volume
*/
public static createWithMass( engine: PhysicsEngine, material: Material | 'CUSTOM', position: Vector2, mass: number, options?: StrictCubeOptions ): Cube {
public static createWithMass( engine: PhysicsEngine, material: MaterialSchema, position: Vector2, mass: number, options?: StrictCubeOptions ): Cube {
let density: number;
if ( material === 'CUSTOM' ) {
assert && assert( options?.customMaterialOptions?.density, 'density needed to create with mass' );
Expand Down
14 changes: 8 additions & 6 deletions js/common/model/Mass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,16 @@ import ReferenceIO from '../../../../tandem/js/types/ReferenceIO.js';
export const MASS_MIN_SHAPES_DIMENSION = 0.1; // 10cm => 1L square
export const MASS_MAX_SHAPES_DIMENSION = Math.pow( 0.01, 1 / 3 ); // 10L square

export type MaterialSchema = Material | 'CUSTOM'; // We pass 'CUSTOM' so materialProperty can create the customMaterial

type SelfOptions = {

// Required
body: PhysicsEngineBody;
shape: Shape;

// Use "CUSTOM" to tell the MaterialProperty to take the initial value from the internal customMaterial it creates.
material: Material | 'CUSTOM';
material: MaterialSchema;
availableMassMaterials: MaterialSchema[];
volume: number;
massShape: MassShape;

Expand All @@ -66,10 +68,12 @@ type SelfOptions = {

// Allow Customization of the material beyond initial value, this includes PhET-iO support for changing the density
// and color, as well as support for some screens to adjust density instead of mass/volume as is most typical, see https://github.com/phetsims/density/issues/101
// TODO AV: Get outta here, https://github.com/phetsims/density-buoyancy-common/issues/270
adjustableMaterial?: boolean;

// Only used when adjustableMaterial:true. Set to true to support a PhET-iO instrumented Property to set the color
// of the block. Set to false in order to calculate the color based on the current density + the density range.
// TODO AV: Get outta here, https://github.com/phetsims/density-buoyancy-common/issues/270
adjustableColor?: boolean;
tag?: MassTag;
accessibleName?: PDOMValueType | null;
Expand Down Expand Up @@ -252,14 +256,12 @@ export default abstract class Mass extends PhetioObject {

options.materialPropertyOptions.tandem = options.materialPropertyOptions.tandem || tandem.createTandem( 'materialProperty' );
const customSolidMaterial = new CustomSolidMaterial( options.materialPropertyOptions.tandem.createTandem( 'customMaterial' ), combineOptions<MaterialOptions>( {
density: options.material === 'CUSTOM' ? undefined : options.material.density
density: options.material === 'CUSTOM' ? undefined : options.material.density // The undefined makes sure we don't override the default
}, options.customMaterialOptions ) );

const initialMaterial = options.material === 'CUSTOM' ? customSolidMaterial : options.material;
this.materialProperty = new MaterialProperty( initialMaterial, customSolidMaterial,

// TODO: Do this part next, https://github.com/phetsims/density-buoyancy-common/issues/270
[],
options.availableMassMaterials.map( x => x === 'CUSTOM' ? customSolidMaterial : x ),
options.materialPropertyOptions as MaterialPropertyOptions );

this.volumeProperty = new NumberProperty( options.volume, combineOptions<NumberPropertyOptions>( {
Expand Down
8 changes: 8 additions & 0 deletions js/common/model/Material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,14 @@ export default class Material extends PhetioObject implements HasValueProperty {
Material.ALUMINUM
];

// TODO: This is the exact list from Density 1.1 (adding in PVC), do we need to support this exactly for some reason? Or can it just be a more general list? https://github.com/phetsims/density-buoyancy-common/issues/270
public static readonly DENSITY_MYSTERY_PHET_IO_CUSTOMIZABLE_MATERIAL = [
...Material.SIMPLE_MASS_MATERIALS,
Material.STEEL,
Material.COPPER,
Material.PLATINUM
];

public static readonly BUOYANCY_FLUID_MATERIALS = [
Material.GASOLINE,
Material.OIL,
Expand Down
6 changes: 5 additions & 1 deletion js/common/model/Scale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ type SelfOptions = {
displayType?: DisplayType;
};

export type ScaleOptions = SelfOptions & StrictOmit<InstrumentedMassOptions, 'body' | 'shape' | 'volume' | 'material' | 'massShape'> & PickOptional<InstrumentedMassOptions, 'body' | 'shape'>;
// TODO: Cleanup https://github.com/phetsims/density-buoyancy-common/issues/270
export type ScaleOptions = SelfOptions & StrictOmit<InstrumentedMassOptions,
'body' | 'shape' | 'volume' | 'material' | 'massShape' | 'availableMassMaterials'> &
PickOptional<InstrumentedMassOptions, 'body' | 'shape'>;

export default class Scale extends Mass {

Expand All @@ -89,6 +92,7 @@ export default class Scale extends Mass {

displayType: DisplayType.NEWTONS,
material: Material.PLATINUM,
availableMassMaterials: [ Material.PLATINUM ],

accessibleName: 'Scale',

Expand Down
2 changes: 1 addition & 1 deletion js/common/view/ABControlsNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import ABPanelsNode from './ABPanelsNode.js';
import Material from '../model/Material.js';

type SelfOptions = {
mysteryMaterials?: Material[];
mysteryMaterials?: Material[]; // TODO: delete, https://github.com/phetsims/density-buoyancy-common/issues/270
};

export type ABControlsNodeOptions = SelfOptions & BlockControlNodeOptions & { tandem: Tandem };
Expand Down
Loading

0 comments on commit d042d53

Please sign in to comment.