001/*
002 * Renderer 4. The MIT License.
003 * Copyright (c) 2022 rlkraft@pnw.edu
004 * See LICENSE for details.
005*/
006
007package renderer.scene.util;
008
009import renderer.scene.*;
010import renderer.scene.primitives.*;
011
012import java.util.List;
013import java.util.ArrayList;
014import java.awt.Color;
015import java.util.Random;
016
017/**
018   This is a library of static methods that
019   add color shading to a {@link Model}.
020*/
021public class ModelShading
022{
023   /**
024      Set each {@link Color} in the {@link Model}'s color list
025      to the same {@link Color}.
026
027      @param model  {@link Model} whose color list is being manipulated
028      @param c      {@link Color} for all of this model's {@link Vertex} objects
029   */
030   public static void setColor(final Model model, final Color c)
031   {
032      if (model.colorList.isEmpty())
033      {
034         for (int i = 0; i < model.vertexList.size(); ++i)
035         {
036            model.colorList.add(c);
037         }
038      }
039      else
040      {
041         for (int i = 0; i < model.colorList.size(); ++i)
042         {
043            model.colorList.set(i, c);
044         }
045      }
046   }
047
048
049   /**
050      Set each {@link Color} in the {@link Model}'s color list
051      to the same random {@link Color}.
052
053      @param model  {@link Model} whose color list is being manipulated
054   */
055   public static void setRandomColor(final Model model)
056   {
057      setColor(model, randomColor());
058   }
059
060
061   /**
062      Set each {@link Color} in the {@link Model}'s color list
063      to a different random {@link Color}.
064
065      @param model  {@link Model} whose color list is being manipulated
066   */
067   public static void setRandomColors(final Model model)
068   {
069      if (model.colorList.isEmpty())
070      {
071         for (int i = 0; i < model.vertexList.size(); ++i)
072         {
073            model.colorList.add(randomColor());
074         }
075      }
076      else
077      {
078         for (int i = 0; i < model.colorList.size(); ++i)
079         {
080            model.colorList.set(i, randomColor());
081         }
082      }
083   }
084
085
086   /**
087      Set each {@link Vertex} in the {@link Model}
088      to a different random {@link Color}.
089      <p>
090      This creates a "rainbow model" effect.
091      <p>
092      NOTE: This will destroy whatever "color structure"
093      the model might possess.
094
095      @param model  {@link Model} whose color list is being manipulated
096   */
097   public static void setRandomVertexColors(final Model model)
098   {
099      model.colorList.clear(); // remove all the current colors
100      for (int i = 0; i < model.vertexList.size(); ++i)
101      {
102         model.colorList.add( randomColor() );
103      }
104      for (final Primitive p : model.primitiveList)
105      {
106         for (int i = 0; i < p.vIndexList.size(); ++i)
107         {
108            p.cIndexList.set(i, p.vIndexList.get(i));
109         }
110      }
111   }
112
113
114   /**
115      Set each {@link Primitive} in the {@link Model}
116      to a different (uniform) random {@link Color}.
117      <p>
118      NOTE: This will destroy whatever "color structure"
119      the model might possess.
120
121      @param model  {@link Model} whose color list is being manipulated
122   */
123   public static void setRandomPrimitiveColors(final Model model)
124   {
125      model.colorList.clear(); // remove all the current colors
126      int cIndex = 0;
127      for (final Primitive p : model.primitiveList)
128      {
129         model.colorList.add( randomColor() );
130         for (int i = 0; i < p.cIndexList.size(); ++i)
131         {
132            p.cIndexList.set(i, cIndex);
133         }
134         ++cIndex;
135      }
136   }
137
138
139   /**
140      Set each {@link Primitive} in the {@link Model}
141      to a different random {@link Color} at each endpoint.
142      <p>
143      This creates a "rainbow primitive" effect.
144      <p>
145      NOTE: This will destroy whatever "color structure"
146      the model might possess.
147
148      @param model  {@link Model} whose color list is being manipulated
149   */
150   public static void setRainbowPrimitiveColors(final Model model)
151   {
152      model.colorList.clear(); // remove all the current colors
153      int cIndex = 0;
154      for (final Primitive p : model.primitiveList)
155      {
156         for (int i = 0; i < p.cIndexList.size(); ++i)
157         {
158            model.colorList.add( randomColor() );
159            p.cIndexList.set(i, cIndex);
160            ++cIndex;
161         }
162      }
163   }
164
165
166   /**
167      Create a {@link Color} object with randomly generated {@code r},
168      {@code g}, and {@code b} values.
169
170      @return a reference to a randomly generated {@link Color} object
171   */
172   public static Color randomColor()
173   {
174      final Random generator = new Random();
175      final float r = generator.nextFloat();
176      final float g = generator.nextFloat();
177      final float b = generator.nextFloat();
178      return new Color(r, g, b);
179   }
180
181
182
183   // Private default constructor to enforce noninstantiable class.
184   // See Item 4 in "Effective Java", 3rd Ed, Joshua Bloch.
185   private ModelShading() {
186      throw new AssertionError();
187   }
188}