001/* 002 * Renderer 4. The MIT License. 003 * Copyright (c) 2022 rlkraft@pnw.edu 004 * See LICENSE for details. 005*/ 006 007package renderer.scene.primitives; 008 009import java.util.List; 010import java.util.ArrayList; 011 012/** 013 A {@code Primitive} is something that we can build 014 geometric shapes out of (a "graphics primitive"). 015<p> 016 See <a href="https://en.wikipedia.org/wiki/Geometric_primitive" target="_top"> 017 https://en.wikipedia.org/wiki/Geometric_primitive</a> 018<p> 019 We have two geometric primitives, 020 <ul> 021 <li>{@link LineSegment}, 022 <li>{@link Point}. 023 </ul> 024<p> 025 Each {@code Primitive} holds two lists of integer indices. 026<p> 027 One list is of indices into its {@link renderer.scene.Model}'s 028 {@link List} of {@link renderer.scene.Vertex} objects. These 029 are the vertices that determine the primitive's geometry. 030<p> 031 The other list is of indices into its {@link renderer.scene.Model}'s 032 {@link List} of {@link java.awt.Color} objects. 033<p> 034 The two lists of integer indices must always have the same 035 length. For every {@link renderer.scene.Vertex} index in a 036 {@code Primitive} there must be a {@link java.awt.Color} index. 037*/ 038/* 039 NOTE: The Primitive class could be an inner class of 040 the Model class. Then each Primitive object would 041 automatically have access to the actual Vertex and 042 Color lists that the Primitive is indexing into. 043*/ 044public abstract class Primitive 045{ 046 // A Primitive object is made up of indices to vertices and colors in a Model. 047 public final List<Integer> vIndexList; // indices for this primitive's vertices 048 public final List<Integer> cIndexList; // indices for this primitive's colors 049 050 /** 051 Construct an empty {@code Primitive}. 052 */ 053 protected Primitive() 054 { 055 this.vIndexList = new ArrayList<>(); 056 this.cIndexList = new ArrayList<>(); 057 } 058 059 060 /** 061 Construct a {@code Primitive} with the given array of indices for the 062 {@link renderer.scene.Vertex} and {@link java.awt.Color} index lists. 063 <p> 064 NOTE: This constructor does not put any {@link renderer.scene.Vertex} 065 or {@link java.awt.Color} objects into this {@link Primitive}'s 066 {@link renderer.scene.Model} object. This constructor assumes that 067 the given indices are valid (or will be valid by the time this 068 {@link Primitive} gets rendered). 069 070 @param indices array of {@link renderer.scene.Vertex} and {@link java.awt.Color} indices to place in this {@code Primitive} 071 */ 072 protected Primitive(final int... indices) 073 { 074 this(); 075 076 for (final int i : indices) 077 { 078 addIndices(i, i); 079 } 080 } 081 082 083 /** 084 Construct a {@code Primitive} object using the two given 085 {@link List}s of integer indices. 086 <p> 087 NOTE: This constructor does not put any {@link renderer.scene.Vertex} 088 or {@link java.awt.Color} objects into this {@link Primitive}'s 089 {@link renderer.scene.Model} object. This constructor assumes that 090 the given indices are valid (or will be valid by the time this 091 {@link Primitive} gets rendered). 092 093 @param vIndexList {@link List} of integer indices into a {@link renderer.scene.Vertex} list 094 @param cIndexList {@link List} of integer indices into a {@link java.awt.Color} list 095 @throws NullPointerException if {@code vIndexList} is {@code null} 096 @throws NullPointerException if {@code cIndexList} is {@code null} 097 @throws IllegalArgumentException if {@code vIndexList} and {@code cIndexList} are not the same size 098 */ 099 protected Primitive(final List<Integer> vIndexList, 100 final List<Integer> cIndexList) 101 { 102 if (null == vIndexList) 103 throw new NullPointerException("vIndexList must not be null"); 104 if (null == cIndexList) 105 throw new NullPointerException("cIndexList must not be null"); 106 if (vIndexList.size() != cIndexList.size() ) 107 throw new IllegalArgumentException("vIndexList and cIndexList must be the same size"); 108 109 this.vIndexList = vIndexList; 110 this.cIndexList = cIndexList; 111 } 112 113 114 /** 115 Add the given array of indices to the {@link renderer.scene.Vertex} 116 and {@link java.awt.Color} index lists. 117 <p> 118 NOTE: This method does not put any {@link renderer.scene.Vertex} 119 or {@link java.awt.Color} objects into this {@link Primitive}'s 120 {@link renderer.scene.Model} object. This method assumes that 121 the given indices are valid (or will be valid by the time this 122 {@link Primitive} gets rendered). 123 124 @param indices array of {@link renderer.scene.Vertex} and {@link java.awt.Color} indices to add to this {@code Primitive} 125 */ 126 public void addIndex(final int... indices) 127 { 128 for (final int i : indices) 129 { 130 addIndices(i, i); 131 } 132 } 133 134 135 /** 136 Add the given indices to the {@link renderer.scene.Vertex} and 137 {@link java.awt.Color} index lists. 138 <p> 139 NOTE: This method does not put any {@link renderer.scene.Vertex} 140 or {@link java.awt.Color} objects into this {@link Primitive}'s 141 {@link renderer.scene.Model} object. This method assumes that 142 the given indices are valid (or will be valid by the time this 143 {@link Primitive} gets rendered). 144 145 @param vIndex integer {@link renderer.scene.Vertex} index to add to this {@code Primitive} 146 @param cIndex integer {@link java.awt.Color} index to add to this {@code Primitive} 147 */ 148 public void addIndices(final int vIndex, final int cIndex) 149 { 150 vIndexList.add(vIndex); 151 cIndexList.add(cIndex); 152 } 153 154 155 /** 156 Set the {@link java.awt.Color} index list to the given array of indices. 157 <p> 158 NOTE: This method does not put any {@link java.awt.Color} objects 159 into this {@link Primitive}'s {@link renderer.scene.Model} object. 160 This method assumes that the given indices are valid (or will be 161 valid by the time this {@link Primitive} gets rendered). 162 163 @param cIndices array of {@link java.awt.Color} indices for this {@code Primitive} 164 @throws IllegalArgumentException if {@code cIndices} does not have the correct length for this {@code Primitive} 165 */ 166 public void setColorIndices(final int... cIndices) 167 { 168 if (vIndexList.size() != cIndices.length ) 169 throw new IllegalArgumentException("wrong number of color indices for this primitive"); 170 171 cIndexList.clear(); 172 for (int i = 0; i < cIndices.length; ++i) 173 { 174 cIndexList.add( cIndices[i] ); 175 } 176 } 177 178 179 /** 180 Give this {@code Primitive} the uniform {@link java.awt.Color} indexed 181 by the given color index. 182 <p> 183 NOTE: This method does not put a {@link java.awt.Color} object 184 into this {@link Primitive}'s {@link renderer.scene.Model} object. 185 This method assumes that the given index is valid (or will be valid 186 by the time this {@link Primitive} gets rendered). 187 188 @param cIndex integer color index to use for this {@code Primitive}'s {@link java.awt.Color} 189 */ 190 public void setColorIndex(final int cIndex) 191 { 192 for (int i = 0; i < cIndexList.size(); ++i) 193 { 194 cIndexList.set(i, cIndex); 195 } 196 } 197 198 199 /** 200 For debugging. 201 202 @return {@link String} representation of this {@code Primitive} object 203 */ 204 @Override 205 public abstract String toString(); 206}